Hi, y'all! I'm very new to MicroPython and Python in general -- I'm a Node/JS web dev -- and I'm trying to understand why some code seems to be running very slowly on my Pico 2 W. I'm not sure if it's something I'm doing wrong or a limitation of the Pico itself, because I've never worked with things like frame buffers and drawing directly to hardware before.
I'm using a Pico 2 W and the Waveshare Pico 1.3 LCD with buttons, and basically I'm just trying to draw an analog clock face along with the date/time and battery percentage in text. I used Waveshare's example driver code with slight modifications (mostly just naming the buttons), which returns a FrameBuffer object to write to.
I figured out how to connect via my home wifi to an NTP server at boot and get the correct time, draw everything to the LCD's buffer and it works great... except it seems like it takes sometimes more than a second to update the screen. Even if I use time.sleep(0.1) at the end of my while True: loop, it still only repeats about once every second or 1.1 seconds, maybe? Enough that the seconds hand on the watch occasionally jumps because the screen refresh is lagging behind real time.
This is the function I'm using. I'm hoping someone can explain what I'm doing wrong or inefficiently here.
All I do in my while True: loop is just this:Is there something I'm obviously missing, or is the Pico just not capable of displaying an analog clock face at faster than 1fps? I'm not used to memory management or anything, being a Node/JS person: is there something I'm doing that's causing issues there?
Any advice would be great. I'm using this to teach myself MicroPython and basic hardware coding. Eventually the display will also connect to my Android phone via BT and probably a tiny phone app so I can control my music playback with it and to pass JSON text to the screen to render, so I can do things like put my Google Tasks list on a screen on it. At least, that's my plan, assuming I can get past this hurdle.
Thanks!
I'm using a Pico 2 W and the Waveshare Pico 1.3 LCD with buttons, and basically I'm just trying to draw an analog clock face along with the date/time and battery percentage in text. I used Waveshare's example driver code with slight modifications (mostly just naming the buttons), which returns a FrameBuffer object to write to.
I figured out how to connect via my home wifi to an NTP server at boot and get the correct time, draw everything to the LCD's buffer and it works great... except it seems like it takes sometimes more than a second to update the screen. Even if I use time.sleep(0.1) at the end of my while True: loop, it still only repeats about once every second or 1.1 seconds, maybe? Enough that the seconds hand on the watch occasionally jumps because the screen refresh is lagging behind real time.
This is the function I'm using. I'm hoping someone can explain what I'm doing wrong or inefficiently here.
Code:
def drawClock(lcd): # This draws the clock face hour numbers for i in range(1, 13): angle = math.radians(90 - i * 30) x = centerX + (centerX) * 0.85 * math.cos(angle) y = centerY - (centerY) * 0.85 * math.sin(angle) lcd.text(str(i), int(x), int(y),lcd.amber) # Gets current time with offset for British Summer Time year, month, day, hour, minute, second, weekday, yearday = time.localtime() if yearday > 88 and yearday < 299: hour = hour + 1 # This draws the clock hands sec_angle = math.radians(90 - second * 6) min_angle = math.radians(90 - minute * 6 - minute * 0.1) hour_angle = math.radians(90 - (hour % 12 + minute / 60) * 30) lcd.line(centerX, centerY,int(centerX + secondHandLength * math.cos(sec_angle)), int(centerY - secondHandLength * math.sin(sec_angle)), lcd.amber) lcd.line(centerX, centerY,int(centerX + minuteHandLength * math.cos(min_angle)), int(centerY - minuteHandLength * math.sin(min_angle)), lcd.red) lcd.line(centerX, centerY,int(centerX + hourHandLength * math.cos(hour_angle)), int(centerY - hourHandLength * math.sin(hour_angle)), lcd.red) lcd.line(centerX+1, centerY+1,int(centerX + 1+hourHandLength * math.cos(hour_angle)), int(centerY - 1- hourHandLength * math.sin(hour_angle)), lcd.red) lcd.line(centerX-1, centerY-1,int(centerX - 1+hourHandLength * math.cos(hour_angle)), int(centerY - 1- hourHandLength * math.sin(hour_angle)), lcd.red) # This gets the battery voltage voltage = vsys.read_u16() * conversion_factor percentage = 100 * ((voltage - empty_battery) / (full_battery - empty_battery)) if percentage > 100 or percentage < 0: percentage = 100.00 # This parses the time and battery percentage and prints them dhour = hour aorp = "am" if dhour > 12: dhour = dhour - 12 aorp = "pm" textTime = f"{day}-{month}-{year} {dhour}:{minute}:{second}{aorp}" textBattery = f"Battery: {int(percentage)}%" lcd.text(textTime,int(centerX - ((len(textTime) * 8) / 2)),0, lcd.white) batteryColor = lcd.white if percentage < 10: batteryColor = lcd.red lcd.text(textBattery,lcd.width - (len(textBattery) * 8),lcd.height - 8, batteryColor)Code:
drawClock(lcd)lcd.show()Any advice would be great. I'm using this to teach myself MicroPython and basic hardware coding. Eventually the display will also connect to my Android phone via BT and probably a tiny phone app so I can control my music playback with it and to pass JSON text to the screen to render, so I can do things like put my Google Tasks list on a screen on it. At least, that's my plan, assuming I can get past this hurdle.
Thanks!
Statistics: Posted by jzellis — Thu Aug 07, 2025 11:33 am