-->
Page 1 of 1

Ultra Low Power Sensor Board

PostPosted: Sat Nov 28, 2015 11:34 am
by DrG
Image
I had an idea to see if I could use an ESP8266 to read some sensors and send the readings to a local server. A critical requirement was that it be battery operated and that the batteries would last for a long time. My original and quite optimistic “goal” was 6-12 month taking readings as little as once an hour. The project materialized and has been tested to some extent and here is the complete write up including code, schematics, photos and results data. The sensor board has six components: 1) real time clock, 2) power circuit, 3) wireless, 4) humidity sensor, 5) temperature sensor and 6) light intensity sensor.

Image
Real Time Clock. The circuit is built around an MCP79410 chip. Communication is through an I2C interface. The board runs on 3.3v but has a battery backup using a CR2025 battery. Of course the chip keeps time, but it also has alarm functions. When an alarm is triggered, the multi-function pin, which is normally pulled high by connection through a 4.7K resistor to the unregulated battery positive supply (see the power schematic below), will go low. That low signal will be the basis of switching the power supply on and off. The schematic for the RTC is straightforward and is pretty much what is contained in the application note that is referenced. I added the actual components that I used. Three important points for this section: 1) There is a lot of capability on this chip although programming it is not too difficult if you use the data sheet – you can use any microcontroller that has an I2C interface that is not already using the dedicated I2C addresses, 2) the pull up resistors for the I2C interface are on the clock board – so you should not use pullups on any other components, 3) I built I2C access points on the board so that it is relatively easy to program externally (just connect power/ground/SCL/SDA).

Image
Power Circuit: A key to this project was to have the power to the rest of the components switched on to read the sensors and send a packet to a local server and then switched off. That is my approach to being ultra-low power. I know there are deep sleep and low power modes, but in this case the approach that I took was to switch power on and off to all of the components – the real time clock, ESP8266 and the sensors. The simple schematic shows how this is done. The unregulated power source is from 4 X 1.2v AA NiMH batteries. For the tests, I used brand new, fully charged, off-the-shelf Duracell batteries (marked 2400 mAh). When an alarm occurs on the RTC MFP pin, the ground signal switches the MOSFET which allows the battery power to go to the 3.3v regulator that supplies regulated 3.3v (Vcc) to everything else (except of course the battery backup to the RTC). This circuit came about through my own curiosity and much appreciated input from others on this board (see viewtopic.php?f=13&t=5747). Although it is not on the schematic, I put a jumper from GND to the Gate of the MOSFET. This allowed me to easily power the RTC board during testing and programming. Also, all of the GNDs are connected.

Image
ESP8266 Circuit. I used an ESP8266-11. It is attached to an SOIC carrier so I could attach headers. The ESP8266 and the sensors all have headers which fit into a socket for easy removal. All programming used the ESPArduino platform, which made things very easy. The ESP8266-11 is not big on IO having only GPIO 00 and 01 (not including RX and TX). This is not a problem, however, because the RTC and the sensors are all I2C devices and the ESPArduino lets you assign the I2C pins and implements the I2C interface easily. Additionally, for run-time these pins are already pulled up, so no problem there. To program the ESP, however, you have to remove the board from the sensor so that you can ground GPIO 00. Certainly, other flavors of the ESP8266 could be used.

Image
HTU21D Circuit. Temperature and humidity are measured using this small board purchased here (http://www.banggood.com/HTU21D-Temperature-And-Humidity-Sensor-Module-p-971471.html). Again, communication with the sensor is through I2C and, as you can see in the photo, hook up is simple with only four connections. If you look at the data sheet for this chip, however, it is not trivial to use. Fortunately some public domain software was available (thank you Nathan Seidle).

Image
BH1750 Circuit. Light intensity is measured by this small board purchased here (http://www.banggood.com/BH1750FVI-Digit ... 15826.html). This chip is actually pretty easy to program and outputs values in lux. The photo shows that it is simple to hookup. It is also an I2C device and one point to note is the ADDR line. This is pulled high to enable an alternative I2C address which I needed to use to get it to work (see code).

That brings us to the programming the client and server. Two source code files are included. The first is the ESP8266 code and is doing all the work. While it is a bit unrefined, I have it divided into sections and, hopefully, the flow is easy to understand. The sensor sections are marked and, as mentioned previously, the HTU21D code is public domain and I left the attribution and commentary in the program. The BH1750 code is short and sweet and you can consult the data sheet for a full explanation of how it works.

Image
The major function of the program is to assemble the packet which contains the time and sensor information (see diagram). I like comma delimited files because they are so easy to process so that is what I used for the format of the simple packet.

The login is the usual code. There is a counter to quit after a certain amount of time without a connection. This did not occur during testing *except* when my router would fail and that happened a few times. I should explain that this has nothing to do with the ESP8266. Basically, every so often, I will have to power cycle my router to allow connections – it’s been that way for a long time. The net is filled with descriptions and discussions of this problem with many routers and no simple solutions (buy a better router?). My conclusion is that there is some poor memory management on the router and after some amount of connections, some cache gets corrupt or some such malfunction. It is notable, however, that while down, the sensor board continued to try to connect and, after power cycling the router, the packets flowed once again without touching the sensor board. Moreover, this “dead” time is not included in the battery life estimate which is based only on the number of packets transmitted. That is, the estimate is actually conservative. In retrospect, I should have just power cycled the router every evening (I did that once) - something to remember for another test (hey, that could be my next project ;) ).

After sending the packet, the code performs the critical step of clearing the alarm interrupt on the RTC, which turns off the power to everything – RTC, ESP8266, and sensors. The next alarm produces a power up for everything and the code does it all again. All of my testing here is based on one minute alarms. There is probably some optimization that can be achieved that would extend battery life. For example, there is a flush and delay segment after packet sending that can probably be trimmed or removed.

The packets are sent to a server running on a Windows 7 machine. The local address of the server is fixed by configuring my router. The server code is a console VB program and is included. It is an absolutely bare bones implementation and used as a simple test program. Basically, it just sits in a blocking call listening for packets and when one is received, it sends it to the screen and to a file and that is all. The only notable part is that I have to trap an exception that occurs because the TCP connection has been abandoned on the ESP8266 end. This situation is exactly what one would expect because there is no graceful close when the ESP8266 powers off. I have toyed with adding an “end of packet” character so that the server knows when it has an entire packet and can close the socket, but it is not necessary at this point.

Results. To me, the results are impressive as the sensor board performed very well (WooHoo). The batteries lasted longer than I had hoped. Remember, I was shooting for the ability to take readings unattended and on one set of batteries (again, 4 X AA NiMH) for 6-12 months. One reading an hour, for six months, comes to 4320 packets (24 X 30 X 60). For 12 months, 8640 packets. For the test, the sensor board successfully transmitted 7434 packets off of one set of batteries. Granted, I spaced the samples one minute apart and not one hour apart, but, that is roughly equivalent to over 10 months of activity at a rate of one reading per hour!

I am happy to share the details of the project and to entertain questions or comments or improvements, if you are so inclined. I ask, however, that responses focus on this project in this thread rather than additional projects that may be better suited for their own thread.

Finally, I am including some graphs of the sensor data. I am impressed with the sensitivity of the sensors. Since I know exactly where the sensor is placed, I can see certain events represented (e.g., curtains being opened, showering, etc..). It all makes sense.

Image
Image
Image

Files in attached archive:
ESPSensorMCPr.ino – The ESPArduino sensor program.
SocketEar.vb – The console VB (VS 2010) simple packet listener (paste into VB) .
Sensortest.txt – The data, comma delimited text file.

Cheers,
DrG

Re: Ultra Low Power Sensor Board

PostPosted: Fri Dec 18, 2015 8:02 am
by Kenspot
Great idea! Do you have any info on how you programmed the MCP79410 alarms?

Re: Ultra Low Power Sensor Board

PostPosted: Sun Dec 20, 2015 10:40 am
by DrG
Kenspot wrote:Great idea! Do you have any info on how you programmed the MCP79410 alarms?


The details are all in the data sheet http://ww1.microchip.com/downloads/en/D ... 02266G.pdf

It's not that difficult, but does require familiarity with the memory map and basic I2C usage in the ArduinoIDE to read and write to the chip registers. Basically and briefly, you have two alarm clocks in memory (each with seconds, minutes, hour, day of month, month) and you set the match time for the alarm, enable it (through a configuration register) and when the clock registers matches the alarm register, the MFP pin is activated. You clear the alarm by sending a command. So, if I want an alarm once every minute, I can put the value of 59 in the alarm 0, seconds register. Every time the clock register for seconds hits 59, it will match with alarm 0, seconds and (because it has been configured to do so) it will trigger the MFP pin. By using both alarms, you have a lot of flexibility. If you wanted to have some specific intervals you could probably reconfigure the alarms dynamically to get whatever you wanted, but I did not get into it at that level.

When I searched on Arduino and this RTC chip, I found a few examples of code to set and read the clock. Those were helpful starters, but I did not see the kind of extensive libraries as you see with a couple of the popular DS chips (e.g., DS3231), but there is info out there.

Cheers,

DrG