Fitness-uhr
- auf dem runden 1.28-Zoll-IPS-LCD-Display 240 x 240 Pixel
- nutzt den ACC Beschleunigungssensor in Micropython
Hardware
- Rundes 1,28-Zoll-IPS-LCD-Display
- RP Pico 2040 (inclusive)
- USB-A zu USB-C Kabel
- 3.7V 100mAh Lithium Polymer Akku
(z.B. von hier)
Fitness-uhr
- auf dem runden 1.28-Zoll-IPS-LCD-Display 240 x 240 Pixel
- nutzt den ACC Beschleunigungssensor in Micropython
- RP Pico 2040 (inclusive)
- USB-A zu USB-C Kabel
- 3.7V 100mAh Lithium Polymer Akku (z.B. von hier)
Es wird wieder der 3-Achsen ACC Sensor genutzt, wie schon in der 1. Anleitung, um die Schritte zu zählen. Zuätzlich wird in dieser Anleitung
die exakte Uhrzeit, auch wenn das Gerät nicht am PC angeschlossen ist, angezeigt. Dazu wird diese auf dem Pico-Laufwerk gespeichert und zur
Stromversorgung wird ein kleiner Akku ins Gehäuse integriert. Es geht also
- um die Stromversorgung beim runden Pico-LCD-Display mit einem kleinen 3.7V 100mAh Lithium Polymer Akku
- um die exakte Erfassung der Zeit auf Basis des Prozessortaktes (unabhängig von time.sleep()) und,
- um Schreib- und Lesevorgänge unter Micropython beim Pico.
Los gehts
1.
Ich gehe als erstes auf die Stromversorgung ein. Der vorgeschlagene 3,7 V Litium-Polymer Akku mit 100 mAh ist größenmäßig gut
in ein Uhrengehäuse
integrierbar. Im Betrieb fließen beim runden Pico-LCD-Display etwa 60 mA Strom, so dass die Akkukapazität ohne nachladen
für ca. 1,5 Stunden reicht. Zum Aufladen kann die Fitnessuhr ohne Funktionsunterbrechung an den USB-C Anschluss angeschlossen werden.
So gesehen besser als beim E-Auto. Die Fitnessuhr muss zwar auch häufig an die "Ladesäule" aber braucht dabei nicht mal anzuhalten.
Ganz wichtig: Ein Anbieter der Displays hat darauf hingewiesen, dass der Batterieanschluss ein wenig gebräuchlicher
MX1.25-Stecker mit 1.25 mm Rastermaß ist. Den passenden Stecker habe ich
(z.B. hier bestellt).
Zu beachten ist, dass bei der Richtung, wie der Stecker in die Inline-Buchse am Display kommt, die Farbkennzeichnung der Polung verkehrt ist.
Dass bedeuted, dass Sie beim Anlöten der Kabel an den Akku bewußt schwarz auf rot und rot auf
schwarz löten müssen. Bei meinen gelieferten Kabeln war es auf jeden Fall so!
Bildbox (klick hier)
2.
Weiter geht es mit dem Einrichten der Uhrfunktion. Der Programmanfang stimmt mit dem in der vorherigen Anleitung überein (
wird am Ende noch einmal komplett zum Kopieren eingefügt). Ab Zeile 93 werden zwei Funktionen definiert, die den Bildschirm aufbauen.
Bildbox (klick hier)
93 def refresh(): 94 # Hintergrundbildschirm 95 LCD.fill(LCD.black) 96 circle(120,120,114,LCD.beige) 97 circle(120,120,86,LCD.black) 98 circle(120,120,75,LCD.darkgray) 99 ring(step,ziel) 100 printstring("Schritte",90,90,1,LCD.white) 101 triangle2(x3,y3,x4,y4) 102 LCD.fill_rect(30,210,160,50,LCD.black) 103 triangle1(x1,y1,x2,y2) 104 # Spannung in % anzeigen anzeigen 105 LCD.rect(90,220,30,10,LCD.white) 106 LCD.rect(120,222,2,5,LCD.white) 107 LCD.fill_rect(92,222,24,6,LCD.glade) 108 reading = Vbat.read_u16()*3.3/65535*2 109 printstring(str(int(reading/4.5*100)) + " %",130,220,1,LCD.white) 110 LCD.show() 111 112 def ring(step,ziel): 113 for i in range (step*120/ziel): 114 xpos_neu = int(width/2 + 100*math.cos((i/2+15)*math.pi/30)) 115 ypos_neu = int(height/2 + 100*math.sin((i/2+15)*math.pi/30)) 116 circle(xpos_neu,ypos_neu,17,LCD.red) 117 time.sleep(0.01) 118 LCD.show()
Danach werden Werte aus der Datei 'last_time.txt' vom Pico-Laufwerk gelesen. Darin ist die Stunde und Minute der letzten bekannten Uhrzeit und die Anzahl der Schritte abgelegt. In diesem Teil des Programms wird auch ermittelt, ob der Pico am PC angeschlossen ist. Wenn ja, liefert 'time.localtime()' die aktuelle Uhrzeit an das Tupel 'current_time'. Diese wird in den Zeilen 141 bis 150 sofort neu in die Datei gespeichert. Ist hingegen 'current_time[0]=2021', dann bedeuted das, dass der Pico ohne Rechneranschluss gestartet wurde. 'time.localtime()' beginnt in diesem Fall am 1.1.2021 die Sekunden zu zählen. Für die Stunde und die Minuten wird dann die letzte bekannte Zeit verwendet. Wenn man also den USB Anschluss des Pico vom Rechner abzieht und innerhalb einer Minute an eine andere Spannungsversorgung anklemmt, verliert man max. eine Minute, die man ja im Bereich der Zeilen 151 bis 157 hinzuaddieren könnte. Ist hingegen der Akku angeschlossen, kommt es zu keiner Unterbrechung, also auch zu keinem Zeitverlust, da der Timer nicht neu startet.
134 # Schritte auslesen 135 with open("last_time.txt", "r") as f: 136 hour = int(f.readline()) 137 minute = int(f.readline()) 138 step = int(f.readline()) 139 f.close() 140 141 current_time = time.localtime() 142 hour = current_time[3] 143 minute = current_time[4] 144 second = current_time[5] 145 if current_time[0] > 2021: 146 with open("/last_time.txt", "w") as f: 147 f.write(str(hour)+"\n") 148 f.write(str(minute)+"\n") 149 f.write(str(step)) 150 f.close() 151 if current_time[0] == 2021: 152 with open("last_time.txt", "r") as f: 153 hour = int(f.readline()) 154 minute = int(f.readline()) 155 step = int(f.readline()) 156 f.close() 157 second = current_time[5] 158 159 refresh() 160 start = time.ticks_ms()
3.
In Zeile 160 wird die Variable Start mit time.ticks_ms() gesetzt. Damit wird später in der while Schleife nach 5 Minuten (300 s)
der Bildschirm refreshed, wodurch wieder der aktuelle Batteriezustand angezeigt wird. In der 'while' Schleife erfolgt dann das Auslesen des
Sensors und die Zeitanzeige. Wenn die Sekunde 59 erreicht ist, wird hochgezählt und die Stunde, Minute und Schritte in der Datei
aktualisiert. Damit der Speichervorgang in der Sekunde 59 nicht mehrfach ausgeführt wird, ist in Zeile 194 eine Pause von 1s, die aber
auf den Sekundentakt von 'time.localtime()' keinen Einfluss hat. Es kommt also nicht zu einer Zeitverspätung.
181 if second == 59: 182 printstring(zeit,50,120,3,LCD.darkgray) 183 minute += 1 184 if minute == 60: 185 minute = 0 186 hour += 1 187 if hour == 24: 188 hour = 0 189 with open("/last_time.txt", "w") as f: 190 f.write(str(hour)+"\n") 191 f.write(str(minute)+"\n") 192 f.write(str(step)) 193 f.close() 194 time.sleep(1) 195 zeit = str(hour) + ":" + str(minute) 196 if minute < 10: 197 zeit = str(hour) + ":0" + str(minute) 198 printstring(zeit,50,120,3,LCD.white) 199 meter = int(step * 0.762) 200 printstring(str(meter)+" m",105,175,1,LCD.white) 201 #cal = int(int(step * 0.38)*4.18)/1000 202 cal = int(int(step * 0.38)*4.18) 203 printstring(str(cal)+" J",105,190,1,LCD.white) 204 if second < 10: 205 printstring(":0" + str(second),157,123,2,LCD.white) 206 else: 207 printstring(":" + str(second),157,123,2,LCD.white) 208 LCD.show()
In den Zeilen 209 bis 236 wird die Bewegung des Sensors, wie bereits aus der 1. Anleitung bekannt, erfasst. Wie versprochen gebe ich
jetzt noch einmal den kompletten Programmcode zu Kopieren an. Klicken Sie dazu auf die Schaltfläche 'Code kopieren'
und setzen ihn im Thonny ein. Bevor Sie das Programm starten, stellen Sie sicher, dass sich die Dateien init_lcd_1_28.py,
font.py und last_time.txt auf dem Picolaufwerk befinden. Die beiden ersten Dateien können Sie noch einmal
hier herunterladen . Die Textdatei legen Sie einfach
im Thonny an, indem Sie auf Datei hinzufügen klicken, dann eine Stunde[Enter]Minute
[Enter]Schritte[Enter] eingeben
und unter dem o.g. Namen speichern.
Updated : 15.08.2023
- Batterieanzeige in extra Funktion und Prozentanzeige bezogen auf die Abschaltspannung (< 3.3 V).
1 # SPDX-FileCopyrightText: 2023 Detlef Gebhardt, written for MicroPython 2 # SPDX-FileCopyrightText: Copyright (c) 2023 Detlef Gebhardt 3 # 4 # SPDX-License-Identifier: GEBMEDIA 5 from machine import Pin,I2C,SPI,PWM,ADC 6 import framebuf 7 import time 8 import init_lcd_1_28 9 import font ... ... ... 235 printstring(":" + str(second),157,123,2,LCD.white) 236 if step == ziel: 237 alpha = 1 238 refresh() 239 LCD.show() 240 time.sleep(0.2)
Viel Spass und Erfolg beim Ausprobieren.
Viel Spass und Erfolg beim Ausprobieren.