-
• #2
That function is only available on devices with a watch battery.
The RAK8212 powers the nRF52832 via a voltage regulator, so the voltage on it will always be 3.3v - you can't work out the battery voltage that way.
-
• #3
You'll need to provide a resistor divider on port bit D28 (which is the only analog input) to scale the voltage between 0-3.3V. Then:
pinMode(D28,'analog');
value = analogRead(D28) * scale_factor;You'll have to figure out the scale factor yourself - 3.3V is full scale which is a value of 1. For example, I'm using a voltage divider to read a 12V battery with a 39k and 10k resistor. The scale factor is 16.21.
-
• #4
@Kartman, I assume your 12V battery has not long term issue w/ this constant drain of 2.44mA... when all things go to sleep, this may though be a significant drain when running on less power capacity than your setup.
EDIT - 2.44 is 1 order off... see next two posts...
A solution that does not constantly drain - only when capacity is measured - is with an additional optocoupler in the feed line of the voltage divider. Yes, the (infrared) switch driver LED consumes more than that... at least the double, but it is only for a very short period... The scale factor has then to be adjusted with the voltage drop of the coupler's switch transistor (which is also dependent on the the overall current flowing and the LED driving current. Some measurement with a multi-meter and different (strong enough*) voltage source can be used to figure out the 'curve'... and show if there is need for a non-linear scaling factor...
Rough schematics:
` VBat ------------------------+-----------------+-------+---- .-----------. | | | | 3..3.3V | | | | 3..3.3V -+---+ Voltage +---' | | | | Regulator | | | | '-----+-----' | | ESPRUINO | | | | iTracker | | Optocoupler | | .--------+---. | .-------------. | | | Opto- | | | | | | + | coupler- +--------[RES3]--+--. .-+--' _______ | driving | | | | | | ___ | pin | | | _|_ / | _______ | | | | \ / --> |/ | Bat ___ | | | | V --> |> | _______ | | | | -+- \ | ___ | | | | | | | _______ | | | .--+--' '-+--. ___ | | | | | | .|. | - | | | | '-------------' |R| | | | | | |E| | | | | | |S| | | | | | |1| | | Analog | | | '|' | | read +---------------------------------+ | | pin | | | .|. | | | | | |R| | | | | | |E| | '-----+------' | | |S| | | | | |2| | | | | '|' | | | | | | GND --+------------+-------+-------------------+-------+---- `
-
• #5
I think you're off by a factor of 10! My calculator says 244uA. I'm measuring a battery whose self discharge is well in excess of 244uA. Opto? Why not just a mosfet like a BSS138? Optos are always the last resort as they age, have wide parameter spread and so on.
-
• #6
..you are right... it was .244 something mA ... dooooh;;;;
Sure, direct mosfet works too... isolation/statics/spikes may be a question... depending what the powering is. To control the mosfet though - I guess you are talking N - it must then be between the voltage divider resistors, does it? It cannot be 'at the really low end/bottom', otherwise the analog pin would get's the VBat 'tickle'. Also, you might loose a bit of range by making RES1 even higher or RES2 lower to force robust switching, but that would probably not hurt.
-
• #7
If you're worried about power consumption then look at the specs for the mic5219 regulator on the RAK8212 board. Torex have some cmos regs where the quiescent current is much less.
-
• #8
@Kartman, w/ nMosFet something like this:
` VBat -----------------------+--------+------------+---- .-----------. | | | | 3..3.3V | | .|. | 3..3.3V -+--+ Voltage +---' |R| | | | Regulator | |E| | | '-----+-----' |S| | | | |1| | ESPRUINO | | '|' | iTracker | | nMosFet | | .--------+--. | .--------.| D | + | | | / | _______ | | | / |\ ___ | | | . | . _______ | nMos- | | G | | |----' | Bat ___ | Fet +-----------+-----| |<---. | _______ | driving | | | | |----| | ___ | pin | | ' | ' _______ | | | \ |/ ___ | | | \ | | - | | | '--------'| S | | | | | | | Analog | | | | | read +------------------------+ | | pin | | | | | | | .|. | | | | |R| | | | | |E| | '-----+-----' | |S| | | | |2| | | | '|' | | | | | GND --+-----------+------------------+------------+---- `
-
• #9
Thanks for the circuits @allObjects - I think that's another one to go on the forum links page.
edit: I take it back about the MOSFET - that's an extremely elegant solution!
The ADC actually functions way better with a low input impedance, so if you add a capacitor between the GPIO and GND it'll protect the IO and increase accuracy.
In fact, if you're feeling really lazy you could just use some high values like 2 x 560kOhm resistors and then a reasonably sized capacitor. While there's power draw it'll be in the 4uA kind of territory, which in this case is probably ok. It won't be super accurate but then the battery voltage fluctuates with temperature anyway so it'll be good enough.
Having said all that it looks like the BG96 may itself have a battery level monitor. I think if you send the AT command
AT+CBC
it'll give you a battery charge value. -
• #10
That's not going to work! If the gate is at 3.3V and the source is at 3.3V, then no current will flow.
I'm not in a position to work through this issue at the moment. Obviously, the 'simple' solution is to use higher value resistors. The values I used were simply an example not taking into account of current draw. With higher value resistors you need to take into account leakage currents. Your solution of using an opto, whilst 'it works' it's not really a clean solution. The opto itself gives you no protection from spikes in the method you're using it. Note that I pulled the part bss138 off the top of my head before I saw your ascii art diagram. -
• #11
@Gordon, something like that:
` VBat ---------------------------+----+----------+---- .-----------. | | | | 3..3.3V | | .|. | 3..3.3V -+------+ Voltage +---' |R| | | | Regulator | |E| | | '-----+-----' |S| | | | |1| | + ESPRUINO | | '|' _______ iTracker | | | ___ .--------+--. | | _______ | | | | Bat ___ | | | | _______ | Analog | | | ___ | read +----+---------[RES3]----+ _______ | pin | | | | ___ | | | | .|. | - | | | | |R| | '-----+-----' ----- | |E| | | ----- | |S| | | | | |2| | | | | '|' | | | | | | GND --+----------+----+--------------+----------+---- `
(Optional) RESistor3 helps smothing ripples and decouples the voltage divider even more.
I had some concerns for the reliable switching of nMosFet as well, as you documented on https://www.espruino.com/mosfets and @DrAzzy points out in a post of this conversation about ...PICO ... and MOSFET.
I will give the options some hands-on consideration - including component specifications- because I have something in (slow) work that uses 3.7 LiPo on solar cell with charge board and powers some sensors, LORA and PICO / Puck. For the nMosFet option I plan to use @DrAzzy's nMosFets - see conversation about Power Supply. I had them already successfully in use with a Espruino-Wifi and LED light panels... LED's feed by 5V and low-side switched.
-
• #12
Nice to see you added a capacitor. If you wanted to do an equivalent of the opto, but in mosfets, then you'd need a p-chan and an n-chan. The devil is in the details, so you'd have to analyse the circuit to see if there is any specific advantage in switching the resistor divider. There has probably been discussion on the likes of stack exchange as this is not a new problem. Low power circuitry is tricky as you need to analyse just about every component for the likes of leakage and temperature sensitivity.
-
• #13
Having said all that it looks like the BG96 may itself have a battery level monitor. I think if you send the AT command AT+CBC it'll give you a battery charge value.
@Gordon I have tried to use the command this way:var at = require("AT").connect(Serial3); at.debug(); at.cmd("AT+CBC\r\n", 1000, function(d) { if (d===undefined) ; console.log("DATA"+d); });
Unfortunately it only returns undefined. Should I use another module or what might cause this error?
-
• #14
Something's very wrong if you're trying to use Serial3. What about:
var at; console.log("Turning Cell on"); require("iTracker").setCellOn(true, function(usart) { console.log("Cell now on"); at = require("AT").connect(usart); at.cmd("AT+CBC\r\n",1000,function cb(d) { if (d=="AT+CBC") return cb; if (d!="OK") console.log("CBC is "+d); }); });
-
• #15
The output is "CBC is AT+CBC", so it did not work unfortunately.
-
• #16
If the result was
AT+CBC
, theif
should have returned and not printed that line?Can you try this:
var at; console.log("Turning Cell on"); require("iTracker").setCellOn(true, function(usart) { console.log("Cell now on"); at = require("AT").connect(usart); at.cmd("AT+CBC\r\n",1000,function cb(d) { if (d=="AT+CBC") return cb; if (d!="OK") console.log("CBC is "+JSON.stringify(d)); }); });
so that we can see if there are any extra characters in there?
-
• #17
Great idea. It worked now using "AT+CBC\r" for comparison. Thank you. Then you get these values: [bcs, bcl, voltage]
The second one (bcl) returns the battery charge level in percent. So it is exactly what I wanted. By the way bcs shows if the battery is charging. I guess that this is the most elegant way to get the battery level.
Hi,
I would like to use the getBattery function using the iTracker RAK8212. Unfortunately I get the error
"Function "getBattery" not found". I am calling E.getBattery(). The RAK8212 has an NRF52832 chip. I am powering it using a lithium battery connected to the board.
Do you know a reason?