ESP8266 battery monitor
Posted: Wed Oct 30, 2019 5:33 pm
Since I'm doing some changes to the solar system, and have had minor issues with the existing monitor setup, I decided to make a new one based on an ESP8266, using a WeMos module.
This will use WiFi to let another host grab data from it, excluding the lightning damage issues, and has a better analog front end so should be more accurate and less susceptible to leakage currents (think spiders etc).
I used 2 ads1115 breakouts, so I cound run the a/d in continuous mode, instead of the blocking mode in the default library for these. You can't do channel switching meaningfully in that mode, but rather just grab the latest results now and then. This allowed me to also set the sample rate at its lowest limit (8 sps) so as to get the benefit of some on chip lowpassing as well as the stuff I added.
The result appears to be robust and as accurate as the meters I have to calibrate it with; kind of by definition, as I adjusted the scaling to read the same as my meters. This system has no offset.
That is, compared to my meters. If anything is drifting, it's a fluke.
I also added a sht31 temperature and humidity sensor, because why not.
Results are dispayed on an ssh 1106 128x64 OLED display so I can see if it's working locally and get a reading when I'm "right there", and because it's cool.
Here is is burning in I did the software on a raspberry pi 4-4g shown here, using arduino 1.6.10, and a geany setup as an external editor to get the kind of code highlighting I like and other features the Arduino IDE lacks.
While that pi takes awhile to start the Arduino IDE, well, that IDE takes awhile (less) to start even on a big fast machine. It's not bad. I'm actually sitting elsewhere and talking to that via VNC, so it can be on the bench, while I'm on the couch with a big screen, in comfort. I set a static IP rather than use DHCP - I have a nice map of where things live on the LAN that I keep updated in a local version of PHPBB (along with a lot of other stuff - it's the ultimate note-to self app).
But no plan survives contact. So I have more than one way of finding things.
The sketch uses a thing that is standard here, which I call tellme - this broadcasts a hostname / IP pair to a known UDP port on the LAN, in this case port 53831. Other, more sophisticated machines (anything running linux) listen on this port and keep a version of /etc/hosts updated with what is online now, including noticing when a canary stops tweeing. So all my devices on the LAN are resolved internally.
I'm using my standard model Arduino scheduler and tiny opsys (it's nor that big a deal), and using my also standard (at least here) setup of having this be a slave that listens on a UDP port - in this case port 42042 - for commands, and simply speaks when spoken to. Whoever is interested simply asks for data, and it's sent back in human readable ASCII. Other commands are easy to add.
A benefit of this is that it's cheap...and it also hard-boots very quickly - so surprises like one might get once in awhile with something bigger (like a pi) - really, no way to get hung up - if it works at all, it works.
Further, an image is a heck of a lot easier to keep as backup than a big linux image.
So, here's the code, compressed. I had to modify the ADS1115 library, so that's in the package too. Basically, nothing special other than adding the ability to start continuous conversions. Of perhaps peripheral interest, this is what I see when messing with the code on my nice comfy couch with a wireless keyboard and a big display (no glasses required). The schematic is really simple. All the perhipherals are wired up to I2C and I used a couple of 2.7k pullups on the lines, maybe not needed (it worked without them).
The voltage a/d input is from a divider, with 3 10k in series, and a 22uf capacitor to inp_n after the first one, and a 1k to the input negative, with a 330uf capacitor across it and the input positive. Just a 31:1 divider with a couple of lowpass capacitors along the way.
Same idea for the one that measures amps, but inp_p and _n are switched, and the values are 4.7k (times two) and there is no capacitor across the inputs - just this lowpass filter.
Power ground and measurement ground aren't connected on this board. They are in the real world, but at the battery. This avoids noise from the switcher I'll be using to get 5v from the 24v nominal batteries. That ampere shunt is .001 ohm and in the negative battery lead.
All the modules are socketed and are unmodified pieces. Sometimes you need to replace one, why make it hard?
This will use WiFi to let another host grab data from it, excluding the lightning damage issues, and has a better analog front end so should be more accurate and less susceptible to leakage currents (think spiders etc).
I used 2 ads1115 breakouts, so I cound run the a/d in continuous mode, instead of the blocking mode in the default library for these. You can't do channel switching meaningfully in that mode, but rather just grab the latest results now and then. This allowed me to also set the sample rate at its lowest limit (8 sps) so as to get the benefit of some on chip lowpassing as well as the stuff I added.
The result appears to be robust and as accurate as the meters I have to calibrate it with; kind of by definition, as I adjusted the scaling to read the same as my meters. This system has no offset.
That is, compared to my meters. If anything is drifting, it's a fluke.
I also added a sht31 temperature and humidity sensor, because why not.
Results are dispayed on an ssh 1106 128x64 OLED display so I can see if it's working locally and get a reading when I'm "right there", and because it's cool.
Here is is burning in I did the software on a raspberry pi 4-4g shown here, using arduino 1.6.10, and a geany setup as an external editor to get the kind of code highlighting I like and other features the Arduino IDE lacks.
While that pi takes awhile to start the Arduino IDE, well, that IDE takes awhile (less) to start even on a big fast machine. It's not bad. I'm actually sitting elsewhere and talking to that via VNC, so it can be on the bench, while I'm on the couch with a big screen, in comfort. I set a static IP rather than use DHCP - I have a nice map of where things live on the LAN that I keep updated in a local version of PHPBB (along with a lot of other stuff - it's the ultimate note-to self app).
But no plan survives contact. So I have more than one way of finding things.
The sketch uses a thing that is standard here, which I call tellme - this broadcasts a hostname / IP pair to a known UDP port on the LAN, in this case port 53831. Other, more sophisticated machines (anything running linux) listen on this port and keep a version of /etc/hosts updated with what is online now, including noticing when a canary stops tweeing. So all my devices on the LAN are resolved internally.
I'm using my standard model Arduino scheduler and tiny opsys (it's nor that big a deal), and using my also standard (at least here) setup of having this be a slave that listens on a UDP port - in this case port 42042 - for commands, and simply speaks when spoken to. Whoever is interested simply asks for data, and it's sent back in human readable ASCII. Other commands are easy to add.
A benefit of this is that it's cheap...and it also hard-boots very quickly - so surprises like one might get once in awhile with something bigger (like a pi) - really, no way to get hung up - if it works at all, it works.
Further, an image is a heck of a lot easier to keep as backup than a big linux image.
So, here's the code, compressed. I had to modify the ADS1115 library, so that's in the package too. Basically, nothing special other than adding the ability to start continuous conversions. Of perhaps peripheral interest, this is what I see when messing with the code on my nice comfy couch with a wireless keyboard and a big display (no glasses required). The schematic is really simple. All the perhipherals are wired up to I2C and I used a couple of 2.7k pullups on the lines, maybe not needed (it worked without them).
The voltage a/d input is from a divider, with 3 10k in series, and a 22uf capacitor to inp_n after the first one, and a 1k to the input negative, with a 330uf capacitor across it and the input positive. Just a 31:1 divider with a couple of lowpass capacitors along the way.
Same idea for the one that measures amps, but inp_p and _n are switched, and the values are 4.7k (times two) and there is no capacitor across the inputs - just this lowpass filter.
Power ground and measurement ground aren't connected on this board. They are in the real world, but at the battery. This avoids noise from the switcher I'll be using to get 5v from the 24v nominal batteries. That ampere shunt is .001 ohm and in the negative battery lead.
All the modules are socketed and are unmodified pieces. Sometimes you need to replace one, why make it hard?