Do you want a cheap Arduino-based data logger that can run for months on a PP3 battery, recording data on an SD card and/or sending it to you in an SMS message? This page describes the design of a data logger that I built for monitoring a beehive (weight and temperature) but bit which could be adapted for many other purposes. It could also be adapted for some control or alarm functions. The main parts are cheap, commonly available modules. You could build the data logger on an electronics breadboard/plugboard (if you don't want to solder), or on Veroboard/stripboard, or by making your own PCB.
The Beehive Monitoring application is described here.
The key to the long battery life is that most of the circuitry including the Arduino is completely powered down between logs. This technique is effective if the interval between logs is long compared to the time it takes for the Arduino system to boot up and then carry out the log action and then switch off again. For example with my beehive logging program, the Arduino is only powered up for 3 to 4 seconds per log. Thus if I log hourly, the Arduino is only on for about 3.5/3600 of the time, i.e. about a thousandth; so if when powered up the logger consumes 30 to 50mA, then the average power consumption is a thousandth of that: 30 to 50uA.
Clearly this approach won't work so well if you want to log every few minutes or seconds. There are other designs described on the web that pay more attention to minimising the consumption of the Arduino when it is powered up.
When the Arduino is powered off, we need a very low power circuit that remains on and will power up the Arduino again after the required interval. For this a Real Time Clock (RTC) IC with an alarm output is used plus a very small amount of additional circuitry. Between logs, the RTC is powered by a button cell which I understand will last for a year or more, and the remaining always-on circuitry by the main battery of the logger.
The average consumption of the data logger from its main battery (i.e. ignoring the RTC button cell) =
{Consumption of Always-On Circuit} + {Consumption of Arduino} x {Powered-Up-Time}/{Logging-Interval}
NOTE: {Consumption of Arduino} includes all those circuits powered up with it, e.g. sensors, SD card, display, etc.
Accordingly this leads to the following design objectives:
Aim for VERY low consumption by the Always-On circuitry.
Keep the consumption of any modules or circuitry that are powered up with the arduino as low as is practical.
Minimise the amount of time the arduino and associated circuitry have to be powered up for, each time the data logger logs.
Don't log too often, i.e. maximise the interval between logs.
I wanted the data logger to be able to send measurements in an SMS. To do this I use a GSM MODEM module. However this GSM module consumes more power than the rest of the circuitry and has to be powered up for longer, typically 30s to 60s, in order to register on the network and transmit the SMS. To prevent this from affecting the data logger's average consumption too much, I designed the circuit such that this module is switched on separately under the control of the Arduino; that way it can be powered up less frequently, not more than once a day. So the logger can for example be taking logs every hour, but only once a day is the GSM module also powered up and an SMS sent containing the data (or a selection of it) from the last 24 hours. So now:
Average consumption of data logger from main battery =
{Consumption of Always-On Circuit} + {Consumption of Arduino} x {Powered-Up-Time}/{Logging-Interval} + {Consumption of MODEM} x {Modem Powered-Up-Time}/{SMS Send Interval}
NOTE: Where {Modem Powered-Up-Time} is 30 to 60 seconds, and {SMS Send Interval} is seconds in a day 60x60x24 if sending an SMS daily.
The circuitry that needs to be powered continuously comprises the Real Time Clock IC (DS3231) and the necessary power-up circuitry to allow the RTC alarm, or a user action, or possibly an event from a sensor, to power up the Arduino. The RTC has its own button cell but the other circuitry will be powered by the main battery. The whole of the circuitry is protected against reverse connection of the PP£ battery by a diode in series with the battery.
The alarm function of the Real Time Clock IC DS3231 is used to wake up the unit. You can buy a small RTC module PCB containing the DS3231 and button cell battery. Alternatively if you design your own PCB, you can buy the surface mount DS3231 chip. My Hive Logger PCB was designed to give the choice of using either a the surface mount IC and button cell holder soldered directly to it, or plugging an RTC module into it; I did succeed in soldering a surface mount DS3231 to my PCB but didn't find it easy.
The RTC module I used was from ebay: “For Arduino DS3231AT24C32 IIC Module Precision RTC Real Time Clock Memory”. As well as the RTC, it includes a 4K x 8-bit EEPROM non-volatile memory (AT24C32 IC) which I don’t make use of. Communication with the DS3231 chip is via I2C bus and it has a fixed address of 0x68.
Module Connections
The module board has a 6-pin right-angle male header with these connections:
32K = 32K clock output of the DS3231
SQW = Dual purpose programmable square wave output / Alarm Output
SCL = I2C SCL – Connects to uC SCL
SDA = I2C SDA – Connects to uC SDA
VCC = Connects to uC power (3.3 or 5V). If disconnected, the module operates off the backup battery
GND = Ground
Power consumption
My card consumes about 4.2mA from 5V supply. When the alarm LED I connected to it is on when alarm occurs, rises to about 5.2mA.
The important output for the data logger design is the pin marked SQW which stands for Square Wave is a dual purpose output. It can carry either a square wave which can be programmed to one of a couple frequencies or it can be used as an interrupt output for the built-in time-of-day alarms. This pin is also an open-collector output and the module includes a 4.7K pull-up resistor on this line as well. Unfortunately to maintain low power consumption when the data logger is in sleep, I had to cut a track to remove the 4.7K pull-up resistor on the pin SQW, and bring SQW directly out to the header connector without the pull-up. This is quite fiddly to do and is a reason why I experimented with using the DS3231 chip directly on my PCB instead of using the sub-module.
How to cut the track on the module: To remove the 4.7K pull-up resistor on the pin SQW, and bring SQW directly out to the header connector without the pull-up. You need to cut the track going to J1 pin2 SQW; cut the track from DS3231 pin 3 INTSQW to the pull up resistor in RP1; add a wire from DS3231 pin 3 INTSQW to J1 pin2 SQW. This is shown in the photos below (Note: I also straightened the connector pins on the RTC module board as it suited my design):
Further Details on RTC Module & DS3231 on the Web from protosupplies.com who include this note and circuit diagram:
Important Note: These modules normally come with a 200 ohm resistor installed in the location next to the glass diode which can be seen in some of the pictures. The resistor and diode form a simple charging circuit that is intended for use with LIR2032 rechargeable batteries. Since the module ships with a non-rechargable CR2032 battery, this resistor is removed since recharging it could cause failure of the battery.
The resistor is taped to the back of the battery in case you want to reinstall it for use with a rechargeable LIR2032 battery or you can toss it.
If you do decide to use a rechargeable battery and add this resistor back in, please note that this circuit does not guarantee that the specified 4.2V charging voltage will be applied to the LIR2032 battery, so there is some chance of overcharging and destroying that battery as well. We recommend either staying with the CR2032 type non-rechargeable battery or do some research and possibly make some circuit modifications if necessary to ensure that the charging voltage is correct for the LIR2032 that you use.
The schematic shows the resistor that is removed and the circuitry should you decide to modify it.
I did not bother to remove the resistor since the data logger is only ever momentarily powered up and thus charging the button cell. So far I have not had a problem with battery failure. I did not include a charging circuit in my PCB where I mount the DS3231 directly.
RTC Software:For the RTC library, I used Adafruit's RTCLib - a fork of JeeLab's excellent RTC library.
The Alarm functions are:
setAlarm1() Set alarm 1 for DS3231.
Note the enum for Alarm Mode:
enum Ds3231Alarm1Mode { DS3231_A1_PerSecond = 0x0F, DS3231_A1_Second = 0x0E, DS3231_A1_Minute = 0x0C, DS3231_A1_Hour = 0x08, DS3231_A1_Date = 0x00, DS3231_A1_Day = 0x10 }
disableAlarm() Disable alarm.
clearAlarm() Clear status of alarm.
alarmFired() Get status of alarm. True if alarm has been fired.
From data sheet DS3231.pdf, Table 2. Alarm Mask Bits:
ALARM 1 has options 1. Alarm once per second 2. Alarm when seconds match 3. Alarm when minutes and seconds match 4. Alarm when hours, minutes, and seconds match 5. Alarm when date, hours, minutes, and seconds match 6. Alarm when day, hours, minutes, and seconds match ALARM 2 has options Alarm once per minute (00 seconds of every minute) Alarm when minutes match Alarm when hours and minutes match Alarm when date, hours, and minutes match Alarm when day, hours, and minutes match
Good Tutorial for connecting RTC DS3231 to Arduino.
The data logger needs some power-up circuitry to allow the RTC alarm, or a user action, or possibly an event from a sensor, to power up the Arduino. This is achieved as follows.
The power to the Arduino is controlled by a flip-flop comprised of two NAND gates. This bistable is flipped into the Power-ON state by any of three events:
When the unit is powered up (battery connected), a capacitor is intended to hold an input low for long enough to make it come up in the Power-ON state.
When the alarm output of the Real Time Clock DS3231 is pulled low.
When the push button mounted on the unit’s case is pressed. This is to allow the user to force a power up in order to read the current weight, etc.
The Arduino is able to flip the bistable into the Power-OFF state via output D4, when the program wants to put the unit back into sleep. The advantage of this design rather than using the RTC alarm to directly control the power, is that the software can clear the RTC alarm without switching off the unit. The software is able to distinguish between a manual and alarm wake up because it can query whether the RTC alarm has been triggered – if it has not, then the wake-up must be manual.
Two NAND gates of a 4011 Quad NAND gate IC is used to make the bistable; the 4000 series of CMOS logic is very low power. The flip-flop power-up circuitry consumes only microamps from the main 9V battery. To keep power low, pull-ups where needed in the bistable circuit are 1M resistors.
Note: It would be easy to use some other event(s) to trigger the bistable if required, e.g. a sensor threshold; just ensure that any additional always-on circuits are also very low power.
Power Switching Transistors
The output from the bistable is used to switch on the power to the logger. It drives a BC547 transistor which in turn drives a TIP32 power transistor that connects the PP3 9V battery to the Arduino’s VIN.
To determine the transistors used, take into account the maximum current the logger consumes which will tell you the minimum current capability you want for the power transistor (the TIP32 is probably overkill). Also, by comparing the maximum current the logger consumes to how much current the 4011 gate output in the bistable circuit can supply, you can calculate how much gain you need from the transistors. Also try to minimise the voltage drop across the switching circuit when on, as the bigger it is, the sooner the logger will cease to work as the battery discharges and its voltage falls.
The circuitry needs to be very low power to achieve a long battery life. The NAND gate will be continuously powered when rest of unit is asleep and so cannot be supplied by the Arduino’s 5V regulator. A very low draw 5V regulator is used to supply it instead: the MCP1702 regulator [MCP1702-5002E/TO 1702-5002E 250 mA Low Quiescent Current LDO Regulator]; don’t use other regulators unless they are equally good.
Note: The option of powering the NAND gate directly by the PP3 9V battery was rejected because the DS3231.pdf data sheet gives Logic 0 Output, 32kHz, INT/SQW, SDA of 0.4V at I OL = 3mA and says Pull Up can be up to 5.5V, regardless of the voltage on Vcc (so NOT MORE, i.e. not 9V!). The INT/SQW is to be connected to a 4011 input pulled-up to the 4011 supply, so that supply has to obey this limit – thus 5V was chosen.
The logging software I wrote needs to know what caused the power-up. The software can detect whether the power up was due to the RTC alarm or was manual (i.e. from ON/OFF switch or push button) because it can read the status of the DS3231 alarm. If the alarm has not fired, then it must have been a manually triggered wake-up. If your logger has other potential triggers (a sensor, etc.), then augment the circuit so that the software can distinguish them as necessary.
In my Hive Logger circuit, the push button has a dual function. It is used to manually wake up the logger (by triggering the bistable), and once awake, it is used to respond to user interface messages displayed on the LCD screen. For the user interface function, an Arduino analogue input is used to detect whether the button is pressed. Note that the same input also doubles up as a way to read the battery voltage of the main battery, which is logged to track how fast the battery is discharging. The doubling up is only to keep as much I/O free for other purposes as possible. Of course if the user were pressing the push button when the battery voltage was read, the voltage reading would be wrong – but this is unlikely during a manual wake-up and almost impossible during normal logging wake-ups as the user is not normally present!
We do not want the GSM module (a Siemens TC35) to be powered up except when needed as it consumes more power than the Arduino. Typically the unit will wake to log more often than it sends an SMS so in most wake-ups the TC35 is not needed at all. And when it is needed it need only be switched on for the actual send operation. Therefore an output from the Arduino is used to turn it on, only when the software requires. This output drives a second BC547 transistor and TIP32 power transistor arrangement which then connect the PP3 9V battery to a Buck step-down voltage regulator set to give the 5V required by the TC35 [MP1584 Adjustable 3A DC-DC Converter Step Down Buck Voltage Regulator]. The Buck is a cheap small PCB module and is more efficient than a traditional linear regulator like the LM317T Adjustable Variable Voltage Regulator. However if re-designing the logger PCB, the latter might be preferable as a simple resistor chain determines the output and there is no risk of forgetting to adjust the Buck’s tiny preset potentiometer or of it accidentally changing and applying an over-voltage to the GSM module.
This data logger design achieves a long battery life by powering up most of the circuitry including the Arduino, only when taking a log, and powering it off between logs.
At the heart of this circuitry is the Arduino, what else you have depends on what sort of logger you want to build. Here are three features that my Hive Logger has that you may want to replicate:
SD Card Reader. As most of the logger is OFF between logs, we need some non-volatile storage for the logged data. For very minimal applications there is some EEPROM on the Arduino itself and if the RTC Module described earlier is used, it includes a 4K x 8-bit EEPROM non-volatile memory on an AT24C32 IC. However adding an SD card not only gives you huge amounts of storage, it also provides an easy way to access the data: you can simply remove the SD card and read it with a PC. If the logger is in the field you don’t necessarily need a PC with you, you can simply exchange the SD card for another and read it when you get home.
LCD Display. A display is not essential; you can configure the logger via a PC before you take it into the field and thereafter just trust it is doing the right thing. However I felt it was reassuring to be able to get some indication of what the logger is doing without needing to connect a PC, and also be able to make simple adjustments, such as adjusting the clock to the correct time. An LCD has fairly low consumption (especially if any backlight is kept dim or off). You could also arrange to switch it off (with a mechanical switch or electronically) when the user does not need it.
Communications. If you want your logger to transmit data to you when in the field, you need to add some sort of communications. I decided to send data in GSM SMS messages as this is very simple at the Arduino end, needs no processing when received on a smartphone, and is cheap (as low as 4p a message using a PAYG SIM in the UK). I experimented with various low cost GSM modems but the only one that worked in the UK was the Siemens TC35.
Below we take a closer look at the Arduino and at options for SD Card, Display and Communications.
I chose to use the Nano because it is small and easy to connect to a PC for development via its USB connector. Several features of the Nano are used, including the on board EEPROM, AtoD Converters, and the SPI and I2C interfaces.
The SPI interface is used to communicate with the SD card module.
The Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers.
With an SPI connection there is always one master device (usually a microcontroller) which controls the peripheral devices. Typically there are three lines common to all the devices:
MISO (Master In Slave Out) - The Slave line for sending data to the master.
MOSI (Master Out Slave In) - The Master line for sending data to the peripherals.
SCK(Serial Clock) - The clock pulses which synchronize data transmission generated by the master.
SS(Slave Select) - the pin on each device that the master can use to enable and disable specific devices.
When a device's Slave Select pin is low, it communicates with the master. When it's high, it ignores the master. This allows you to have multiple SPI devices sharing the same MISO, MOSI, and CLK lines.
On Nano: SPI: D10 (SS), D11 (MOSI), D12 (MISO), D13 (SCK) pins support SPI communication.
The I2C interface is required to communicate with the RTC and LCD modules. The wire library allows you to communicate with I2C / TWI devices.
On the Nano: I2C: A4 (SDA) and A5 (SCL). Support I2C (TWI) communication using the Wire library. [ Nano]
The Nano is based on the ATmega328 microcontroller. It has 32 KB of Flash Memory (2 KB of which is used by bootloader), 2 KB SRAM, 1 KB EEPROM. A word of warning: I struggled to fit all of my software for the Hive data logger into the available flash and had to be careful with SRAM usage too. However I did find that I could squeeze a bit extra out of the Nano by using the EEPROM to store strings (text) for the user interface; on the Hive data logger I load either Spanish or English strings for the user interface into the EEPROM on start up, using the EEPROM ‘update’ command which reads first and only writes the data if it has changed (which is faster and avoids wearing out the EEPROM).
Running low on SRAM is particularly problematic because the compiler cannot tell you if you will run out at run time; things just begin to go wrong at run time when you approach the limit. Removing debug print statements helps as text uses up a lot of variable space. Constant data can be put into program memory PROGMEM (the flash) on the Arduino but even the flash is almost used up.
V4.3 of Hive logger program had:
Sketch uses 30368 bytes (98%) of program storage space. Maximum is 30720 bytes. Global variables use 1350 bytes (65%) of dynamic memory, leaving 698 bytes for local variables. Maximum is 2048 bytes.
The SD Card reader used is a low cost and simple device found on ebay. It allows the user to both read and write to micro SD cards, and is easily interfaced to an Arduino. Both Micro SD Card and Micro SDHC cards are supported. The card reader is a 5V device for both power and logic levels, and uses the SPI interface. This device takes exclusive usage of the SPI, and other SPI devices cannot be used in parallel.
Power consumption
With the standard Arduino SD library, my card consumes about 4.6mA before being initialised, and then 22mA once active. There’s no apparent way to make the card inactive. Ending SPI with SPI.end() doesn't help.
Tried the SdFat library instead. My card then consumes about 4.6mA before being initialised, and then blips up probably to 22mA when card being accessed but returns to about 4.5mA.
This library also used 1278 less bytes of program storage space than the standard one, and about the same (4 more bytes!) of global variables. So, SdFat library seems better!
The new File class in SdFat supports all the SD.h File member functions plus the SdFile member functions. SdFat also supports the SD.h style open for the File class. NOTE: I Had problems getting this to work. I updated the SdFat library to 1.1.4 via Tools->Manage Libraries in the IDE and then it all worked. To check the card one of the test example sketches. Remember with these programs to edit them to the pin you have connected as CS (chip select), e.g. if using D10, the line:
const int chipSelect = 10;
On the first prototype data logger and another project, I used the Nokia 5110 LCD Screen which can show 6 lines of 12 characters. However I found it very unreliable, tending to fade completely: you have to press or move the screen to try to get the image back. It also requires bitmaps which take up so much space that I had to store the in a file on the SD card.
On subsequent versions of the Hive logger I use an LCD module that has 2 Lines of 16 Characters, and a piggy-back board attached to the underside that provides the I2C interface.
16x2 HD44780 5V LCD Display Module + I2C / IIC serial interface module
These displays are easy to find on Ebay in various sizes (number of lines and characters per line). No bit maps are needed. It’s available in :
Green background with black text.
Blue background with white text (apparently better for low-power applications).
Red text on black background.
Software and Interfacing for LCD: A good guide here at www.makerguides.com
Of three libraries for LCD with I2C interface that I tried, I found that the LiquidCrystal_I2C library worked once I’d edited the example to have the correct I2C address as found above and have selected the 16x2 display size. On compilation it used less program space than the other two.
I2C 1602 LCD Board Module – the 1602 is the I2C board controller chip
I2C Address: 0X20~0X27 (the original address is 0X20,you can change it yourself)
Supply voltage: 5V. The backlight and contrast is adjusted by a potentiometer
Compatible for 1602 LCD 2004 LCD
Module specification PDF.
How to find the I2C address of the LCD
Most I2C LCDs ship with the default address ‘0x27’, but it can be different depending on the batch/manufacturer. If this is the case, you will need to find the actual address of the LCD before you can start using it. On the Arduino website, you can find a simple example sketch that scans the I2C-bus for devices. If a device is found, it will display the address in the serial monitor.
The LCD and its I2C interface, are mounted above the Hive Logger PCB on 18mm M3 pillars.
It is necessary to straighten with pliers the connector pins on the I2C piggy-back board attached to the underside of the LCD, in order for them to plug into the connector on the Hive Logger PCB below. If needed their length can be trimmed slightly.
At the opposite end of the I2C piggy-back board is a single jumper for the LCD LED intensity. Replace this jumper with a 3.3k resistor (soldered to the header pins instead), both to save power and because the LED is in any case too bright otherwise.
The LCD module piggy-back board has a potentiometer preset. Once the unit is ready to be switched on, experiment to find the best adjustment to see the screen characters clearly. You will need to unplug the LCD from the Hive Logger PCB to adjust the potentiometer. Note: in some positions of the potentiometer, the characters on the screen may not be visible at all!
If the LCD does not work, it may be because it has been supplied with a different I2C address. See “How to find the I2C address of my LCD” in the section of the LCD module, for how to find the address. Note: if it is different, this has to be changed in the software.
Power consumption: I measured 4.7mA with no backlight (jumper on I2C board removed) and 17.5 mA with backlight (jumper on I2C board in place). On the blue units I measured 2.4 to 2.7mA with no backlight jumper (it’s more when more characters are displayed) and 4.4 to 4.8 mA with a 1k resistor instead of the jumper. Changed to a 3.3k which is about the highest that still gives reasonable illumination and got 3.1 to 3.4 mA, so chose the 3.3k.
If your data logger is in or very close to a building, you may be able to use the Ethernet or WiFi to connect to the internet. There are modules and Arduino libraries for this. My hive data logger is for use in apiaries well away from buildings so a WAN technology is needed.
The most familiar to me and one was certain to cover the apiaries is the mobile phone network. A drawback is that it’s necessary to have a SIM and pay for the communications. I’m unwilling to use a contract SIM because of the contract cost and having to worry about security if the SIM is stolen from the unattended device. With PAYG SIMs, if the SIM is stolen, the only loss is the remaining credit, and sending an SMS can be as as little as 4p a message. Instead of using SMS one could also use a data connection, however a data connection via GPRS appears to sometimes attract a higher minimum charge on any day that data is used. I also felt that a data connection was more complex since I would need to set up a server on the internet to send the data to. Sending data in GSM SMS messages to a smartphone is simple and requires no software on the smartphone (although you could write an app to receive and present the messages instead of just viewing the text, but again this is significant extra work!).
Alternatives to the Cell Phone Network
Technologies such as LoRa and SigFox have been developed for the ‘internet of things’ offering devices connection to the internet using low-power radio communications with low data rates. SIMs are not required. These may well be a better option but they are unfamiliar to me, I’m not sure about coverage, and again they would seem to require some server-side work to get the data to the end user. Well worth investigating however. I note that LoRa modems can both connect to a network for long range communication, and also operate point to point for distances of up to 2 or 3 km or so (depending on topology, etc) - useful if your logger is not very far away.
I tried a number of small and very cheap (£5 or less) GSM modems sourced from China. I was able to get them to see the mobile network but none of them would register in the UK. Eventually I bought a Siemens TC35 modem (a larger PCB costing about £15 to £20) which worked without any problems.
The GSM module was purchased via ebay: "GSM SIEMENS TC35 SMS Wireless Module UART/232"
Siemens TC35 development board on-board industrial-grade dual-band GSM module: TC35, Working Band Dual Band: 900/1800Mhz, can achieve low power consumption of voice, SMS (text messages, MMS does not support transmission, adaptive wide baud 4800bps ~ 115200bps.
The module has a reasonable power consumption of approximately 150-200mA during calls and 40-50mA when idle with SIM card registered on the network. To save power, remove the MAX232 IC from its socket, as it is not needed (as we don’t use the RS232 interface) and it consumes additional power.
Powering Up and Activating the TC35 GSM Module
From Siemens TC35 / TC37 Hardware Interface Description, section “Timing of the ignition process”: When designing your application platform take into account that powering up TC35/TC37 requires the following steps.
a) The ignition line cannot be operated until V BATT+ passes the level of 3.0V.
b) 10ms after V BATT+ has reached 3.0V the ignition line can be switched low. The duration of the falling edge must not exceed 1ms.
c) Another 100ms are required to power up the module.
d) Ensure that V BATT+ does not fall below 3.0V while the ignition line is driven. Otherwise the module cannot be activated.
e) If the VDDLP line is fed from an external power supply as explained in Chapter 3.3.4, the /IGT line is HiZ before the rising edge of VBATT+.
From Ignition going low for 100ms, "Figure 7: Power-on by ignition signal" shows a maximum of 900mS until the modem is ready for AT commands, i.e. 800mS after Ignition line goes high again.
Powering Down: From Siemens TC35 / TC37 Hardware Interface Description, section “3.3.4.1 Turn off GSM engine using AT command”: The best and safest approach to powering down the engine is to issue the AT^SMSO command. This procedure lets the engine log off from the network and allows the software to enter into a secure state and to save data before disconnecting the power supply.
See also AT Command Set, section 6.18 AT^SMSO Switch off mobile station:
Test command: AT^SMSO=? Response: OK
Execute command: AT^SMSO Response: ^SMSO: MS OFF OK
I used the 19200 baud rate to talk to modem which I believe is the DEFAULT rate.
I found by trial and error that after powering ON the modem, some delays were necessary for correct operation. Additionally, after each step, the software waits for any response (which it copies to the terminal and to ERROR.TXT for debug if required). If an ‘OK’ response from the MODEM is expected, the program waits for several seconds, but this is cut short as soon as the “OK” is detected. In other steps that don’t result in an ‘OK’, a shorter wait is used.
To achieve low power consumption and thus a long battery life, the sensors you connect to your data logger should also only be powered-up when the Arduino, SD Reader, etc. are powered up to take a log. If that is not possible because for some reason the sensor needs to be continuously powered, then you will need to focus on minimising its power consumption.
Many low-cost sensors that are easy to connect to an Arduino are available. For the Hive Logger I used weight (more correctly ‘force’) sensors (load cells supplied with an HX711 A/D PCB to read them), and the LM335 precision temperature sensor(*). The connections to these are on the circuit diagram; refer to the Hive Logger page for more details.
For any sensor you find for sale, you will often also find that other people have already used the sensor and put a tutorial on the web. Similarly there may be an Arduino library that makes using the sensor easy (there is for example for the HX711).
(*) Note: Fake LM335s are on the market on ebay. The codes on the fake devices I received were 42752 LM335Z. The symptom is in a test set up at 20C they give about 0.7V instead of 2.93V.
The circuit was designed in KiCad and a PCB (the “Hive PCB”), and a PCB laid out. The circuit diagram is shown below but is probably best viewed via the KiCad project. A view of the PCB is also shown.
To understand how to use KiCad, see the brilliant series of several Youtube videos starting with An "Intro to KiCad – Part 1: How PCBs Are Made | DigiKey". There are 10 videos that take you through the whole process - essential viewing!
The PCB gerber files generated by KiCad were sent for manufacture to Chinese company JLC PCB who made 5 copies of the PCB for under in £10 total. Had I used surface mount components, they could also have populated them.
Hive PCB Circuit Diagram
View of the Hive PCB in KiCad
As the project grew in scope, I ended up struggling to fit all the code I wanted into the Arduino Nano’s program memory (flash). It is also easy to run out of dynamic memory RAM too, especially if using many strings (text). See the section ‘Arduino Memory’ above for more details about memory use.
The software is in a single file, the current version is here: LowPower_DataLogger_v4_3.
It does of course use various Arduino libraries.
The software depends on the SD Card being present and containing the following files in the root directory (Note: the SD Library only supports short 8.3 names for files; max 8 characters + extension):
UITXT.TXT : Specifies User Interface text displayed by the program.
CONFIG.TXT : Specifies the configuration settings.
Both these files actually have a CSV (Comma Separated Value) format, but I’ve used the extension TXT so that they are opened by a text editor when clicked, not Excel.
The UITXT.TXT file is used to store the many strings used by the UI somewhere other than in program memory (of which there is not enough). On program start, they are loaded into the Nano’s EEPROM (or if already in EEPROM, updated if any have changed). The number and order of the text strings in the file must exactly max an enum in the program. The use of this method allows multi-language support. Currently there is a column in UITXT.TXT for the English version and another for the Spanish. An entry in the CONFIG.TXT file specifies which of these should be used.
This technique of storing texts in EEPROM and multi-language support could well be useful in other Arduino projects.
Because the Data Logger has no keypad, just a push-button, it would not be easy to configure the data logger from it’s own UI. Therefore configuration is achieved by editing the CONFIG.TXT file on a PC and then saving it to the SD Card.
The CONFIG.TXT file is in CSV format and contains parameters ‘numbered’ in the first column ‘PARAM’ by the letters A to I. The second column is the VALUE which is what the user can edit. The 3rd and 4th columns are just to help when editing and contain the NAME / NOMBRE of the parameter in English and Spanish; they are not used by the software. These parameters allow the user to specify: (A&B) a Start and End time for logging; (C&D) how often logs should be taken in Days, Hours or Minutes; (E) how many days between sending an SMS; (F) SMS enabled or disabled; (G) the phone number of the smartphone to send the SMS to; (H) a 4-character hive name or ID to go in the SMS; (I) whether the UI should be in English of Spanish. An example is shown below.
PARAM, VALUE, NAME, NOMBRE A, 2020-10-10 14:00,Start,Inicio B, 2020-10-18 18:00,End,Fin C, 2,Every,Cada D, H,D_H_or_M, D_H_o_M E, 1,DaysPerSMS,DiasPorSMS F, Y,SMS_Yes_No,SMS_Si_No G, +441234567890,TelNum,TelNum H, Hiv1,Hive,Colmena I, S,Lang,Idioma
The Data Logger writes to two files on the SD Card, which it creates the first time it executes.
LOG.TXT : Where the log data is written
ERROR.TXT : Where AT Command dialogues and any error messages are written.
The LOG File
The data captured by the Data Logger is written to the file LOG.TXT, again in a CSV format. The columns (Date-Time, measurements, etc.) are easily understood.
The first line of the LOG file is the column headings. These are:
DateTime , Wt(kg) ,Ex(C), In(C), Bat, M, Er
The first 4 columns are the Time of the measurement, the Weight in kg and the External and Internal temperatures in Centigrade.
The remaining columns are for diagnostics. They are:
Bat - The battery voltage. This is included because if the battery voltage falls too low, the measurements may be unreliable (in particular the temperature readings may be ridiculously high).
M - The Mode. It indicates the type of log. Possible values are ‘A’ for an automatic log (when the Logger wakes up by itself), or ‘M’ for a manual log (i.e. when you wake up the Logger with the push button, or on first switch on).
Er - Error Number. If an error was detected, the number is logged. 0 = No Error. A list of errors is in the ‘List of Possible Errors’ section. Details of the error should also have been written to ERROR.TXT.
To use the LOG file copy it to a PC. You can view it in a text editor (like Microsoft Notepad); normally a text editor will open it automatically if the extension is .TXT
You can also open the LOG file in a spreadsheet like Excel. The easiest way to do this is to make the file extension .CSV and then click on it.
When Excel opens the CSV file for the first time, it is likely to ask how you want to import the columns. Select the DateTime column and choose Date YMD. The DateTime should now be in the first column of the spreadsheet and you will be able to generate graphs with DateTime as the X-Axis.
The ERROR File
Errors detected by the program are written to the ERROR.TXT file on the SD card with the DateTime that they occurred. When sending an SMS, all interactions with the GSM MODEM (the AT commands and their responses) are written to the ERROR.TXT file whether normal or not, so that if problems occur with sending the SMS message, then they can hopefully be diagnosed by inspecting this file on a PC. The ERROR.TXT file will therefore steadily grow but there is lots of space on an SD card! If desired, the file can be deleted and the software will create a new one.
Arduino programs are arranged in two functions: setup() which is executed once when the Arduino powers up or is reset; loop() which executes after setup and as the name implies, loops forever. The Data Logger program is a little unusual in that we power up for each log, so each time setup() is run. Pseudocode for the program is given below.
SET UP CODE =========== Set programERROR to NO_ERRORS (none). Initialise Serial, SD Card interface, Real Time Clock, LCD. Read the configuration from the CONFIG.TXT file on SD. Read English or Spanish UI Texts from UITXT.TXT on SD. Determine Wake-Up reason. May be ‘Manual’ (from switch on or push button) or the RTC alarm. IF Wake-Up reason was 'Manual' THEN set ManualWakeUp TRUE ENDIF Display WELCOME screen MAIN LOOP ========= Read Battery Voltage Init & Clear LCD, and display Time, Battery Voltage. IF RTC Alarm has fired THEN set DoAlarmLog TRUE ENDIF (note: if Nano is continuously powered from PC, the alarm may have gone off since last time around the loop) */ Clear the alarm and disable it. Work out when the alarm needs to go off to do next log and set it. Display number of LogTimes since Start, and the next LogTime. Make Measurements ... Read Temperatures and Weight. IF DoManualLog THEN log measurements to LOG file, marked 'M' for Manual. ENDIF IF DoAlarmLog THEN Log measurements to LOG file, marked 'A' for Auto. IF SMS Due THEN Send SMS ENDIF ENDIF IF FATAL ERROR THEN Display error Clear and disable alarm, or the unit will never sleep. The unit will not wake up again except by a manual wakeup or when connected to a PC. ENDIF IF WakeUp was Alarm OR wake up was Manual and has now been handled THEN IF WakeUp was Manual THEN display GOODBYE text ENDIF POWER DOWN (The Arduino and most of the data logger will switch OFF) ENDIF ***************************************************************** // We only get to here if it was a manual wake up (not alarm) or we are // continuously powered IF No program ERRORs THEN Display current measurements and how long until the next log ELSE Display the ERROR number and Error details on the LCD screen ENDIF Display Clock screens and ask user if they want to adjust the clock. IF Yes, enter clock adjustment dialogue. Ask user if they want to view the configuration settings. IF Yes, enter the view config screens. Ask user if they want to calibrate the sensors (Optional, in some builds only). IF Yes, enter the calibration screens. Ask user if they want to sent a test SMS. IF Yes, display “Sending SMS to” until completed. /* End of MAIN LOOP – The Manual WakeUp has now been handled */
Arduino Nano On-Board Regulators
If powering peripherals from the Arduino regulated 5V supply, you must not exceed it’s maximum rating. It seems there’s not a simple answer to what that maximum is, since if you supply V_in of the Arduino with a higher voltage you will have more heat generated for a given current and will therefore need a lower limit. The regulator on my Nano is AMS1117. While its maximum may be about 1A, in practice, people suggest a lower limit, e.g. with 9volt on V-in, a limit of about 225mA (including 25mA for the Nano itself). In practice we are trying to minimise the data logger’s consumption, so this should be plenty.
The Nano also has a 3.3V supply generated by on-board voltage regulator.
To estimate the battery life we need to know how much the data logger consumes when operating, how long it operates for, and what the residual consumption is when asleep between measurements.
Module | Current (measured, or from data sheet) |
Arduino Nano | About 20mA |
16x2 HD44780 5V LCD Display Module + I2C serial interface module | 5mA no backlight, 18mA backlight ON |
RTC Real Time Clock DS3231 & 24C32 with I2C interface | 4.2mA from 5V supply. Timekeeping Battery Current: 0.84uA typical, 3uA maximum. |
MicroSD Card Reader with SPI interface | Once started, 20mA with SD.h. With SdFat library, 20mA when accessed but only 4.5mA afterwards. |
I measured the consumption of the completed Hive Data Logger, and got these results:
Operating State | Current drawn from PP3 |
Asleep | 7.5uA |
Awake, GSM TC35 not powered up | 40mA to 45mA |
Awake, GSM TC35 powered up and sending SMS | 65mA with some periods at about 120mA |
MicroSD Card Reader with SPI interface | Once started, 20mA with SD.h. With SdFat library, 20mA when accessed but only 4.5mA afterwards. |
We also need to know how long the data logger is ON for. There is a minimum time because the Arduino takes a couple of seconds to boot up. People report Arduino measured startup delays from application of power to the entry to setup() (signalled by a pin write) as between 1.7-2.2s (some say 3s). Ho much extra time the logger needs to be on for above this minimum depends on your application. With the Hive Data Logger, and got these results:
Logger Action | Time ON |
Normal WakeUp to take a log (no SMS sent) | 4 to 5 seconds |
Time to send an SMS. Note: longer if AT+CREG? has to be retried various times because modem is slow to register onto a network. | About 25 seconds (up to ~ minute if CREG retries) |
PP3 9 volt batteries are made using a variety of technologies. Note that the typical voltage supplied, particularly by rechargeable batteries is lower than 9V, in one case so low that it is unsuitable. Some PP3 batteries are:
Battery Type | Suitability |
Rechargeable NiMH (typically 210 to 250mAh) | Should get most of quoted mAh before voltage goes below 7.3V |
Rechargeable NiMH 300mAh from Ansmann | Has significantly more capacity and maintains voltage well under load. |
Rechargeable Lithium-ion (Nominal voltage 7.4V) | Attractive capacities but nominal voltage is too low: 7.4V, with final discharge voltage 5.5V. |
Disposable Alkaline: Duracell Plus 9V PP3 6LR61 | About 2.5 hours at 50mA (=125mAh), or only about 0.75 hours at 100mA (=75mAh). |
Disposable Lithium: Energizer Ultimate Lithium 9V PP3 6LR61 800mAh. | From data sheet: 6.5 hours at 100mA (= 650mAh). Therefore: should give about 2 to 3 times the life of a 250mA rechargeable. |
Battery manufacturers should quote the mAh (milliAamp hours) capacity of the battery. We also have to avoid discharging the battery to the point where its voltage falls below the minimum the data logger requires.
So first we need to find out what the minimum voltage the logger requires. Experience with the Hive logger is that temperature readings become erroneous once Vin to the Arduino falls below about 6.5V (probably because below this point the Nano's regulator doesn't produces a constant 5V). However from the battery terminal to the Nano there is a 0.78V drop across the safety diode and TIP32. Thus the minimum battery voltage is more like 7.3V
Now that we know the minimum voltage required, we can check battery data to get an estimate of the mAh we can expect the battery to supply, at a voltage greater than this minimum. Typically the manufacturer will supply a graph showing the effects of different discharge rates. Below is an example for one brand of rechargeable NiMH battery:
GP Batteries GP20R8H Typical: 210mAh Rated: 200mAh When discharged at 40mA to 7.0V at 20Centigrade. From data sheet graphs: 5 hours to fall to 7.3V at 40mA (= 200mAh), 2 hours to fall to 7.3V at 100mA (= 200mAh), 11.5 hours to fall to 7.3V at 20mA (= 230mAh). Discharge : -20 to 50°C Storage : -20 to 35°C. Recommended discharge current 20 to 600mA.
Based on the above data, estimates for battery life mad for the Hive logger, using a rechargeable PP3 9V 250mAh battery are:
8 months operation with 2 logs per day and 1 SMS per day.
12 months operation with 2 logs per day and an SMS every 2 days.
14 months operation with 2 logs per day and an SMS every 3 days.
To build a data logger like the one described, you need some understanding of electronics and experience of building circuits, plus a familiarity with Arduino hardware and software. There are many tutorials on the web if needed.
Then, depending on your level of skill, I suggest prototyping bits of the system on an electronics breadboard/plugboard. With any new module I acquire - say the SD Card Reader – I usually set up just the new module and an Arduino on a breadboard, install any required library and get I working with a simple test program. Libraries will usually have examples and test software which you can use and modify if needed.
Once you are confident you know how to use all the modules, you could build the Power-Up circuitry required for the data logger. So you will want the Arduino, the RTC, the NAND gates for the flip flop, and a few discrete components (resistors, transistors, etc.). When you achieve this you then have a basic data logger with limited storage available in the Arduino EEPROM. You can then proceed to add the sensors you require, and whichever combination of SD-Card, display, and communications, that you want.
Mounting the Data Logger
I have packaged my Hive Logger in a plastic project box with transparent lid. These boxes have a flange and rubber seal, though are probably not completely waterproof. An advantage of the transparent lid is that you can see the display as well as any indicator LEDs without having to cut a hole in the case.
Data loggers have countless applications. This logger was designed for low power unattended operation where measurements are made infrequently. Infrequent being at least several minutes apart, because although the unit could be programmed to log every 10 seconds or so, the powered-down periods between logs would be long enough to reduce the average power consumption by much.
Applications that occur to me include:
Pollution / Air Quality monitoring station. A Plantower PMS 5003 or PMS 7003 sensor could be connected to the logger for monitoring particulates like PM2.5.
Pollution / Air Quality of journeys. As above but also including a GPS module so that you could measure the variation of pollution along a route.
Solar Oven performance. Measuring inside and outside temperatures.
Alarms. Wake the unit via by triggering the power control bistable, either when a sensor value exceeds a bound or due to some indication of crime (e.g. a door opened).
ENDS