loboris / MicroPython_ESP32_psRAM_LoBo

MicroPython for ESP32 with psRAM support
Other
831 stars 344 forks source link

Notification disables time.sleep longer than 100 ms after breaking from a first time.sleep() #297

Open WilliamHarvey97 opened 5 years ago

WilliamHarvey97 commented 5 years ago

Here's a test code I made:

import _thread
import utime

def test():
    while True:
        start_time = utime.time()
        utime.sleep(2)
        print('Delta Time: ', str(utime.time() - start_time))

th_id = _thread.start_new_thread('test', test, ())

utime.sleep(1)
_thread.notify(th_id, 0x01)

Output:

Delta Time:  1.000637
Delta Time:  0.100451
Delta Time:  0.100862000000001
Delta Time:  0.100442000000001
Delta Time:  0.0998160000000006
Delta Time:  0.100755999999999
Delta Time:  0.100586
Delta Time:  0.0998420000000024

...

I understand why it is breaking the first time.sleep after 1 second. But why subsequent utime.sleep() always breaks after ~100ms when there is a pending notification? It will continue like that until the notification will be get in the child thread. Was this behavior intended to shorten the notification handling delay? I tested the following code from the thread template in the wiki and I got the same behavior:

From the wiki's thread template:

        # ---------------------------------------------------------------
        # - Using sleep in thread function                              -
        # ---------------------------------------------------------------
        # 'utime.sleep(sec, True)' & 'utime.sleep_ms(ms, True)' functions returns the
        # actual ellapsed sleep time. The sleep will be interrupted if
        # a notification is received and the returned value will be less
        # than the requested one
        # ---------------------------------------------------------------
        # Example:
        print("TH_FUNC: Loop started")
        for i in range(0, 5):
            print("TH_FUNC: Loop no:", i)
            sleep_time = utime.sleep_ms(10000, True)
            if sleep_time < 10000:
                # Notification received while sleeping 
                print("TH_FUNC: Notification while sleeping", st)
                # Sleep for the remaining interval if needed
                utime.sleep_ms(10000 - sleep_time)
        print("TH_FUNC: Loop ended")

For now, I'm fixing this by using a custom sleep function:

def sleep(sleep_time_ms):
        time = 0
        while time < sleep_time_ms:
                time += utime.sleep_ms(sleep_time_ms - time, True)

This will end to sleep the wanted time.

Thank you for your reply, not sure if it is an issue or a feature.