more detail and a working example of how to synchronise the Raspberry Pi Pico to a host computer . . . can this now be incorporated into rshell?
Code: Select all
#!/usr/bin/env python3
#
# Vendor:Product ID for Raspberry Pi Pico is 2E8A:0005
#
# see section 4.8 RTC of https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf and in particular section 4.8.6
# for the RTC_BASE address (0x4005C000) and details of the RD2040 setup registers used to program the RTC
#
from serial.tools import list_ports
import serial, time
picoPorts = list(list_ports.grep("2E8A:0005"))
utcTime = str( int(time.time()) )
pythonInject = [
'import machine\r\n',
'import utime\r\n',
'rtc_base_mem = 0x4005c000\r\n',
'atomic_bitmask_set = 0x2000\r\n',
'led_onboard = machine.Pin(25, machine.Pin.OUT)\r\n',
'(year,month,day,hour,minute,second,wday,yday)=utime.localtime('+utcTime+')'+'\r\n',
'machine.mem32[rtc_base_mem + 4] = (year << 12) | (month << 8) | day\r\n',
'machine.mem32[rtc_base_mem + 8] = ((hour << 16) | (minute << 8) | second) | (((wday + 1) % 7) << 24)\r\n',
'machine.mem32[rtc_base_mem + atomic_bitmask_set + 0xc] = 0x10\r\n',
'for i in range(5):\r\n',
' led_onboard.toggle()\r\n',
' utime.sleep(0.03)\r\n',
'led_onboard.value(0)\r\n'
]
if not picoPorts:
print("No Raspberry Pi Pico found")
else:
picoSerialPort = picoPorts[0].device
with serial.Serial(picoSerialPort) as s:
s.write(b'\x03')
s.write(b'\x03')
s.write(b'\x01')
for n in range(len(pythonInject)):
s.write(bytes(pythonInject[n], 'ascii'))
time.sleep(0.1)
s.write(b'\x04')
s.write(b'\x02')
print( 'Raspberry Pi Pico found at '+str(picoSerialPort)+'\r' )
print( 'Host computer epoch synchronised over USB serial: '+utcTime+'\r' )
The above code is designed to be executed on a host computer (Windows, Mac or Linux) and will
automagically find your connected Pico and then synchronise its date and time (this code requires that
python3 and
pyserial are installed on the
host computer).
No MicroPython code needs be added or running on the Pico for this to work,
but Thonny does need to closed (
so as not to block the USB serial port) whilst it does it's magic
It works by injecting a small MicroPython script, which it modifies on the fly with the host computers UTC, into the Pico over the USB serial link using the RAW REPL functionality of MicroPython (kudos to
rshell for some of the ideas/techniques used
https://github.com/dhylands/rshell)
Oh, and the injected code generates
a short pulse of the Pico on-board LED to let the user know the RTC has been synchronised
More information can be found on
pyserial here
https://pyserial.readthedocs.io/en/latest/pyserial.html. To install
pyserial enter the following on the host computer command line.
NOTE: if code is running on the Pico, the synchronisation process will interrupt it. You can restart the code running on your Pico board using Thonny, provided you don't disconnect it from power (
effectively reseting it). If you do reset the Pico, or disconnect it from power, you will need to re-sync your Pico board with a host computer again to have an accurate
RTC (by default, at startup, the MicroPython interpreter running on the Pico initialises the
Pico system clock to
1609459201 -
Thursday, 1st January 2021 00:00:01)
This post
https://www.raspberrypi.org/forums/view ... 6&t=300676 provides some more information regarding how to achieve a ‘
RTC battery backup’ by attaching a battery to VSYS and GND, but it does have the disadvantage of powering the whole Pico (~ 19mA) rather than just the RTC.