RTC Alarm with repeat=True

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
Post Reply
ahx
Posts: 2
Joined: Fri Oct 30, 2015 9:35 pm

RTC Alarm with repeat=True

Post by ahx » Fri Oct 30, 2015 10:26 pm

RTC Alarm with repeat=True

I´m trying to build something like a data logger that executes some lines of code, then goes into sleep/deepsleep mode and wakes up after a defined time period to start again.

My code below is based on the machine.RTC.alarm sample with repeat set to True. As expected the WiPy goes into sleep mode for the first 10 seconds, than wakes up (the heartbeat led flashes a few times very quickly) and stops the script execution without any error message. The code within alarm_handler is not executed. Even with pass as single command within alarm_handler no periodic alarm happens.

Code: Select all

import machine
from machine import RTC

rtc = machine.RTC()   # init with default time and date

def alarm_handler (rtc_o):
	# do something...
	f = open('/flash/test.txt', 'a')
	f.write('.')
	f.close()

# create a RTC alarm that expires after 10 seconds
rtc.alarm(time=10000, repeat=True)

# enable RTC interrupts
rtc_i = rtc.irq(trigger=RTC.ALARM0, handler=alarm_handler, wake=machine.SLEEP)

# go into suspended mode
machine.sleep()
Any suggestions or other approaches for my problem?

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: RTC Alarm with repeat=True

Post by danicampora » Sat Oct 31, 2015 9:33 am

Hi,

There are two problems.

1. You can't do file operations on an interrupt handler. I really need to add an IRQ section to the docs explaining this. Interrupts are meant to do fast, non-blocking operations, this is the case with any MCU, no matter if you code in C, assembly or MicroPython. Besides that, MicroPython doesn't allow to allocate memory on an IRQ handler (yet).

2. The alarm is configured to wake up the MCU in machine.SLEEP mode only, and the you just put the MCU into sleep once, so even with an empty handler, it will only execute once. Solutions, change the IRQ line to:

Code: Select all

rtc_i = rtc.irq(trigger=RTC.ALARM0, handler=alarm_handler, wake=machine.SLEEP | machine.IDLE)
Therefore it's also triggered when the machine is IDLE. Or:

Code: Select all

rtc_i = rtc.irq(trigger=RTC.ALARM0, handler=alarm_handler, wake=machine.SLEEP)

while True:
    machine.sleep()
And finally, the best approach is to use your handler to set a flag, that you check within your main code:

Code: Select all

def alarm_handler (rtc_o):
    global rtc_wake
    rtc_wake = True
    
# then in your main loop
while True:
    machine.sleep()
    if rtc_wake:
        rtc_wake = False
        # do wathever you want
Another point, printing messages over the Telnet REPL inside an IRQ handler doesn't work, it won't crash, but the message simply won't be printed, this is due to the same reasons explained above. I reckon that the docs are lacking in this area, will address it soon.

Cheers,
Daniel

ahx
Posts: 2
Joined: Fri Oct 30, 2015 9:35 pm

Re: RTC Alarm with repeat=True

Post by ahx » Sat Oct 31, 2015 11:14 pm

Now everything makes sense.
Thanks!

Post Reply