How low can arduino can go?
-
@HarryDutch thanks for we'll explained information. I really really appreciate it. Thanks to you, my adventure go to land of low power start to Gammon website. Well explained also in that website.
And finally I can make justification about what cause that give me bad power consumption. Start with plain arduino, either using led or not, finally I can dive to 4uA (thanks to you). After that, slowly but sure, I attach RF, the result still quite the same (without calling mysensor library) - few uA differences - not significant.Then I start with mysensor code, and guess what, it now bump to 2.2mA like my first email. At this point, I realized the one that cause high power consumption is mysensor library. Until now, I still doing test about this. Will update it here for sketches and result for every sketch.
@funky81 Interesting ... that should not happen. Does your node actually communicate with the gateway? The "normal" power consumption I have: a few seconds around 2-3 mA (starting-up) ; 2-10 seconds 27 mA (sending, searching for communication partner); until end of "gw.sleep" 20 uA (withing the limits of my equipment).
-
To be honest I have not the foggiest idea why the current drops that much during sleep after a few days. What I do know is that 900 and 120 µA during sleep is way too much. The point is that whatever you connect to your Arduino, you have to switch it off when it’s not needed. At least when you use batteries to power your project. Take for example the DHT22 you use. According to the datasheet it’s using 50 µA in stand-by mode and the current drain of the light sensor (LM393?) is about 800 µA. I assume that you want to take a sample every 5 minutes or so? If that’s the case you can sleep the Arduino between 2 samples and switch off the light sensor and the DHT22 sensor at the same time.
There are a couple of ways to achieve that: using a transistor (http://jeelabs.org/2012/09/07/switching-with-a-pnp-transistor/#comments) using a MOSFET (logic level) (http://jeelabs.org/2012/09/08/switching-with-a-p-mosfet/) or using one of the I/O pins of the Arduino as a “power supply”. The last solution only works for low currents like 1.5 mA (max) for the DHT22. I don’t have the specs for the LM393 but it should be around 3 mA. There’s one important fact about using I/O pins as power pins and that is the voltage drop. When you click the first URL above you see a graph showing the relation between the pin output voltage and the source current. As you can see there is a voltage drop so that the sensor will not get the full supply voltage. Looking at the datasheet for the DHT22 the supply voltage goes from 3.3V (min) to 6V (max). If you are using a 3.3V Arduino Pro Mini it’s possible that the DHT22 is not getting enough voltage from the I/O pin to operate reliably (not tested). So in this case you can use the 5V Pro Mini. The code for the DHT22 looks something like this:
void setup() { pinMode(7, OUTPUT); // “power pin” you can use any other pin digitalWrite(7, LOW); // switch power off } void loop() { digitalWrite(7, HIGH);// switch power on delay(1000); // delay is needed for the sensor to stabilize // take a sample and the rest of your code digitalWrite(7, LOW);// switch power off }You can try the same for the light sensor. Maybe you can use the same pin to power both sensors (not tested). Do not exceed 20 mA per pin. So try this and see if your problem is still present. I think it's a good idea to do some tests yourself with using a transistor/MOSFET as a switch. I learned a lot by doing these tests by myself.
-
@funky81 Interesting ... that should not happen. Does your node actually communicate with the gateway? The "normal" power consumption I have: a few seconds around 2-3 mA (starting-up) ; 2-10 seconds 27 mA (sending, searching for communication partner); until end of "gw.sleep" 20 uA (withing the limits of my equipment).
@AWI yes, it can communicate with the gateway normally.
Following is my test result- First code
/** */ #include <SPI.h> #include <MySensor.h> #include <avr/sleep.h> //#include <avr/wdt.h> MySensor gw; // watchdog interrupt //ISR (WDT_vect) { wdt_disable(); /* disable watchdog*/ } // end of WDT_vect void setup() { // pinMode(7,OUTPUT); // digitalWrite(7, HIGH); // gw.begin(); Serial.begin(115200); Serial.print("Setup"); } void loop() { // gw.powerUp(); //digitalWrite(7, HIGH); // gw.sendBatteryLevel(0); Serial.print("Loop"); Serial.flush(); // gw.powerDown(); //gw.sleep(30*1000); sleep(); // digitalWrite(7, LOW); // sleep(); } void sleep(){ // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 1 second delay wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); }With this code I've got
- Test_Current_0 : 0.004 mA - Plain, Just Arduino (w/o LED, w/o Voltage Regulator)
- Test_Current_0 : 0,009 mA - Config in point 1 + Voltage Regulator (HT7333)
- Test_Current_0 : 1,58 mA - Config in point 2 + NRF24L01+
Another test
/** */ #include <SPI.h> #include <MySensor.h> #include <avr/sleep.h> //#include <avr/wdt.h> MySensor gw; // watchdog interrupt //ISR (WDT_vect) { wdt_disable(); /* disable watchdog*/ } // end of WDT_vect void setup() { // pinMode(7,OUTPUT); // digitalWrite(7, HIGH); gw.begin(); Serial.begin(115200); Serial.print("Setup"); } void loop() { //gw.powerUp(); //digitalWrite(7, HIGH); gw.sendBatteryLevel(0); Serial.print("Loop"); Serial.flush(); //gw.powerDown(); gw.sleep(30*1000); //sleep(); // digitalWrite(7, LOW); // sleep(); } void sleep(){ // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 1 second delay wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); }Config is the same with no 3 (above), but the power consumption in sleep I take around 2.37 mA.
Is it maybe I've got bad NRF24L01+ ?
----- Updated
It seems my suspicion, it seems the cause of high power consumption is NRF24L01+ radio. I've checked all of my radio, it appears that 2 of 9 seems fake / bad condition.Thanks for contribution of @HarryDutch @AWI @Dheeraj @tbowmo @GuyP and others, so now I can play with other level of MySensor.
Thanks
-
To be honest I have not the foggiest idea why the current drops that much during sleep after a few days. What I do know is that 900 and 120 µA during sleep is way too much. The point is that whatever you connect to your Arduino, you have to switch it off when it’s not needed. At least when you use batteries to power your project. Take for example the DHT22 you use. According to the datasheet it’s using 50 µA in stand-by mode and the current drain of the light sensor (LM393?) is about 800 µA. I assume that you want to take a sample every 5 minutes or so? If that’s the case you can sleep the Arduino between 2 samples and switch off the light sensor and the DHT22 sensor at the same time.
There are a couple of ways to achieve that: using a transistor (http://jeelabs.org/2012/09/07/switching-with-a-pnp-transistor/#comments) using a MOSFET (logic level) (http://jeelabs.org/2012/09/08/switching-with-a-p-mosfet/) or using one of the I/O pins of the Arduino as a “power supply”. The last solution only works for low currents like 1.5 mA (max) for the DHT22. I don’t have the specs for the LM393 but it should be around 3 mA. There’s one important fact about using I/O pins as power pins and that is the voltage drop. When you click the first URL above you see a graph showing the relation between the pin output voltage and the source current. As you can see there is a voltage drop so that the sensor will not get the full supply voltage. Looking at the datasheet for the DHT22 the supply voltage goes from 3.3V (min) to 6V (max). If you are using a 3.3V Arduino Pro Mini it’s possible that the DHT22 is not getting enough voltage from the I/O pin to operate reliably (not tested). So in this case you can use the 5V Pro Mini. The code for the DHT22 looks something like this:
void setup() { pinMode(7, OUTPUT); // “power pin” you can use any other pin digitalWrite(7, LOW); // switch power off } void loop() { digitalWrite(7, HIGH);// switch power on delay(1000); // delay is needed for the sensor to stabilize // take a sample and the rest of your code digitalWrite(7, LOW);// switch power off }You can try the same for the light sensor. Maybe you can use the same pin to power both sensors (not tested). Do not exceed 20 mA per pin. So try this and see if your problem is still present. I think it's a good idea to do some tests yourself with using a transistor/MOSFET as a switch. I learned a lot by doing these tests by myself.
thanks Harry, definitely will try your suggestion of I/O pins as power supply.
-
@AWI yes, it can communicate with the gateway normally.
Following is my test result- First code
/** */ #include <SPI.h> #include <MySensor.h> #include <avr/sleep.h> //#include <avr/wdt.h> MySensor gw; // watchdog interrupt //ISR (WDT_vect) { wdt_disable(); /* disable watchdog*/ } // end of WDT_vect void setup() { // pinMode(7,OUTPUT); // digitalWrite(7, HIGH); // gw.begin(); Serial.begin(115200); Serial.print("Setup"); } void loop() { // gw.powerUp(); //digitalWrite(7, HIGH); // gw.sendBatteryLevel(0); Serial.print("Loop"); Serial.flush(); // gw.powerDown(); //gw.sleep(30*1000); sleep(); // digitalWrite(7, LOW); // sleep(); } void sleep(){ // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 1 second delay wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); }With this code I've got
- Test_Current_0 : 0.004 mA - Plain, Just Arduino (w/o LED, w/o Voltage Regulator)
- Test_Current_0 : 0,009 mA - Config in point 1 + Voltage Regulator (HT7333)
- Test_Current_0 : 1,58 mA - Config in point 2 + NRF24L01+
Another test
/** */ #include <SPI.h> #include <MySensor.h> #include <avr/sleep.h> //#include <avr/wdt.h> MySensor gw; // watchdog interrupt //ISR (WDT_vect) { wdt_disable(); /* disable watchdog*/ } // end of WDT_vect void setup() { // pinMode(7,OUTPUT); // digitalWrite(7, HIGH); gw.begin(); Serial.begin(115200); Serial.print("Setup"); } void loop() { //gw.powerUp(); //digitalWrite(7, HIGH); gw.sendBatteryLevel(0); Serial.print("Loop"); Serial.flush(); //gw.powerDown(); gw.sleep(30*1000); //sleep(); // digitalWrite(7, LOW); // sleep(); } void sleep(){ // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 1 second delay wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); }Config is the same with no 3 (above), but the power consumption in sleep I take around 2.37 mA.
Is it maybe I've got bad NRF24L01+ ?
----- Updated
It seems my suspicion, it seems the cause of high power consumption is NRF24L01+ radio. I've checked all of my radio, it appears that 2 of 9 seems fake / bad condition.Thanks for contribution of @HarryDutch @AWI @Dheeraj @tbowmo @GuyP and others, so now I can play with other level of MySensor.
Thanks
@funky81 What power consumption did you end up with when in sleep mode with your NRFXXXXX connected? I am using the door/window sensor sample, when close it consumes 11.5 uA and when open it consumes 8.5uA (I wish that could be the other way around since the window will be closed most of the time).
-
@funky81 What power consumption did you end up with when in sleep mode with your NRFXXXXX connected? I am using the door/window sensor sample, when close it consumes 11.5 uA and when open it consumes 8.5uA (I wish that could be the other way around since the window will be closed most of the time).
-
@iask I haven't upload my latest door sketch to my node yet. But if I'm using above sketch, idle 4uA and around 18mA while transfer.
Do you have any issues like me before?
@funky81 Well I am not sure what else to try to get lower than 11.5uA. If you are getting 4uA then it's possible. I will have to try your sleep method
void sleep(){ // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 1 second delay wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); }currently I am using
gw.sleep(INTERRUPT,CHANGE, 0); -
@funky81 Well I am not sure what else to try to get lower than 11.5uA. If you are getting 4uA then it's possible. I will have to try your sleep method
void sleep(){ // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 1 second delay wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); }currently I am using
gw.sleep(INTERRUPT,CHANGE, 0); -
I use the @funky81 's sleep method but the nrf doesn't go to sleep so I draw 14ma. When I use the gw.sleep method, I draw +-26ua. Is it possible to go below? (without the nrf, my own pcb with atmega328 go to 5ua in sleep mode with your function (doesn't work with gw.sleep because it's a test without the nrf ;D)
-
I use the @funky81 's sleep method but the nrf doesn't go to sleep so I draw 14ma. When I use the gw.sleep method, I draw +-26ua. Is it possible to go below? (without the nrf, my own pcb with atmega328 go to 5ua in sleep mode with your function (doesn't work with gw.sleep because it's a test without the nrf ;D)
@Tibus do you have other nrf to try? I'm affraid you're using fake nrf.
30% of my nrf (out of 10), are fake...one more thing, sleep method in above post dont turn off nrf radio while sleep.
you can try gw.sleep() if you want turn off nrf radio while sleep (MyGateway gw) -
yes, when I use de gw.sleep it works great but I can't go lower than 26ua+-. My test with your function draw 14ma because the nrf doesn't go to sleep... But is there a method to go lower than 26ua with the nrf? I'm already verry happy of the 26ua but if I can go lower, it would be even better ;D
Do you things it's because I use fake nrf? where can i bought real nrf? The one I use is from electrodragon. -
yes, when I use de gw.sleep it works great but I can't go lower than 26ua+-. My test with your function draw 14ma because the nrf doesn't go to sleep... But is there a method to go lower than 26ua with the nrf? I'm already verry happy of the 26ua but if I can go lower, it would be even better ;D
Do you things it's because I use fake nrf? where can i bought real nrf? The one I use is from electrodragon.