View previous topic :: View next topic |
Author |
Message |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
Sleep, Low Power App |
Posted: Tue Sep 27, 2005 9:55 pm |
|
|
Hello All,
Getting further into a handheld remote app. I plan on prolonging battery life by putting it to sleep after a period of inactivity. Any key press will wake it.
Compiler: 3.18
Part: 18F4620
Target Voltage: 3.3V
Osc Speed: 20MHz
I've done some reading and I have learned the general approach to reducing power during sleep. I'll list them here for my own benefit...
Turn off UARTs and SPIs
Set pins to float
Turn off WDT
Disable BOR
(Essentially get rid of everything except for Int on Change.....)
Do I combine the keypress ISR with the wake-up ISR?
If I include the wake-up in the keypress ISR do I just use a flag to indicate to the ISR whether the ISR is being entered from a "sleepy keypress" or an awake keypress?
Can I switch modes to an internal oscillator to further reduce power?
I've started to realize that most anything handled in #fuses can be done in real time in code. What are the biggies that can't... earlier I learned that once a WDT is set in a #fuse it can't be disabled (at least that was the symptom that I was experiencing.)
Which timer would best lend itself to tracking the time between keypresses and determine when to enter a sleep mode? I'm thinking a 5 minute delay with no keypresses will cause a sleep state... (Now that I think of it I'll just use the firmware timer I've already implemented...)
Here's my general plan of attack:
Minimize #fuses
Do all "setups" in a reset function...
Shut everything down prior to sleeping
Another question I thought of... What are the problems associated with returning to operation from sleep... any registers that will bite me, etc.
I'm off to experiment.....
Thanks in advance for everything,
John
EDIT>
Thought of some other questions....
Why not power pull-ups from a PIC pin and float the pin prior to sleep to reduce power?
Code restarts after sleep() instruction upon wake-up....?
I'm using CCP1 for a negative voltage generator on an LCD, does PWM continue during sleep?
Another EDIT>
I just toyed with floating the PWM pin and then restarting it after sleep. It didn't work, contrast came up but gibberish was displayed that faded out after a second or so. Ideas? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 28, 2005 11:53 am |
|
|
I wouldn't set unused pins to floating. I would only set a pin
to float if there was a pull-up or pull-down resistor on that pin. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Mon Oct 31, 2005 2:51 pm |
|
|
OK, putting the finishing touches on this thing and finally got the "sleep" mode to work. (I wasn't setting some flags upon waking, so the LCD wasn't getting init'ed.)
I'm trying to minimize current in sleep mode as described above and will FLOAT pins that have pull-ups. I was wondering... I have pull-ups on SCL, SDA, TX, RX, etc.... What should I do to those pins upon waking? In other words how do I get them back into the configuration (I2C and RS232) they were in prior to putting the PIC to sleep?
Thanks,
John |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Mon Oct 31, 2005 3:07 pm |
|
|
When the PIC goes to sleep the program just stops running. None of the values in RAM are lost. You should be able to restore the IO you changed before going to sleep and be back up and running as it was before going to sleep. You could also re-initialize everything.
Code: |
while(1)
{ Initialize_Hardware();
initialized=1;
while(initialized)
{ normal_loop_Stuff();
if(go_to_Sleep)
{ Ready_To_Sleep();
sleep();
go_to_Sleep=0;
initialized=0;
}
}
}
|
|
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Mon Oct 31, 2005 3:15 pm |
|
|
Thanks Neutone,
So, from what you're saying, if I:
Code: |
output_float(PIN_RC_3);
output_float(PIN_RC_4);
output_float(PIN_RC_6);
output_float(PIN_RC_7);
|
I don't have to do anything when I wake the PIC? The RS232 and the I2C will work as advertised? (I would try it right now, but I'm away from the hardware.)
Thanks,
John
Last edited by jecottrell on Mon Oct 31, 2005 5:16 pm; edited 1 time in total |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Mon Oct 31, 2005 3:24 pm |
|
|
If you assign those pins as Input or Output after waking from sleep, yes you should be fine. For some pins to be assigned to float you have to disable the hardware module that uses the pin. This is shown in detail in the datasheets. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Mon Oct 31, 2005 5:40 pm |
|
|
I did some reading and couldn't find anything that addressed the issues Neutone mentioned in his previous post.
Does the MSSP and the ECCP require to be diasbled prior to sleep? What am I looking for in the data sheet that would tell me that... or would that be in the general 18F part guide?
I guess what I really need here is the $0.02 guide on deciphering this info in the datasheet.
So, in an honest effort to try to figure this out (before I ask for some spoon feeding) here is a slight revision based on what has been discussed so far:
Code: |
//disable ECCP and MSSP if req'd
//not sure how to do that if necessary
output_float(PIN_RC_3); //I2C SCL output
output_float(PIN_RC_4); //I2C Data output
output_float(PIN_RC_6); //RS232 TX output
output_float(PIN_RC_7); //RS232 RX input
//Sleep Here
sleep();
//Wake Here
set_tris_c(0b10000000); //set RC_7 as input, all others as output |
Is there any good place to read about what I'm attempting?
Thanks again for all the help,
John
EDIT:
I guess one really ugly way to do this is to reset on wake-up. I think that would work in my case. But, I'd like to learn the elegant/correct way to do this. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 31, 2005 5:58 pm |
|
|
Quote: |
output_float(PIN_RC_3); //I2C SCL output
output_float(PIN_RC_4); //I2C Data output
output_float(PIN_RC_6); //RS232 TX output
output_float(PIN_RC_7); //RS232 RX input
//Sleep Here
sleep();
//Wake Here
set_tris_c(0b10000000); //set RC_7 as input, all others as output
|
I don't see the need for any of the TRIS changes that you're doing
above.
1. The i2c is already going to be configured as inputs, because that is
the i2c idle state.
2. The RS-232 Rx is already set as an input, because it has to be,
in order to receive data.
3. The idle state for the RS232 Tx pin is a high level. The MAX232
transmit buffer has got an internal 400K pullup to Vdd on it's
microcontroller side. There is not likely to be much, if any,
voltage differential between those two. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Mon Oct 31, 2005 7:57 pm |
|
|
OK, I'm going to take a few more swings at this horse... I don't think it's quite dead yet.
I used reset_cpu() after sleep() and it seems to work well, and is suitable for my application. So much for elegance.
So my only questions remaining concern prepping the CPU for sleep.
The following questions are asked concerning limiting current leakage from the CPU during sleep to maximize battery life.
The MSSP and EUSART have 10K pullups. Is it worth while to float those pins? To float those pins do I have to disable the MSSP and EUSART? The datasheet says that when the hardware is disabled the pin then becomes I/O (I assume then, and only then, can it be floated?)
BTW, I2c is connected to EEPROM and EUSART is connected directly to MaxStream XBee radio.
Thanks again,
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 31, 2005 8:19 pm |
|
|
Get an inexpensive meter like this, that can measure DC current
down to 0.1 uA, and put it in series with the positive battery wire.
http://www.bkprecision.com/www/np_specs.asp?m=2706A
Then if you have some doubt about how sleep mode current is
affected by your power-down configuration, you can test it. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Mon Oct 31, 2005 8:44 pm |
|
|
I like that approach much better. Seeing is believing.
I replaced my Fluke110 with a 111 to be able to measure current... I wish I had known that that resolution was available at that price..... And I just sent a Digikey order in this morning.... Arrrggghhh.
Thanks for the info,
John |
|
|
MGP
Joined: 11 Sep 2003 Posts: 57
|
|
Posted: Tue Nov 01, 2005 4:13 pm |
|
|
Extech also makes some excellent DMM's for the money.
I purchased one of these (MM570) specifically to measure very low currents in MSP430 based designs I was doing at the time:
http://www.extech-direct.com/Multi-Meters/EXT-MM560and570.htm
If you look at the specs, they compare favorably to Fluke meters that are 2-3 times the price. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Nov 01, 2005 5:16 pm |
|
|
Thanks for the info. I ordered a BK Precision from Digikey this morning.
I think it will due for what I'm attempting, and it was only $99.
Thanks for the info. |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Wed Nov 02, 2005 9:31 am |
|
|
I suggest writing a program that does nothing but put the processor to sleep and measure the current. You can use that as your bench mark to know when you have everything powered down correctly in your application. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Nov 02, 2005 11:33 am |
|
|
I got the code working to take care of disabling the MSSP and the EUART. It took some reading to figure out the struct, etc. But I got it, no problem.
Quote: | I suggest writing a program that does nothing but put the processor to sleep and measure the current. |
I'll do that. I can just comment out the housekeeping code prior to the sleep to give me an idea of a starting point.
I did a pin by pin accounting and tried to decide what state to put each pin in prior to sleep. I'll validate those GUESSES when the uAmmeter arrives tomorrow.
My biggest problem, I think, will be with the keypad implementation that I used. (The keypad is the only thing that will wake the PIC.) I used the circuit in the MeLabs X-1 board:
http://www.melabs.com/downloads/labx1sch.pdf
Mine is identical except for the pull down resistor R17 which is not present.
My problem is this, that keypad relies on the port_b_pullups and they are inherently going to waste alot of power during sleep.
So, I think my options are:
1. Expect the client to buy lots of batteries. (If so, you may want to buy stock in DuraCell, it could go up if I use this approach.)
2. Put an extremely high pull-up (1M+ ?) on the columns to wake the PIC from sleep without using the internal pull-ups during sleep. This would also solve a problem I noticed when I disable the pull-ups prior to sleep. When I disable the port_b_pullups prior to sleep, the PIC wakes as the pull-ups drain....essentially creating a PIC with sleep apnia. (And not to mention the keypad can't wake the PIC.)
3. Re-implement the keypad with a different, more sleep friendly, circuit.
4. Try something different that I haven't thought of....
Any ideas would be greatly appreciated.
John |
|
|
|