PDA

View Full Version : Timer and long (hours) sleep period - how to?



flotulopex
- 2nd January 2007, 15:09
Hello,

I need to record temperature & humidity over days with a sample frequency of 15 minutes.

Since the PIC will be battery powered, I think about putting it to SLEEP until the next sample record happens.

According to my PIC's data sheet (16F88 - 4MHz), the TMR0 won't be able to wakeup during SLEEP mode.

What is the best way to time the PIC for long sleep periods?

mister_e
- 2nd January 2007, 19:57
Have a look at the SLEEP section of your datasheet, look what could Wake-Up your PIC. WatchDog timeout is one of those... if my memory serves me well.

skimask
- 2nd January 2007, 20:43
Hello,

I need to record temperature & humidity over days with a sample frequency of 15 minutes.

Since the PIC will be battery powered, I think about putting it to SLEEP until the next sample record happens.

According to my PIC's data sheet (16F88 - 4MHz), the TMR0 won't be able to wakeup during SLEEP mode.

What is the best way to time the PIC for long sleep periods?

Watchdog Timer at max time out is about 268 seconds, set up a counter, 3 time outs will get you 13.4 minutes (give or take). The watchdog timer isn't all that accurate. You can however use TMR1 with a low power crystal on it and prescale that a bunch, but again, you'll end up waking every so often and using that same counter to get your 15 minutes.

You could use a 4 wind up clocks and some lever switches to reset your PIC every 15 minutes :)

flotulopex
- 3rd January 2007, 08:27
I'll try this one.

But what is the Watchdog exactly ment for? I thought it is some kind of internal controlling timer.

Why wouldn't I use a "timer" to do this job? There are 3 available timers in 16F88...

skimask
- 3rd January 2007, 16:55
I'll try this one.

But what is the Watchdog exactly ment for? I thought it is some kind of internal controlling timer.

Why wouldn't I use a "timer" to do this job? There are 3 available timers in 16F88...

A watchdog timer is used when the program running 'goes nuts'. When it's running, you have to periodically reset the WDT. If you don't reset it, the WDT will execute a processor reset.

There is 3 timers available, but they all use power to run them. The WDT uses a lot less power, even though it's not quite as accurate.

Check your PBP and/or PIC manual for the CLRWDT instruction. It should become clear as mud to ya. :)

flotulopex
- 3rd January 2007, 21:01
Well, after some readings today, I thought I would have won this challenge easely on my own, but... still searching my way in the myst after hours.

Here is my simple test code:

' Fuses
@ DEVICE PIC16F88,INTRC_OSC_NOCLKOUT,PROTECT_OFF,WDT_ON,PWR T_ON,MCLR_ON
@ DEVICE PIC16F88,BOD_ON,LVP_OFF,CPD_OFF,DEBUG_OFF,CCPMX_OF F

'-------------------------------------------------------------------------------
' Register settings
OSCCON = %01100000 'Internal RC set to 4MHZ
OPTION_REG = %00001111 'enable PORTB pullups, prescaler to WDT, rate 1:128
WDTCON = %00010111 'Prescaler 1:65536, WDT ON

'-------------------------------------------------------------------------------
' Init
LED1 var PORTB.0

'-------------------------------------------------------------------------------
' Program
MAIN:
if STATUS.4 = 0 then 'a WDT Time-Out occured
CLEARWDT 'clear Watchdog Timer
toggle LED1
endif
goto main

end

On the top of this, pre- & postscalers are not clear to me, even after reading the datasheet 3 times (must be my poor english... and my math too).

A.- The prescaler rate is set in the OPTION_REG bits 2-0. Am I right to say that this prescaler becomes the postscaler when affected to WDT (OPTION_REG.3=1)?

B.- At 4MHz, 1 Tosc is about 1µs. Shall I understand that, if my program would work, my LED should toggle every 128x65536=8'388'608µs=8,388...seconds? I feel this is wrong, but I don't know why.

C.- Should I handle the WDT as an interrupt and make a routine for this (reading the datasheet it looks not to be the case, but...)?

D.- In several block diagrams, I noticed that the WDT uses the 31,25kHz osc freq. Does this mean I have to set my oscillator to 31,25kHz (I tried this - doesn't make it better working)?

My brain needs a break; going for some dishwashing... ;-)

flotulopex
- 4th January 2007, 17:11
I really need some help on this one. Does anybody have a code sample using Watchdog timer?

I read the "Watchdog Timer Operation" datasheet, but it is still not very clear to me.

Here is my piece of code (that works) when I don't use the WDTCON postscaler:
' Fuses
@ DEVICE PIC16F88,INTRC_OSC_NOCLKOUT,PROTECT_OFF,WDT_ON,PWR T_ON,MCLR_ON
@ DEVICE PIC16F88,BOD_ON,LVP_OFF,CPD_OFF,DEBUG_OFF,CCPMX_OF F

'-------------------------------------------------------------------------------
' Register settings
OSCCON = %01100000 'Internal RC set to 4MHZ
ANSEL = %00000000 'Disable Analogue Inputs
OPTION_REG = %00000111 'enable PORTB pullups, prescaler to WDT, rate 1:128
'WDTCON = %00000001 'Prescaler 1:32, WDT ON

'-------------------------------------------------------------------------------
' Init
LED1 var PORTB.0

'-------------------------------------------------------------------------------
' Program
MAIN:
toggle LED1
NAP 7
goto main

end
If I use SLEEP instead of NAP, I can set up the sleeping time up to more than 18 hours.

It looks as the pre- or postscaler don't affect the sleep period... (?)

I'm completely lost....

skimask
- 4th January 2007, 17:48
Well, after some readings today, I thought I would have won this challenge easely on my own, but... still searching my way in the myst after hours.

Here is my simple test code:

' Fuses
@ DEVICE PIC16F88,INTRC_OSC_NOCLKOUT,PROTECT_OFF,WDT_ON,PWR T_ON,MCLR_ON
@ DEVICE PIC16F88,BOD_ON,LVP_OFF,CPD_OFF,DEBUG_OFF,CCPMX_OF F

'-------------------------------------------------------------------------------
' Register settings
OSCCON = %01100000 'Internal RC set to 4MHZ
OPTION_REG = %00001111 'enable PORTB pullups, prescaler to WDT, rate 1:128
WDTCON = %00010111 'Prescaler 1:65536, WDT ON

'-------------------------------------------------------------------------------
' Init
LED1 var PORTB.0

'-------------------------------------------------------------------------------
' Program
MAIN:
if STATUS.4 = 0 then 'a WDT Time-Out occured
CLEARWDT 'clear Watchdog Timer
toggle LED1
endif
goto main

end

On the top of this, pre- & postscalers are not clear to me, even after reading the datasheet 3 times (must be my poor english... and my math too).

A.- The prescaler rate is set in the OPTION_REG bits 2-0. Am I right to say that this prescaler becomes the postscaler when affected to WDT (OPTION_REG.3=1)?

B.- At 4MHz, 1 Tosc is about 1µs. Shall I understand that, if my program would work, my LED should toggle every 128x65536=8'388'608µs=8,388...seconds? I feel this is wrong, but I don't know why.

C.- Should I handle the WDT as an interrupt and make a routine for this (reading the datasheet it looks not to be the case, but...)?

D.- In several block diagrams, I noticed that the WDT uses the 31,25kHz osc freq. Does this mean I have to set my oscillator to 31,25kHz (I tried this - doesn't make it better working)?

My brain needs a break; going for some dishwashing... ;-)

A) Yes, that particular divider unit is a prescaler for TMR0 and a postscaler for WDT, assignable to either TMR0 or WDT, not both (actually, it can be, but that's beside the point for now).

B) WDT is driven by internal (nominal) 31.25Khz clock source. 1/31250 = 32us... 32us * 128 * 65536 = 268.435456 seconds, 4minutes+28.36992seconds.

C) A WDT timeout does one of two things: Either it wakes a PIC up from SLEEP (section 15.13.1) in which case it will start execution at the instruction following the SLEEP, or it'll do a PIC RESET (Table 15-2, 15-3 and 15-4).

D) WDT clock is an independant clock source (section 15.12.1

skimask
- 4th January 2007, 18:09
I really need some help on this one. Does anybody have a code sample using Watchdog timer?

I read the "Watchdog Timer Operation" datasheet, but it is still not very clear to me.

Here is my piece of code (that works) when I don't use the WDTCON postscaler:
' Fuses
@ DEVICE PIC16F88,INTRC_OSC_NOCLKOUT,PROTECT_OFF,WDT_ON,PWR T_ON,MCLR_ON
@ DEVICE PIC16F88,BOD_ON,LVP_OFF,CPD_OFF,DEBUG_OFF,CCPMX_OF F

'-------------------------------------------------------------------------------
' Register settings
OSCCON = %01100000 'Internal RC set to 4MHZ
ANSEL = %00000000 'Disable Analogue Inputs
OPTION_REG = %00000111 'enable PORTB pullups, prescaler to WDT, rate 1:128
'WDTCON = %00000001 'Prescaler 1:32, WDT ON

'-------------------------------------------------------------------------------
' Init
LED1 var PORTB.0

'-------------------------------------------------------------------------------
' Program
MAIN:
toggle LED1
NAP 7
goto main

end
If I use SLEEP instead of NAP, I can set up the sleeping time up to more than 18 hours.

It looks as the pre- or postscaler don't affect the sleep period... (?)

I'm completely lost....



Then keep it simple and use sleep and nap. They're already there for you to use and they power down the PIC to save battery power. They're totally WDT driven and don't rely on the PIC system clock (i.e. 4mhz, 20mhz, whatever). So you can set your register options for the slowest possible clock speed, wait for the sleep/nap to finish, do some checks or whatever, then when the time is right, crank up the clock speed and go.

flotulopex
- 4th January 2007, 18:23
Thank you Skimask,

I have now put a "SLEEP 10" command in my main loop to make some tests.

When I change the prescaler values in OPTION_REG, nothing changes; the SLEEP time stays around 10 seconds.

When I now activate the WDTCON register (with OPTION_REG) and put the prescaler to 1:32, my LED blinks almost every half second. Setting the rate at 1:64 doubles the 'pause' delay.

A.- Why is the prescaler in OPTION_REG not affecting the SLEEP time?

B.- According to all datasheets, it is not reliable to use WDT since the time may vary in an important scale. What is then the best way to make long delays with the PIC?

skimask
- 4th January 2007, 18:35
Thank you Skimask,

I have now put a "SLEEP 10" command in my main loop to make some tests.

When I change the prescaler values in OPTION_REG, nothing changes; the SLEEP time stays around 10 seconds.

When I now activate the WDTCON register (with OPTION_REG) and put the prescaler to 1:32, my LED blinks almost every half second. Setting the rate at 1:64 doubles the 'pause' delay.

A.- Why is the prescaler in OPTION_REG not affecting the SLEEP time?

B.- According to all datasheets, it is not reliable to use WDT since the time may vary in an important scale. What is then the best way to make long delays with the PIC?

a) not sure, my best guess is that PBP handles it for you behind the scenes. Check your .lst file to see what's really happening.

b) WDT has about +/- 15% tolerance on the clock. If you want 15 minutes, you'll get between 12m45s to 17m15s, generally you'll usually be a lot closer than that. See Section 15.13.1, use Timer1 with an external crystal (2 crystals total, one for PIC, one for Timer1), but that option uses a bit more power.

flotulopex
- 4th January 2007, 20:17
Thanks a lot Skimask for your support.

I'm going to try with TMR1.

A little more power is maybe worth the precision gain.

Thank you.

skimask
- 4th January 2007, 20:41
Thanks a lot Skimask for your support.

I'm going to try with TMR1.

A little more power is maybe worth the precision gain.

Thank you.

You could add in a RTC chip, and wake up just a bit more often and compare the RTC's time with what you expected and adjust your nap/sleep time to get you really close to 15 minutes, or even use the RTC's alarm function (usually tied to a pin) to wake up the PIC at intervals. RTC chips use hardly any power except when awake and I'd suspect that adding an RTC would use much less power than adding another oscillator to a PIC.

peterdeco1
- 5th January 2007, 17:43
Hi Flotul. I've used a code similar to this in the past and found it to be accurate within 2 minutes per hour using the internal oscillator set to 4 MHZ. Also, I operated it at 3V (using an LF series PIC), current consumption was only 1/2 mA and runs a long time on 2AA alkaline batteries.


x var word
let x = 0

start:
pause 1000
let x = x + 1
if x >= 900 then (15 minutes passed, do your measurement)
goto start

flotulopex
- 8th January 2007, 07:32
Thank you for your suggestions.

Two minutes may look acceptable in some cases but if you have to record datas over days and weeks, it's is no more accurate enough.

I'll have to make some tries but, as said by skimask, an RTC is maybe the best choice after all.

Thanks again.