View previous topic :: View next topic |
Author |
Message |
sentinel
Joined: 02 Feb 2009 Posts: 141 Location: Tasmania
|
Posted: Fri Feb 25, 2022 4:39 am Post subject: Mysterious pulse train during Powerdown |
|
|
I have a mega168A running the following code which seems to behave well until about 11 seconds after the mains power is cut, whereupon a 12.95 Hz stream of pulses appears at the supercap (& Vcc) terminals indicating a 6.3 mS current draw every 77 mS or so. This drains backup power much too quickly.
The watchdog operates properly if I comment out the "Reset Watchdog" line and the green LED lights when power is restored, so the watchdog and the PCINT13 interrupt appear to also work.
The frequency of this pulse train seems to be independent of whatever code is in the main loop and is rock steady. I can't see how it is related to the RTC crystal frequency either. Curious how every second pulse seems to have a longer trailing edge spike.
Is the micro-controller being woken up 13 times a second? If so, why?
Edit: Removing all references to the watchdog stops this puzzling behaviour, so I am presumably using the watchdog incorrectly. Can anyone please suggest where I am going wrong?
Code: |
$regfile = "m168def.dat" 'Using ATmega168A
'Oscillator Is 8 Mhz divided By 8 Internally.
$crystal = 1000000 'Also, RTC has external 32,768 Hz crystal on OSC pins
$baud = 9600
$hwstack = 40
$swstack = 40
$framesize = 40
Dim Date_saved as Eram String * 8
Dim Time_saved as Eram String * 8
Dim Message_counter As Byte
Dim Timerflag As Bit
Dim Shutdown_flag as bit
Shutdown_flag = 0
Config Serialin = Buffered , Size = 40 , Bytematch = 10
Config Clock = Soft , Gosub = Sectic
Config Date = Dmy , Separator = /
Ddrb = &B000100 'Configure inputs and outputs
Ddrc = &B0011110 'Configure inputs and outputs
Ddrd = &B00001100 'Configure inputs and outputs
Portb = &B111011 'Set pullup resistors
Portc = &B1000001 'Set pullup resistors
PortD = &B11110011 'Set pullup resistors
Date$ = Date_saved 'Recover the saved date & time
Time$ = Time_saved
Pcmsk1 = &B0010_0000 'Set mask to only enable PCINT 13
On Pcint1 Checkint 'When interrupt occurs, go to the subroutine
Enable Pcint1
Blue_led Alias Portc.1
Green_led Alias Portc.2
Red_led Alias Portc.3
Power_on Alias Pinc.5
Blue_led = 1
Green_led = 1
Red_led = 1
Const On = 1
Const Off = 0
Const Light = 0
Const Dark = 1
Didr0 = Bits(ain1d , Ain0d) 'Disable digital input buffer on the AIN1/0 pin
Stop Ac
Reset Acsr.acbg 'Disable Analog Comparator Bandgap Select
Set Acsr.acd 'Switch off the power to the Analog Comparator
Set Didr1 '.ain1d
Set Didr1.ain0d
Config Adc = Single , Prescaler = Auto , Reference = INTERNAL_1.1
Config Watchdog = 8192 'Set the watchdog to time out at 8 seconds
Start Watchdog
On Wdt Wdt_isr Nosave
Enable Wdt
Enable Interrupts
'===========================================================================
'Main program
'===========================================================================
Do
If Shutdown_flag = 1 then Powerdown
If Power_on = 1 then
If Timerflag = 1 Then 'Executed once per second
Timerflag = 0
End If ' End of one second tick
Reset Watchdog
End if
Loop
'===========================================================================
'Timer interrupt subroutine
'===========================================================================
Sectic:
Timerflag = 1
Return
'=========================================
' Serial input interrupt routine
' ========================================
Serial0charmatch:
Incr Message_counter
Return
Wdt_isr:
Date_saved = Date$ : Time_saved = Time$
Return
Checkint: 'PCINT13 isr
If Power_on = 0 Then
Blue_led = Dark
Red_led = Dark
Green_led = Dark
Ucsr0b.txen0 = 0 'Disable USART0 transmit
Ucsr0b.rxen0 = 0 'Disable USART0 receive
Stop Adc
Stop Watchdog
Date_saved = Date$ : Time_saved = Time$
Shutdown_flag = 1
Else
Ucsr0b.txen0 = 1
Ucsr0b.rxen0 = 1
Start Adc
Start Watchdog
Date$ = Date_saved: Time$ = Time_saved
Green_led = Light
Shutdown_flag = 0
End If
Return
End |
(BASCOM-AVR version : 2.0.8.2 , Latest : 2.0.8.5 ) |
|
Back to top |
|
|
sentinel
Joined: 02 Feb 2009 Posts: 141 Location: Tasmania
|
Posted: Fri Feb 25, 2022 5:48 am Post subject: |
|
|
OK, after further tests, I've found that what is needed is a "Disable watchdog"/"Enable watchdog" as well as/instead of the "Stop watchdog"/"Start watchdog". This stops the pulse train and allows the backup voltage to stay higher for longer.
HOWEVER, when I apply this to the full program code, the problem returns. What's going on?
I'm curious about the timing of that pulse train, though, and why there's an 11 second delay before it kicks in. |
|
Back to top |
|
|
SZTRAD
Joined: 30 Dec 2019 Posts: 165
|
Posted: Fri Feb 25, 2022 7:11 am Post subject: |
|
|
Maybe because it doesn't have the 8192 option?
And I'd study the program further.
0 0 0 0 2K (2048) cycles 16ms
0 0 0 1 4K (4096) cycles 32ms
0 0 1 0 8K (8192) cycles 64ms
0 0 1 1 16K (16384) cycles 0.125s
0 1 0 0 32K (32768) cycles 0.25s
0 1 0 1 64K (65536) cycles 0.5s
0 1 1 0 128K (131072) cycles 1.0s
0 1 1 1 256K (262144) cycles 2.0s
1 0 0 0 512K (524288) cycles 4.0s
1 0 0 1 1024K (1048576) cycles 8.0s
Oh, no.Mark's writing in the correct option
Sorry, |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Fri Feb 25, 2022 11:35 am Post subject: |
|
|
You should check/refer to the datasheet about registers you set.
I check only two and find some misstatement.
Code: | Didr0 = Bits(ain1d , Ain0d) 'Disable digital input buffer on the AIN1/0 pin
Stop Ac
Reset Acsr.acbg 'Disable Analog Comparator Bandgap Select
Set Acsr.acd 'Switch off the power to the Analog Comparator
Set Didr1 '.ain1d
Set Didr1.ain0d |
AIN1D and AIN0D have DIDR1 register not DIDR0. In DIDR0 you have ADC0D - ADC5D
Because in Bascom DAT files AIN1D and AIN0D have aliases for 1 and 0 so those two bits are set only but without any warrning. So if you want to disable ADC inputs then ADC2D - ADC5D are not set correctly.
If you use Set for whole register "Set Didr1" then only bit 0 will be set so next command "Set Didr1.ain0d" means exactly the same.
I dont know what inputs you want to disable and what to save.
For DIDR0 and DIDR1 proper use of Bits should be like this:
Code: | DIDR0 = Bits(ADC5D,ADC4D,ADC3D,ADC2D,ADC1D,ADC5D)
DIDR1 = Bits(AIN1D,AIN0D)
| (or their equivalent in numbers)
This are only two registers I check because my curiosity but maybe there is more.
Better check that datasheet and save some time.
I also recommend setting some bits on register AFTER Bascom configs like Config ADC etc. |
|
Back to top |
|
|
sentinel
Joined: 02 Feb 2009 Posts: 141 Location: Tasmania
|
Posted: Fri Feb 25, 2022 11:41 am Post subject: |
|
|
I tested Config Watchdog = 8192 in a minimum program on the same chip and it times out after about 8 seconds. |
|
Back to top |
|
|
sentinel
Joined: 02 Feb 2009 Posts: 141 Location: Tasmania
|
Posted: Fri Feb 25, 2022 2:10 pm Post subject: |
|
|
Thanks EDC, I agree that those registers need to be checked and matched to this chip. My intention is to disable the analogue comparator and the analogue input buffer. |
|
Back to top |
|
|
sentinel
Joined: 02 Feb 2009 Posts: 141 Location: Tasmania
|
Posted: Sat Feb 26, 2022 9:17 am Post subject: |
|
|
Even after removing the watchdog and all reference to shutting down the analogue comparator and other power-saving measures during powerdown, the 13 Hz pulse train continues while the device is shut down. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat Feb 26, 2022 10:51 am Post subject: |
|
|
sentinel wrote: | OK, after further tests, I've found that what is needed is a "Disable watchdog"/"Enable watchdog" as well as/instead of the "Stop watchdog"/"Start watchdog". |
Riddling your way to success?
Quote: | whereupon a 12.95 Hz stream of pulses |
Your scope shows 6.508Hz
Quote: | Curious how every second pulse seems to have a longer trailing edge spike. |
Scope sampling issues.
Your main loop reformatted:
Code: | Do
If Shutdown_flag = 1 then Powerdown
If Power_on = 1 then
If Timerflag = 1 Then
Timerflag = 0
End If
Reset Watchdog
End if
Loop |
It shows if Power_on = 0, there is no reset of the Watchdog.
I have to assume, what Power_on means, as you did not comment it.
If Power_on = 1 means mains power is on, then in battery-mode it will be 0.
Accordingly the Watchdog-interrupt will trigger after it expires, waking up the controller, executing Wdt_isr and then the main loop.
Code: | On Wdt Wdt_isr Nosave |
'Nosave' should be used only if you know what you do. Do you know?
If you do not do a clean reset (WDTON = set = 0) after executing the Watchdog-ISR, the therein destroyed registers may result in random behavior of the main loop.
The only way it could not do damage is, if the main would look exactly like that:
How's the WDTON-fuse set? |
|
Back to top |
|
|
sentinel
Joined: 02 Feb 2009 Posts: 141 Location: Tasmania
|
Posted: Sat Feb 26, 2022 1:59 pm Post subject: |
|
|
Quote: | Riddling your way to success? |
You've rumbled me.
Quote: | Your scope shows 6.508Hz |
Yes, that's because the trigger level was lower than the shorter negative spikes but was only being triggered by the longer ones, giving a value of half the actual frequency. Expanding the timebase shows that the spike length is not an artefact of the sampling rate, but really does alternate in length.
Quote: | It shows if Power_on = 0, there is no reset of the Watchdog. |
Surely if the watchdog is off in Powerdown (entered when Power_on = 0), it doesn't need to be reset?
Quote: | 'Nosave' should be used only if you know what you do. Do you know? |
It would appear not. I had assumed that when the Wdt_isr is called, there would be a clean reset. 'Nosave' is gone.
The watchdog fuse is not set at flashing time, but is only turned on in firmware. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat Feb 26, 2022 5:21 pm Post subject: |
|
|
sentinel wrote: | You've rumbled me. |
You're welcome
Quote: | Expanding the timebase shows that the spike length is not an artefact of the sampling rate, but really does alternate in length. |
Fast spikes exceeding the scope's bandwidth may be recorded differently. Can you expand a spike until it's more than a vertical line?
Quote: | Surely if the watchdog is off in Powerdown (entered when Power_on = 0), it doesn't need to be reset? |
Ok. I missed the mechanism with pinchange. Which I would not trust btw.
There is always a delay between a pinchange-trigger event and reading the pin in question.
Additionally the hysteresis of the IO-pin diminishes as temperature rises, see 'Pin Thresholds and Hysteresis' in the data sheet.
At 25 °C there's roughly 100mV hysteresis, at 85 °C nearly none. With a little ripple on the Power_on-pin you get multiple executions of the Checkint ISR.
What you would need is a Schmitt trigger.
Apart from theory this is easy to test for you, toggle a pin within Wdt_isr and compare with start of the pulse train.
If you want to keep the pinchange mechanism, I suggest to lock/disable the pinchange ISR after it was triggered and add a small delay before the Power_on pin is checked.
Unlock it within main loop, be sure to delete any pending pinchange interrupts before enabling them by
Before starting the watchdog again, I would do a watchdog reset first.
Quote: | I had assumed that when the Wdt_isr is called, there would be a clean reset. |
My mistake, I read the WDT is in 'Interrupt mode', instead it runs in 'Interrupt and System Reset mode', first WD-timout executes the WD-ISR, then switches to 'System Reset mode', second timeout results in a WD-reset.
Quote: | The watchdog fuse is not set at flashing time, but is only turned on in firmware. |
How do you do this? WDTON is a fuse and this controller can not access its fuses from code.
And the WD is always in "System Rest mode", if this fuse is set. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|