Timer and time.sleep function

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
leob
Posts: 4
Joined: Mon Sep 28, 2020 8:28 pm

Timer and time.sleep function

Post by leob » Wed Mar 10, 2021 8:46 pm

Hi all,
I'm using micropython 1.14 on ESP32 board and I'm new to micropython. I'm using timers to run some tasks on the board and I have a loop where I read values 10 times the value of a sensor and then give back the average of the value. The loop has a time.sleep of 1 second at the end to give 1 second of time for next read.
It seems that in the second of the sleep, the timer will not work anymore and if the timer ends during the sleep, the event is not fired until the sleep ends.
I suppose this is the standard behavior of the sleep function but reading the documentation I did not understand if there is a similar function that introduce a delay without stopping the timers.
Could you please help me?

Thank you!

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Timer and time.sleep function

Post by jimmo » Thu Mar 11, 2021 4:59 am

leob wrote:
Wed Mar 10, 2021 8:46 pm
I suppose this is the standard behavior of the sleep function but reading the documentation I did not understand if there is a similar function that introduce a delay without stopping the timers.
Can you share your code to demonstrate the issue, and I can test and debug it on an ESP32 here.

The timer will generate soft interrupts, which means the scheduler will then dispatch them. My understanding is that on ESP32, the scheduler is run from time.sleep (as long as the sleep is long enough, which 1 second should definitely be).

leob
Posts: 4
Joined: Mon Sep 28, 2020 8:28 pm

Re: Timer and time.sleep function

Post by leob » Thu Mar 11, 2021 7:41 am

Hello Jimmo,
thanks for your reply!
I prepared this piece of testing code.

When you startup the board, you will see the "Salt Alarm ON" and "Salt Alarm OFF" regularly until saltAlarmBuzzer() starts and block everything with its sleep of 0.6 seconds. When checkSalt is called, everything is stopped until the loop ends. When it ends the timer events will be fired as always.
Below the code you can put in main.py file

Thank you again for your help!

Code: Select all

from machine import Timer
import time
from machine import Pin
from machine import ADC

timer0 = Timer(0)
timer0.init(period = 30 * 1000, mode = Timer.ONE_SHOT, callback = lambda t: checkSalt())

timer1 = Timer(1)
timer1.init(period = int(400), mode = Timer.PERIODIC, callback = lambda t: saltAlarmBlink())

timer2 = Timer(2)
timer2.init(period = int(1400), mode = Timer.PERIODIC, callback = lambda t: saltAlarmBuzzer())


def saltAlarmBuzzer():    
    buzzerOutput = Pin(26, Pin.OUT)

    print("Buzzer ON")
    buzzerOutput.value(1)    
    time.sleep(0.6)
    print("Buzzer OFF")
    buzzerOutput.value(0)

def saltAlarmBlink():
    saltAlarm = Pin(33, Pin.OUT)
    if (saltAlarm.value() == 0):
        print("Salt Alarm ON")
        saltAlarm.value(1)
    else:
        print("Salt Alarm OFF")
        saltAlarm.value(0)


def checkSalt():
    saltReader = ADC(Pin(36))
    saltReader.atten(ADC.ATTN_11DB)

    read = []

    i = 0
    while (i < 10):
        val = saltReader.read()            
        read.append(val)
        print("salt value: ", val)
        i += 1
        time.sleep(5)

    timer0 = Timer(0)
    timer0.init(period = 30 * 1000, mode = Timer.ONE_SHOT, callback = lambda t: checkSalt())

warrenfelsh
Posts: 1
Joined: Tue May 17, 2022 6:00 am

Re: Timer and time.sleep function

Post by warrenfelsh » Tue May 17, 2022 6:01 am

Python sleep() will pause for an hour, day or whatever if given the proper value. It does not allow other processes take place (in same script) however. A better way is to use an event which will create an event on timeout.

Have a look at threading.Timer. It runs your function in a new thread without using sleep().

from threading import Timer

def hello():
print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
The second method to delay would be using the implicit wait method:

driver.implicitly_wait(5)

The third method is more useful when you have to wait until a particular action is completed or until an element is found:

self.wait.until(EC.presence_of_element_located((By.ID, 'UserName'))

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Timer and time.sleep function

Post by pythoncoder » Tue May 17, 2022 6:42 am

These solutions are relevant to CPython. In MicroPython support for pre-emptive multitasking is rudimentary. It is also resource-heavy. The best way to achieve concurrency is usually to use uasyncio.
Peter Hinch
Index to my micropython libraries.

Post Reply