In this topic I want to place all kinds of battery tips like how to reduce power consumption and how to measure your battery life for instance. I’m not a expert on this, but i want to share all the things i found out.
This topic will be based on Arduino Pro Mini’s (3.3V) and Attiny’s.
Hardware mods
The 3.3V pro mini is a easy to use device. It has all the functions you need and its quite small. If you want to use it for a battery powered sensor you must do some modifications because it draws to much power by itself.
Remove the power LED and regulator
The LED uses around 1,5 mA, thats quite a lot. The regulator uses around 50uA. Sounds not that much but imagine that a PIR sensor uses around 240 uA with the regulator. Remove the components according to the image below (please do not cut any lines, removing the components will do it). After that you can’t use the Vcc of the programmer anymore.
Software mods
Change BOD to 1.8V instead of 2.7V
This step is a little bit harder. because you have do change some fuses in the 328P (this is not needed for the attiny’s because the drop-out voltage is disabled by default). By default the Arduino has a drop-out voltage of 2.7V. That means if your batteries are lower than 2.7V, the Arduino stops working. You can adjust it to 1.8V or even disable it. The main thing what its all about is that you have the fuses like this:
LOW: 0xff
HIGH: 0xda
EXTENDED: 0x06
Go to your arduino folder.
Mac: user/library/arduino15/packages/arduino/hardware/avr/1.6.x/
Windows: [arduino folder]\hardware\arduino\
open boards.txt and search for ## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
a little bit lower your see this:
pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0x05
change it to:
pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0x06
Now all you have to do is re-burn the bootloader with a AVRISP or an arduino as ISP (read here below).
Run the Pro Mini on 1 Mhz
If your arduino is running on 8 Mhz, it can’t go lower than 2.4V. If you change it to 1 Mhz, it can go to 1.8V. To do this you need a custom board and a new bootloader for the arduino IDE.
Go to your arduino folder and edit the boards.txt.
Mac: user/library/arduino15/packages/arduino/hardware/avr/1.6.x/
Windows: [arduino folder]\hardware\arduino\
search for ## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
and add this after the last line (pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L
) of this device:
## Arduino Pro or Pro Mini (1.8V, 1 MHz) w/ ATmega328
## --------------------------------------------------
pro.menu.cpu.1MHzatmega328=ATmega328 (1.8V, 1 MHz)
pro.menu.cpu.1MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.1MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.1MHzatmega328.upload.speed=9600
pro.menu.cpu.1MHzatmega328.bootloader.low_fuses=0x62
pro.menu.cpu.1MHzatmega328.bootloader.high_fuses=0xD4
pro.menu.cpu.1MHzatmega328.bootloader.extended_fuses=0x06
pro.menu.cpu.1MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_1MHz.hex
pro.menu.cpu.1MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.1MHzatmega328.build.f_cpu=1000000L
The next thing you have to do is add a new bootloader. In the arduino folder go to bootloaders/atmega/ and create a new hex file called ATmegaBOOT_168_atmega328_pro_1MHz.hex
In this file add these hex codes and save it:
:107E0000112484B714BE81FFE6D085E08093810001
:107E100082E08093C00088E18093C10086E0809377
:107E2000C2008CE08093C4008EE0BFD0259A86E02B
:107E300023EC3FEF91E0309385002093840096BBC4
:107E4000B09BFECF1D9AA8958150A9F7EE24FF2480
:107E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E45
:107E600098D0813461F495D0082FA5D0023829F13B
:107E7000013811F485E001C083E083D07FC08234F3
:107E800011F484E103C0853419F485E09CD076C0F8
:107E9000853579F47ED0E82EFF247BD0082F10E0C2
:107EA000102F00270E291F29000F111F84D07801E1
:107EB00065C0863521F484E086D080E0DECF84364C
:107EC00009F040C066D065D0082F63D080E0E81686
:107ED00080E7F80618F4F701D7BEE895C0E0D1E0D6
:107EE00058D089930C17E1F7F0E0EF16F0E7FF06A2
:107EF00018F0F701D7BEE8955ED007B600FCFDCFBD
:107F0000A701A0E0B1E02C9130E011968C9111977F
:107F100090E0982F8827822B932B1296FA010C0160
:107F2000A7BEE89511244E5F5F4FF1E0A038BF0770
:107F300051F7F701C7BEE89507B600FCFDCFB7BE05
:107F4000E8951CC0843761F424D023D0082F21D0B9
:107F500032D0F70185917F0114D00150D1F70EC0C6
:107F6000853739F428D08EE10CD085E90AD08FE02E
:107F700084CF813511F488E018D01DD080E101D084
:107F80006FCF982F8091C00085FFFCCF9093C600E3
:107F900008958091C00087FFFCCF8091C00084FDD0
:107FA00001C0A8958091C6000895E0E6F0E098E150
:107FB000908380830895EDDF803219F088E0F5DF4B
:107FC000FFCF84E1DECF1F93182FE3DF1150E9F7D5
:107FD000F2DF1F910895282E80E0E7DFEE27FF27CC
:027FE000099402
:027FFE0000057C
:0400000300007E007B
:00000001FF
Start up the arduino IDE and select board arduino pro mini and after that processor: Atmega328 (1.8V, 1 MHz).
Now you can burn your new bootloader with 1 Mhz with a AVRISP or arduinoISP.
The arduino programmer (ISP)
To change the fuses, you need an AVR programmer. The easiest way is to use a Arduino Uno and load the sketch ‘ArduinoISP’ to it. after that set it up like this:
In the programs AVRFuses or AVR studio you can simply use the AVRISP programmer.
Measure your battery
If you attach your batteries directly to the Vcc, the 328p or attiny can measure the voltage. This can be used as battery level (Be aware: this gives you an indication, its not 100% accurate).
Add this to the bottom of your sensor sketch in the Arduino IDE (or add this library):
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
Now you can call the function readVcc():
float batteryV = readVcc();
To change it to percentages you have to set the minimal voltage (empty) and the max voltage (full).
Lets say 3.2V is full and 2.4V is empty.
then this is the formula:
int MIN_V = 2400;
int MAX_V = 3200;
batteryPcnt = min(map(batteryV, MIN_V, MAX_V, 0, 100), 100);
So if your battery is 2.8V: (((2800 - 2400) / (3200 - 2400)) * 100 ) = 50%
more to be add…
If you have any tips, feel free to post it!