Weather station rebuilding - Improving energy consumption / using other sd lib


at the moment my weather station uses a 5V/16MHz Arduino Pro Mini, Nokia 5110 display, DHT22, BMP180, RTC3231 and SD card reader (with normal SD.h lib !) for logging data every 15 minutes. It uses 3 AA batteries on a Pololu 5V step up converter. LEDs are desoldered and deep sleep is used. It works quite nice, however every 5 - 6 weeks the batteries are empty and i don´t really like the display because it´s small, contrast is bad and the sleep consumption is still quite high (0.4 mA). The whole station uses about 0.8 - 1.0mA in sleep (depending on battery voltage), which also is quite high.

So i decided to rebuild it and bought a Waveshare 2.9 (should be 3.3V, but works with 5V as well) inch epaper display. It took me quite a long time to rework the given lib for my needs (adding sleep, progmem for fonts and logic for importing fonts from dotfactory). Nevertheless it still uses more memory than the old Nokia display. This leads to the first big problem:

  • I can´t use SD.h any longer because it uses too much memory (all together over 70%). This makes the code unstable. Is crashes or freezes the display after few loops. If i remove SD.h and the sd-code, it runs fine ... Are there any SD-libs that use less (i need about 20% less) memory than SD.h that uses over 50%? ... I just use 2GB SD card for logging a few values in a csv-file which has the name of the date (for example 20170727.csv). What about this one ? : I didn´t try it yet, just want to know from experience how to use SD-cards without this memory killing SD.h ...

The other thing is the energy consumption. I tried to undervolt the arduino to 3.3V by giving it 3.3V at 5V pin ... and it works fine. So I made some measurements with results (including sensors and epaper display in sleep - but without any voltage converter):

5V in deep sleep: 0.11mA 5V while active: about 12mA

3.3V in deep sleep: 0.05mA 3.3V while active: about 8mA

... which leads me to 2 possibilities.

1) Running it without any voltage converter with 3x AA (4.5V at the beginning dropping to 3.0V shortly before dying).

2) Rebuilding it to 4 batteries (with 2 in row and 2 parallel) giving 3.0V at the beginning, dropping to 2.0V at the end. This would need a step up converter to 3.3V. My old 5V pololu uses about 0.4mA in idle which is too bad in my opinion. Is there any 3.3V stepup converter which does not exceed 0.05mA in idle (so that at least it would not exceed the 5V-non-converter-configuration in idle) ?


My approach would be to get rid of the converter and choose components that will operate on 2x alkaline AA batteries, or use a low drop out 3.3V converter and 3x NiMH AA batteries with a solar cell as trickle charger.

Also, you can eliminate the SD card and its associated code. Instead, you can use the outstanding Sparkfun Openlog as an outboard data logger, although that may draw too much current when the rest of the system is sleeping.

Have you followed all the tips is this low power tutorial?

“Have you followed all the tips is this low power tutorial?”

•Run the processor at a lower frequency
→ No.
•Run the processor at a lower voltage
→ Yes. 3.3V via 5V Pin on Pro Mini.
•Turn off unneeded internal modules in software (eg. SPI, I2C, Serial, ADC)
→ Yes. However, turning off the I2C doesn´t really work. This causes another, however smaller, Problem.
•Turn off brownout detection
→ VPowering via 5V pin should bypass the brownout. Otherwise it would have shut down at 16Mhz / 3.3V
•Turn off the Analog-to-Digital converter (ADC)
→ Yes.
•Turn off the watchdog timer
→ No.
•Put the processor to sleep
→ Yes. Deep Sleep Mode.
•Don’t use inefficient voltage regulators - if possible run directly from batteries
→ Yes. I plan to get rid of it in my new configuration.
•Don’t use power-hungry displays (eg. indicator LEDs, backlit LCDs)
→ The Waveshare epaper uses no power at all (< 10µa) in sleep mode
•Arrange to wake the processor from sleep only when needed
→ Yes.
•Turn off (with a MOSFET) external devices (eg. SD cards, temperature sensors) until needed
→ didn´t do it yet.

All in all i have 50µa consumption @3.3v only with arduino, still 50µa with BMP180(i2c), DHT22(onewire) and the Display(SPI). But with the DS3231 (i use this very basic one: it rises to 120µa because i cannot really shut down the i2c. The voltages just drops from 3.33V to 3.1V when shutting down SDA and SCL. So there has to be a leakage somewhere … On I2C a cheap ebay basic BMP180 is master and the ds3231 slave.

“Also, you can eliminate the SD card and its associated code. Instead, you can use the outstanding Sparkfun Openlog as an outboard data logger, although that may draw too much current when the rest of the system is sleeping.”
→ Well. If it uses 2mA in sleep, it´s useless. Even my old weather station uses below 1mA all in all in sleep. My new one would use 0.12mA at the Moment. If i get the ds3231 shut down somehow, i could even reach 0.05mA. In the old configuration, the SD Card Reader used no power at all in sleep, because i powered it from pin. I plan to save data in Eeprom and write it only once a day instead writing it every 15 minutes onto SD card. The only Problem is the massive SRAM consumption of all SDCard libs. My sketch is getting unstable somewhere between 60 and 65% of used SRAM for global variables. I already have removed many floats and used int16_t or even int8_t instead. But it just isn´t enough. With sdcard using 45% of SRAM there is no room … :confused:
Is there no way to reduce this global 512 Byte Buffer in These libs ? Speed is no Problem, because the writte data is very small.

… powering down the I2C is now finished, too. There were 3 (!) pullups on I2C. I deactivated the arduino internal and desoldered the two 432 (4.3k) on the RTC. The soldered ones on the BMP180 are now the only left. Using a digital pin for powering the RTC (for being able to shut it down) brings me now down to 50µa in sleep. → This is good enough for me.

Another thing is:
I have not given up to use the classic SD.h (or perhaps SDFAT) for logging onto SD card. However, therefore i have to free a bit more SRAM. So i went back to the Waveshare Lib, because they put everything in SRAM. And i found some Hex Arrays (which are in fact static const) that can stay in flash. However, they are not used directly, but forwarded as pointers through some functions. and i just don´t know where [and why] to use the pgm_read_byte statement. I did some try-and-error but nothing has worked yet. The code is:

static const unsigned char LUTDefault_full[] = {31 Hex numbers ...};

void WaveShare_EPD::EPD_Write(unsigned char *value, unsigned char datalen)
	unsigned int i = 0;
	unsigned char *ptemp;
	ptemp = value; // pgm_read_byte(&value); - not working
	EPD_DC_0;		// When DC is 0, write command 
	SPI_Write(*ptemp);	//The first byte is written with the command value
	EPD_DC_1;		// When DC is 1, write data
	//Serial.println("send data  :"); 
	for(i= 0;i<datalen-1;i++){	// sub the data

void WaveShare_EPD::EPD_WirteLUT(unsigned char *LUTvalue,unsigned char Size)
	EPD_Write(LUTvalue, Size); // pgm_read_byte(&LUTvalue); - not working

void WaveShare_EPD::EPD_init_Full(void)
	EPD_Init();			// Reset and set register 
  EPD_WirteLUT((unsigned char *)LUTDefault_full,sizeof(LUTDefault_full));   // neu

In setup you call EPD_init_full() for initializing the display (with the given hex data in the array). From there the array is given as a pointer to the function EPD_WirteLUT (casted to uchar pointer). This function then gives the size of array and every single uchar value to EPD_Write. There it is written by SPI to the display.
Where do i have to put the pgm_read_byte statement when using PROGMEM for the array ? I don´t get it with all the casting and pointers. I know that pgm_read_byte doesn´t work with sizeof (it always returns 1), so i put 31 instead of the given sizeof statement. As long as i just use this one display type, this is okay… I mentioned above where i tried to ut the pgm_read_byte statement. Nevertheless it doesn´t work.

THX so far.

Read the Cave Pearl project blog there are a lot of tips using DS3231 (you have to remove some resistors), SD card, Pro mini (you have to cut the trace to the LDO in the board). The guy who write in this bloag has years of experience. For example he logs data in the DS3231 board flash chip and when is filled he writes data on SD.

Is there any possibility to change battery setup?

3x C cells could triple your battery run time on your old setup. (3-4 months run time) 3x D cells could hextuple the run time. (7-8 months run time)

or go Solar like jremington suggested, and use a single LiFePO4 14500 cell or 3x NiMh AA and run indefinitely.

Watch out for C and D-cells that are cheap and just an AA cell inside a larger cylinder. Surprizingly common. For long battery life you have to avoid secondary cells with a high self-discharge rate like standard NiMH, since whatever the capacity they are flat in a couple of months!

MarkT: Watch out for C and D-cells that are cheap and just an AA cell inside a larger cylinder. Surprizingly common. For long battery life you have to avoid secondary cells with a high self-discharge rate like standard NiMH, since whatever the capacity they are flat in a couple of months!

Open an Ultrafire 18650 and you'll find sand and other chinese debris inside and if you manage to find a coin cell inside you can consider yourself lucky. :P

CandlePowerForum has a battery shootout thread and you can see RayOVac D Alkaline outperforms both Duracell and Energizer with 12Ah @500mA discharge. Staying away from Zinc Carbon D cells is recommended.

However in BatteryShowdown's AA alkaline tests, Ikea Alkalisk along with Kirkland outperformed almost all major brands except Varta. Ikea cells were also the cheapest they ever tested. I guess when it comes to AAs, cheapos beats the branded. :D

so ... little update from me. The project is almost finished. With every possible trick (bit booleans, progmem, PSTR for constant strings in waveshare lib, ruducing floats by saving them as (u)int16_t) i was successful to get it running stable. 88% flash and 60% SRAM for globals ...

I had to remove the VCC powering of the DS3231 after desoldering the pullup resistors, because without these and with VCC power from pin, it resetted the datetime from time to time. Don´t know why ... I now just have SDA, SCL and GND connected and it works fine. To be honest, after rethinking it again, i don´t even know why the DS3231 didn´t shutdown with these pullups. Because when powering via Pin, you need additional pullups, because they are for the "pin-vcc" while the others on the I2C are connected to "normal" VCC. It should work and shutdown normaly even with these pullups. But it didn´t ... Well, without any power except from battery it works fine now. Another thing i realized was that different (china) arduinos have different voltage regulators. And these can have massive effect in µa regions even when powering via VCC. They consume power even when "backwards" powered ! I had 3 different types. Two with A6, A7 and GND on backside and red plastic reset button (one type has "deek robot" written on the backside, the other type has "Arduino-Pro-Mini" written there). The third type has nothing on the backside and A6 / A7 in the middle like A4 and A5 and a metal reset button. The "deek robot" one had 50µa at 3.3V powered via VCC pin and with voltage regulator. Both others had about 110µa. After removing the voltage regulator on one of the metal-reset-button-type arduinos (i have many of them ...), i got 20µa. So on the deek robot the regulator uses 30µa, both others consume 90µa when backwards powered ... Last but not least i now only save 2 values per hour (at minute = 0 and minute = 30) and save them in eeprom. Once a day (when 48 values are stored in eeprom) i write them to sdcard at once. It saves massive power, because writing all values almost doesn´t take more time than saving one value. Just powering on and initializing sdlib uses 70mA for about 0.5 sec ! I power the sdcard via 4 digital pins (:D) because my transistors i have here (TIP122) all consume too much power even when base isn´t powered ... Display value refreshing is only done when: temp changes +- 0.5°C, when minmax changes, pressure changes +- 0.5hPa or humidity +- 1%. If i refresh all values, the promini is active for about 5 seconds due to the high resolution (too much). This way i have average activity round about 1.5 sec @ 12mA (5V) or 8mA (3.3V).

All in all: 0.06mA (standby) + (10mA / 60 * 1.5sec)(activity) + 70mA /(60*60*24sec) = 0.32mA average -> 2000mAh (AA cell capacity) / 0.32mA = 6250 hours / 24 = 260 days. If this is real, i will rework it to 6 AA cells (3 in row / 2 parallel -> 4.5V -> 4000mAh) and it should last 1.5 years. Definitely no solar cell needed.

What is giving me a bit of concern is: I bought a 2nd waveshare 2.9 screen for testing and playing around. And i realized that my 1st one is much more grey/brown in background and the letters are more "washed out" (i will post a photo ). I hope that is isn´t an issue because of the too high voltage. It should be used only at 3.3V only. I tested it at 5V and in my configuration is also gets 4.5V max when batteries are new. However, the usage of voltage regulators would totally destroy my idle consumption. And i would have to use one that could shift the SPI, because it leaks somehow, too. When i connect 5V SPI and 3.3V VCC to the display, i measure about 4.5V at display VCC ...

Here is the photo. A bit blurry because it is made inside (not enough light) from mobile phone , but still you can see it …