Weird sleep_ms behaviour

Hello everyone,

I’m observing some unusual behavior with the utime.sleep_ms() function on the BG95-M3 module, both on the official PI Zero EVB and a custom board.

Somwhere inside my script, I run a polling loop for ~1 second using ~10 ms steps. I record utime.ticks_ms() before and after each sleep_ms() call.

What works:
When the board is plugged into USB and properly enumerated, everything works as expected:

  • The loop runs ~56 times per second
  • Each sleep_ms(10) call actually sleeps for around 18 ms, which is somehow expectable due to RTOS overhead

The issue:
When USB is disconnected or not enumerated (e.g. by switching off VBUS), the delay for each sleep_ms(10) call jumps to 600–1000 ms or more. As a result:

  • The loop only runs ~2 times per second
  • All time-based operations slow down: socket timeouts, waitForNetwork(), etc.

Other notes:

  • utime.ticks_ms() still behaves correctly and shows accurate time deltas
  • It seems like some background task or timing mechanism is stalling when USB isn’t enumerated
  • I’ve disabled all known power-saving features using these AT commands:
    • AT+CPSMS=0
    • AT+CEDRXS=0
    • AT+QSCLK=0
      …but the behavior remains unchanged.

Request:
Has anyone encountered this issue or something similar?
Any ideas for a fix or workaround would be greatly appreciated!

Thanks in advance!

After like 30 minutes it got even worse and the sleep_ms(10) takes something about 9 seconds, sometimes up to a minute!

Some additional details:

  • When plugged an unplugged quickly, it works correctly when plugged and then returns to the previous state when unplugged (so to the magnitude of seconds instead of hundreths of msecs)
  • There has to be some socket communication!
  • I am using the latest V0003 firmware for M3 available online.

This is my minimal example to reproduce:
main.py (1.4 KB)
When downloaded to device, just start the code and then unplug VBUS detect line to stop USB device.

hi petr

sorry for the late reply.

I have tried and checked your script.I can reproduce your problem.

As far as I know, the API sleep_ms in Quecpython has a relatively large error.

If you want to reduce the time error, I recommend using hardware timers.
Here are the relevant links.
Timer - Control Hardware Timers - QuecPython

Hi!
I am able to work around it in my code. The problem is, it affects also some system functions like checkNet.waitNetworkReady(timeout) or socket timeouts, which means, that in case of weaker signal or packet loss, It can get stucked for much longer period than specified rendering the application unresponsive.

As far as I know, there is indeed an issue with time inaccuracy in Quecpython. In my opinion, this should be optimized through the app side.
May I ask if you have tried to synchronize different threads using methods such as semaphores and queues? it might work better.

I actually did not try to use threading at all.
We are using a really simple work cycle like in this pseudocode (there is more, but this is the overall structure):

while True:
  sleep(10)

  msg = readLineFromUart()
  if msg:
    checkNet.waitNetworkReady(30):
    if not tryUdpRequest(msg, retries: 3, timeout: 2.5):
       tryTcpRequest(msg, timeout: 10)

Assuming, the network is connected, this loop should take 10+3*2.5+10 in the worst case, but sometimes it takes around 300 secs even when the network is ready.

Could you show me the complete test script? Let me try it.

However, in Python, delays are indeed inaccurate, especially with the sleep function.