Hello,
Today's question is about power usage. I'm trying to minimize the power usage of a sensor I'm using for a home made alarm system. I'm using interrupts, putting the nrf2401 transceiver I'm using in powerDown state as well as the mega328p chip in power down.
The reed switches I have are some from sparkfun: Reed Switch - COM-08642 - SparkFun Electronics So what I'm doing is having my interrupt fire on state change for digital pin 2 (interrupt 0). However when the magnet is applied (door is closed) which will be the primary state, I'm pulling ~9.4 mA of power. If I remove the magnet power spikes at ~27.3 mA while it transmits then when everything goes back to sleep it is using ~112 uA.
The sleep usage without the magnet is a lot higher than I'd like to begin with. I'd really like to be under 50 uA while sleeping, but don't know if there is really anything I can do about that.
The problem is when the magnet is present (door is closed) 9.4 mA is far far to high. I might could live with 112 uA but at 9.4 mA I'd be going though batteries in a matter of days instead of my goal of a year. I'm pretty sure the reason for this large draw is the pull down resistor I have on the mega pin side of the reed switch. But without this pull down resistor, I get some sort of weird charge holding in the reed switch that causes a 15 to 20 second delay before the pin state changes.
Any suggestions? I'm guessing a normally closed reed switch would solve this but I'm not really sure? Would a Hall Effect sensor be better here?
I don't really have a circuit diagram right now. Really don't even know enough to make one honestly. Lol, I'm one of those people that skips the boring stuff. I'm the same way with programming (I'm a full time software developer), I have never once done a design sheet for a piece of software before I wrote it. Never really had need for things like that, I can usually picture and hold them in my head and not need to waste time with drawing them out.
What software do people use most often to make circuit diagrams? Here is a crude drawing of the diagram I just jotted down really quick.
You could get the opposite type of switch so that it's open when the door is closed? Since that the most common state you want it to use the least amount of power. Use the internal pullup/down rather than an external resistor and put a resister inline to limit current.
Any suggestions? I'm guessing a normally closed reed switch would solve this but I'm not really sure? Would a Hall Effect sensor be better here?
Sure, cheapest lowest current operation for the switch is to wire it to ground, not +5vdc,and remove the 330 ohm resistor, and then enable the internal pull-up resistor for that input pin. That will be around a 40K-50K ohm value. Then in your software invert your logic such that a low signifies the 'active' state.
Any suggestions? I'm guessing a normally closed reed switch would solve this but I'm not really sure? Would a Hall Effect sensor be better here?
Sure, cheapest lowest current operation for the switch is to wire it to ground, not +5vdc,and remove the 330 ohm resistor, and then enable the internal pull-up resistor for that input pin. That will be around a 40K-50K ohm value. Then in your software invert your logic such that a low signifies the 'active' state.
Lefty
Awesome, I did not know about this internal pull up resistor. That is a nifty feature.
Using this method, with the magnet present I'm at 192.5 uA current, and without the magnet 111.2
That is still a bit higher than I was hoping though, and why I wanted to make this project work with the ATTiny84 instead of the mega328p. Removing everything but the mega328p from the circuit still leaves me with 110 uA current open, 190 uA current closed (simulating closed by jumping a ground wire to the interrupt pin). I'm guessing that pull up resistor is accounting for the 80 uA difference there. I'd really like to get it under 100 uA while closed. If I can do that I can get close to my 1 year battery life goal using 1/2 AA 3.6v 1200 mAh batteries. As it is now, I'm looking at more like 2/3rds a year. This is of course ignoring the power usage when it's transmitting, but that will be about the same either way and will depend on how many times the door is opened and closed.
I read this article here: http://jeelabs.org/2009/05/16/power-consumption-more-savings/ talking about getting a mega328 to 6.8 uA current when powered down. It talks about disabling brown out to get there, but I don't really understand how to do that, or if I even can do that?
steven6282:
I read this article here: http://jeelabs.org/2009/05/16/power-consumption-more-savings/ talking about getting a mega328 to 6.8 uA current when powered down. It talks about disabling brown out to get there, but I don't really understand how to do that, or if I even can do that?
Anyone have any more information on how to do this so that I can get the power usage in sleep mode to he absolute bare minimums?
Open circuit state: pullup active, controller will wake up on pin low
Closed circuit state: I will disable the pullup and put the processor to sleep and wake it up periodically. After wakeup I will enable the pullup and see if the circuit is still closed (pin == low). If so stay in state 2.
The point is that this minimizes the closed circuit current consumption.
Also I would like to point out that you can save a lot of current by disabling unnecessary parts of the processor BEFORE going to sleep (e.g. ADC, serial, counters,...). I also found that it helps to lower (or even better: stop) the system clock while sleeping. Also you may want to consider a lower clock because it implies lower operational voltage --> you can drain the batteries lower. If exact timing is not relevant: the RC oscillator consumes less power than the crystall oscillator.
IMHo it is not very hard to get below 10uA average power consumption. Getting below 5uA is harder and staying below 1uA is really tricky.
I don't really think I can disable the pull up and wake up periodically to check it. I'd have to wake it up every second since this is meant to be in response to someone opening a door, I don't want gaps in there where someone can open the door and close it before it checks it. And it really doesn't take that long to open a door and get in it, time it yourself, if you are trying to be quick you could do it in a couple seconds.
As for the datasheet and disabling parts of the processor I don't need. I would love to do that but as I said in jeelabs reference I don't understand how to do that. Sorry when the datasheet starts talking about bit settings and stuff like that it is gibberish to me. I need to know exactly what code would need to be executed to do it, the datasheet doesn't provide that. I've never done anything with that level of direct hardware interaction before.
Looking at the JeeLabs reference it looks like this is what "disables the ADC"
ADCSRA &= ~ bit(ADEN);
PRR &= ~ bit(PRADC);
Where the heck do these values and variables come from? I've tried searching the data sheet and don't see ADCSRA or ADEN anywhere in them. I don't even really understand what the &= operating is doing or the ~ in front of the bit value function is?
Ok, I've now even tried simply using power_all_disable(); and power_all_enable(); with 0 uA change. Does the power.h functions not work on the 328p or something?
sigh this is getting very annoying. It seems like nothing I'm doing is even working...
I found this page: Reducing Arduino Power Consumption - SparkFun Learn
And it seems like the only thing I haven't done from that page is disable the brown out detection, so I set up my bootloader settings like this:
According to the Atmel Studio 6, and that tutorial linked that is supposed to disable brown out detection. This is essentially what they are using for their bare minimum 1 uA in the tutorial.
Yet my current remains exactly the same 192.3 uA with the magnet present.... what the heck is going on here?
First off, I don't know why, but it doesn't appear as if any of the functions in power.h are working for me.
I'm now putting it to sleep like this:
byte mcucr1, mcucr2;
uint8_t prrSave = PRR, adcsraSave = ADCSRA, acsrSave = ACSR;
ADCSRA &= ~ bit(ADEN);
PRR &= ~ bit(PRADC);
ACSR = (1<<ACD); //Disable the analog comparator
radio.powerDown();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(0,stateChange, CHANGE);
// turn off brown-out enable in software
MCUCR = _BV (BODS) | _BV (BODSE); // turn on brown-out enable select
MCUCR = _BV (BODS); // this must be done within 4 clock cycles of above
sleep_cpu();
sleep_disable();
PRR = prrSave;
ADCSRA = adcsraSave;
ACSR = acsrSave;
detachInterrupt(0);
I didn't actually burn the bootloader with the extended fuse set to 0xFF earlier. I must've made the change without restarting the IDE or something. For some reason, if I try to burn the bootloader with the extended fuse set to 0xFF, I get an error verifying saying 0xff != 0x07. No idea why it wont let me set it to 0xff, but I set it to 0x06 for the 1.9v brownout detector instead and that is actually better for my project anyway. I just disable it completely right before sleeping.
After changing to manually disable PRR and ADC like in the code above, and disabling brown out detector in code (MCUCR stuff), I am now down to 86 uA while in a closed state, and a whopping 1 uA while in open state. This will give me 109 days on a coin cell 225 mAh battery, or 581 days on a 1200 mAh 1/2 AA battery. I'm probably going to go with the 1/2 AA batter, it is still small enough for my project, and the amount of power it has behind it is awesome. Of course these numbers are not taking into account spikes while waking up to transmit and such (tops out at around 16.4 mA for about 3 tenths of a second when transmitting).
These are much more pleasing numbers now. However it does leave me wondering, if I did get a normal closed relay switch and didn't need to use the internal pull up resistor, would this thing be around 1 to 6 uA while closed? If that were the case a coin cell battery could theoretically last between 4 and 25 years! (again, ignoring wake up power usage, and at this point also ignoring normal battery discharge rate lol).
I do not fully understand you last question. How do you want to detect that the contact is closed/open? IMHO the best way would be to not use an on/off switch but a switch that can switch between 0 and 5V (or high and low). Then you would need no pullup/pulldown. This would allow to completely get rid of the current drain through the resistor.
I don't really understand what you are saying there? A reed switch is not a simple on / off switch. It's a switch that is open or closed based on the presence of a magnet. Most are normally open, meaning when no magnet is presence it's open and no electricity passes through the switch. There are however some that are normally closed so that the circuit is completed only when a magnet is not present (in my situation with the magnet on a door and the sensor on the door frame, the door will be closed most of the time so the magnet will be present).
I'm not sure what you mean by changing this for a switch that is 0 or 5v. The problem with putting power through the reed switch is it holds a charge and takes 10 to 15 seconds to dissipate, so the pin it's going to would not detect a state change for that 10 to 15 seconds. Thus why I was using a pull down resistor in the first post to bleed off the excess charge. Per retrolefty's suggestion, I changed to using an internal pull up resistor on the atmega328p that puts the pin high if there is no ground present, then wire a ground through the reed switch so that when the magnet is present it grounds out the pin. Essentially the internal resistor is still bleeding off power in this state the same as the resistor was in my original design (thus using up ~80uA of power), but it's a lot less bleed off and it doesn't require an external resistor.
What I'm theorizing is if I had a normally closed reed and wired power to it instead of ground, when the magnet is present the circuit would be open so there would be no bleeding of power and the pin would remain in a low state. Once the door opened, the circuit would complete and the pin would go high. So while the door is open I'd have higher a power consumption rate, but when it's closed (the state it is in the majority of the time) I'd have a much lower power consumption rate. And any type of charging of the reed switch shouldn't be a problem because I'm not really concerned with the door closed event, only when it is opened. If however I did want to detect the door closed and it was holding a charge I could use a pull down resistor again to bleed off the charge quickly once the door was closed and should not increase the power usage any. The disadvantage to the normally closed reed switches is they are much more expensive (3 to 5 dollars), and I only see SMD versions of them. The SMD probably isn't a huge disadvantage just makes it a bit harder to work with when prototyping without a circuit board designed yet. Still, I'm probably going to order one to try it out soon, wish I could get one locally but there are no stores around my area that carry parts like that. Radioshack's electrical components in store are rather limited.
I suggest to use a device like this: http://de.rs-online.com/web/p/reed-schalter/2897806/. Connect the common pin to your input, nc to ground and no to 5V (or vice versa). Then you will not need any pullup / pulldown resistor and the whole thing will consume no additional current except for switching.
That is basically the same thing as what I was talking about. The only difference in that one is you can wire it to be normally open or normally closed by putting power to a different wire. However I'm suspecting that will most likely consume some current on it's own because it probably has a small internal magnetic coil and the wiring is simply reversing the poles to make it normal open or normally closed. It probably would not consume much current, but a standard normally closed switch without the option of switching probably would consume less to none.
I'll keep it in mind though, might pick a couple up just to play and test with. Thanks for the suggestion.