← index #16008Issue #16519
Related · high · value 0.808
QUERY · ISSUE

Using ntptime.settime() while _thread is running can break sleep timing

openby GM-Script-Writer-62850opened 2024-10-14updated 2026-03-24
bugport-rp2

Port, board and/or hardware

Raspberry Pi PICO W

MicroPython version

MicroPython v1.23.0 on 2024-06-02; Raspberry Pi Pico W with RP2040

Reproduction

  • _thread_work() - measure how long time.sleep takes
  • wifi() - connect to wifi and reconnect if it does down
    • wifi_auth just has the wifi login variables
  • setTime() - this sets the clock using ntptime
    • this was unreliable in micropython 1.2, hence the try blocks
  • wait4clock() - just some busy work for asyncio, can be used to start process that depend on the clock being set
import _thread
import ntptime
import asyncio
import time

sleep=asyncio.sleep_ms
#ntptime.host="10.0.0.69"
wlan = 0

def _thread_work():
	while 1:
		then=time.ticks_ms()
		time.sleep(1)
		then=time.ticks_diff(time.ticks_ms(),then)
		print("Core 1:",then)

async def wifi():
	from wifi_auth import ssid, password
	import network

	global wlan
	wlan = network.WLAN(network.STA_IF)
	wlan.active(True)
	wlan.config(pm = 0xa11140)# Power management is very very bad, ping time is around 1000x worse and packet loss insane
	wlan.connect(ssid, password)

	while 1:
		while 1:
			wstat=wlan.status()
			if wstat < 0 or wstat >= 3:
				break
			print('Waiting for WiFi connection...')
			await sleep(1000)

		if wlan.status() == 3:
			status = wlan.ifconfig()
			print('Wifi Connected; ip =',status[0])
			while wlan.isconnected():
				await sleep(30000)
			print('WiFi Down')
		else:
			print("Failed to connect to wifi; retry in 30 seconds")
			await sleep(30000)
		wlan.connect(ssid, password)
#END wifi()

async def setTime():
	#ntptime.settime() failure: [Errno 110] ETIMEDOUT
	#ntptime.settime() failure: overflow converting long int to machine word
	print('Attempt to set time')
	success=0
	try:
		print("calling ntptime.settime()")
		ntptime.settime()
		success=1
	except OverflowError:
		# it is not going to work
		print("overflow error; settime is borked")
	except OSError:
		print("ntptime.settime() failure")
	if not success:
		await sleep(10000)
		asyncio.create_task(setTime())
	else:
		print("END of setTime() process")
#END setTime()

async def wait4clock():
	delay=2000
	while time.time() < 1640995200: # Wait for clock to set or a 1 year...)
		print("Waiting for clock...")
		await sleep(3000)
	print('Clock set:',time.time())
	#_thread.start_new_thread(_thread_work,())
#END wait4clock()

async def main():
	asyncio.create_task(wait4clock())
	asyncio.create_task(wifi())
	while not wlan or not wlan.isconnected():
		then=time.ticks_ms()
		await sleep(1000)
		then=time.ticks_diff(time.ticks_ms(),then)
		print("Core 0:",then,"Waiting for wifi")
	asyncio.create_task(setTime())
	while 1:
		then=time.ticks_ms()
		await sleep(1000)
		then=time.ticks_diff(time.ticks_ms(),then)
		print("Core 0:",then)

_thread.start_new_thread(_thread_work,())

asyncio.run(main())

Expected behaviour

Calls to time.sleep(1) and asyncio.sleep_ms(1000) should be near 1 second long

Observed behaviour

output of example code:

Waiting for clock...
Waiting for WiFi connection...
Core 1: 1000
Core 0: 1000 Waiting for wifi
Waiting for WiFi connection...
Core 1: 1000
Core 0: 1001 Waiting for wifi
Waiting for WiFi connection...
Core 1: 1000
Waiting for clock...
Core 0: 1003 Waiting for wifi
Wifi Connected; ip = 10.0.0.190
Core 1: 1000
Core 0: 1001 Waiting for wifi
Attempt to set time
calling ntptime.settime()
END of setTime() process
Core 1: 22526
Core 0: 22522
Clock set: 1728875328
Core 1: 5324
Core 0: 5324
Core 1: 7473
Core 0: 7474
Core 1: 17208
Core 0: 17208
Core 1: 5319
Core 0: 5319
Core 1: 24678
Core 0: 24678
Core 1: 5325
Core 0: 5325
Core 1: 24678
Core 0: 24678
Core 1: 5330
Core 0: 5330
Core 1: 24673
Core 0: 24673
Core 1: 5325
Core 0: 5325
Core 1: 24684
Core 0: 24684
Core 1: 5319
Core 0: 5319
Core 1: 24682
Core 0: 24683
Core 1: 5324
Core 0: 5324
Core 1: 1939
Core 0: 1939
Core 1: 5734
Core 0: 5734
Core 1: 5836
Core 0: 5836
Core 1: 11162
Core 0: 11162
Core 1: 5329
Core 0: 5330
Core 1: 7059
Core 0: 7059
Core 1: 13925
Core 0: 13926
Core 1: 3687
Core 0: 3687
Core 1: 5325
Core 0: 5325
Core 1: 7269
Core 0: 7269
Core 1: 17413
Core 0: 17413
Core 1: 5325
Core 0: 5325
Core 1: 1018
Core 0: 1018
Core 1: 23655
Core 0: 23655
Core 1: 5324
Core 0: 5324

Additional Information

  • Note this does not have a 100% reproduction rate, feels near 50%
  • This is a regression since micropython 1.2 (rp2-pico-w-20230426-v1.20.0.u2f)
  • Note that Thonny is set to NOT synchronize device's real time clock (Tools -> Options-> Interpreter)

Code of Conduct

Yes, I agree

CANDIDATE · ISSUE

RP2: machine.RTC().datetime() does not advance during lightsleep

openby madozuopened 2025-01-03updated 2025-12-13
bugport-rp2

Port, board and/or hardware

Raspberry Pi Pico W and Raspberry Pi Pico 2 W

MicroPython version

All versions starting with v1.24.0 (including recently released v1.26.0)

Reproduction

  1. Copy code below to Pico and name it "main.py"
  2. Reset the Pico and allow the code to complete (approx 5 seconds). No repl needed as the code writes a log file to the flash storage
  3. Connect the Pico to the USB port and inspect the file "local.log" on the Pico

Code used to test:

# Test RTC sleep behaviour
import machine, os, time

SLEEP_MS = const(2000)

def write_log(s: str) -> None:
    dt = machine.RTC().datetime()
    log_text = f"[RTC={dt[4]:02d}:{dt[5]:02d}:{dt[6]:02d} ticks={time.ticks_ms()}]  {s}"
    with open("local.log", "a") as file:
        file.write(log_text + "\n")

write_log(f"Machine = '{os.uname()[4]}'")
write_log(f"Version = '{os.uname()[3]}'")
time.sleep_ms(SLEEP_MS)
write_log(f"After time.sleep_ms({SLEEP_MS})")
machine.lightsleep(SLEEP_MS)
write_log(f"After machine.lightsleep({SLEEP_MS})")

Expected behaviour

The real time clock should advance by 2 seconds after running 'machine.lightsleep(2000)' like it was on micropython versions up to and including 1.23.0. Example output from 1.23.0:

[RTC=00:00:01 ticks=49]  Machine = 'Raspberry Pi Pico W with RP2040'
[RTC=00:00:01 ticks=54]  Version = 'v1.23.0 on 2024-06-02 (GNU 13.2.0 MinSizeRel)'
[RTC=00:00:03 ticks=2058]  After time.sleep_ms(2000)
[RTC=00:00:05 ticks=4065]  After safe_sleep(2000) with 0 early wakeups

Observed behaviour

The real time clock does not advance during machine.lightsleep(2000) as shown below running on 1.26.0:

[RTC=00:00:01 ticks=36]  Machine = 'Raspberry Pi Pico W with RP2040'
[RTC=00:00:01 ticks=42]  Version = 'v1.26.0 on 2025-08-09 (GNU 14.2.0 MinSizeRel)'
[RTC=00:00:03 ticks=2033]  After time.sleep_ms(2000)
[RTC=00:00:03 ticks=4037]  After machine.lightsleep(2000)

Additional Information

While machine.RTC().datetime() does not advance during machine.lightsleep(), time.ticks_ms advances as expected.

Code of Conduct

Yes, I agree

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied