Schrittzähler

von Waveshare nachgebaut 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


Im 'Anleitung 4' habe ich das runde Pico-LCD-1.28 Display von Waveshare vorgestellt und ein paar Anregungen für die Inbetriebnahme unter Circuitpython gegeben. Dabei habe ich es als sehr schade empfunden, dass es in Circuitpython bisher keine Beispielprogramme gibt. Insbesondere fehlt noch eine Bibliothek QMI8658 zur Nutzung des Sensors. Der eingebaute Sensor ermöglicht die Messung der Beschleunigung in 3 Achsen (3-Achsen-Beschleunigungsmesser) und der Orientierung in 3 Achsen (3 Achsen-Gyroskop). Da Waveshare in Micropython ein Beispielprogramm mit der 'class LCD_1inch28' und 'class QMI8658' bereitstellt, habe ich mich diesmal dafür entschieden.

Los gehts

Eine Sache sei noch vorab erwähnt. Diese Anleitung ist für evtl. erste Schritte bei der Pico-Nutzung sehr schwer und erfordert etwas Erfahrung.
Im Auslieferungszustand hat das Display eine Firmware, welche unterschiedliche Farben und Werte des Sensors anzeigt. Damit kann der Nutzer noch gar nichts anfangen. Es sieht nur, dass irgend etwas funktioniert.
Laden Sie sich also eine aktuelle Firmware (uf2-Datei) von Micropython für den RP Pico 2040 z.B. von hier herunter und flashen damit das Display. Anleitungen gibt es dafür im Netz reichlich.
Als nächstes brauchen Sie die Datei 'RP2040-LCD-1.28.py'. Die können Sie von Waveshare oder hier von meiner Seite herunterladen. Entpacken Sie die zip-Datei, schließen das Display über den USB-A zu USB-C Anschluss an und starten das Programm. Was Sie sehen ist ähnlich wenig, wie bei der mitgelieferten Firmware, aber jetzt kann man den vollständigen Quellcode einsehen und analysieren. Das bringt uns nach vorne.
Schauen wir uns das Programm zusammen an:

  
  

1   from machine import Pin,I2C,SPI,PWM,ADC
2   import framebuf
3   import time

7   I2C_SDA = 6
8   I2C_SDL = 7
10  DC = 8
11  CS = 9
12  SCK = 10
13  MOSI = 11
14  RST = 12
16  BL = 25
18  Vbat_Pin = 29

22  class LCD_1inch28(framebuf.FrameBuffer):
23      def __init__(self):
24          self.width = 240
25          self.height = 240
        

336 class QMI8658(object):
337    def __init__(self,address=0X6B):
338        self._address = address
339        self._bus = I2C(id=1,scl=Pin(I2C_SDL),sda=Pin(I2C_SDA),freq=100_000)
340        bRet=self.WhoAmI()
341        if bRet :
342            self.Read_Revision()
343        else    :
344            return NULL
345         self.Config_apply()

397     def Read_XYZ(self):
398        xyz=[0,0,0,0,0,0]
399        #QMI8658AccRange_8g
400        acc_lsb_div=(1<<12)
401        #QMI8658GyrRange_512dps
402        gyro_lsb_div = 64
403        for i in range(3):
404            xyz[i]=raw_xyz[i]/acc_lsb_div#(acc_lsb_div/1000.0)
405            xyz[i+3]=raw_xyz[i+3]*1.0/gyro_lsb_div
406        return xyz

411 if __name__=='__main__':
  
413     LCD = LCD_1inch28()
414     LCD.set_bl_pwm(65535)
415     qmi8658=QMI8658()
416     Vbat= ADC(Pin(Vbat_Pin))
    
418     while(True):
419        #read QMI8658
420        xyz=qmi8658.Read_XYZ()
421
422        LCD.fill(LCD.white)
423
424        LCD.fill_rect(0,0,240,40,LCD.red)
425        LCD.text("RP2040-LCD-1.28",60,25,LCD.white)
426
427        LCD.fill_rect(0,40,240,40,LCD.blue)
428        LCD.text("Waveshare",80,57,LCD.white)
429
430        LCD.fill_rect(0,80,120,120,0x1805)
431        LCD.text("ACC_X={:+.2f}".format(xyz[0]),20,100-3,LCD.white)
432        LCD.text("ACC_Y={:+.2f}".format(xyz[1]),20,140-3,LCD.white)
433        LCD.text("ACC_Z={:+.2f}".format(xyz[2]),20,180-3,LCD.white)
434
435        LCD.fill_rect(120,80,120,120,0xF073)
436        LCD.text("GYR_X={:+3.2f}".format(xyz[3]),125,100-3,LCD.white)
437        LCD.text("GYR_Y={:+3.2f}".format(xyz[4]),125,140-3,LCD.white)
438        LCD.text("GYR_Z={:+3.2f}".format(xyz[5]),125,180-3,LCD.white)
439
440        LCD.fill_rect(0,200,240,40,0x180f)
441        reading = Vbat.read_u16()*3.3/65535*2
442        LCD.text("Vbat={:.2f}".format(reading),80,215,LCD.white)
443
444        LCD.show()
445        time.sleep(0.1)
  

In den Zeilen 1 bis 3 werden Module importiert. Dann erfolgt die Variablendefinition der Pins in den Zeilen 7 bis 18. Es folgt ab Zeile 22 bis 333 die Klasse 'class LCD_1inch28' für die Displayansteuerung. Diese brauchen Sie bei jedem Programm, welches das runde-LCD-Display 1.28 nutzt. Ebenfalls die Klasse 'class QMI8658' für den Sensor Zeilen 336 bis 407. Der Rest in der 'while' Schleife ist das eigentliche Hauptprogramm, was den darzustellenden Inhalt für das Display enthält. Durch die riesige Menge an Zeilen, sieht man den Wald vor lauter Bäumen nicht mehr. Deshalb habe ich diesen Teil des Programms ausgelagert in eine Datei 'init_lcd_1_28.py', die von jedem späteren Programm importiert werden kann. Ebenso habe ich eine Datei 'font.py' ausgelagert. In der Originalversion ist nur eine winzige Schriftgröße möglich. Mit der importierten Font-Map sind es immerhin drei. Sie können sich diese beiden Dateien wieder herunterladen und im Hauptverzeichnis des Pico-Displays speichern. Am Ende dieser beiden Dateien sehen Sie auch, wie man das automatische Starten verhindert, wenn es von woanders importiert wird. Im Hauptprogramm werden dann später einfach die benötigten Klassen aufgerufen. Dadurch ist sehr viel für die Übersichtlichkeit des Hauptprogramms getan. Übrig bleibt folgender Code, mit der identischen Funktion, wie das Ursprungsprogramm 'RP2040-LCD-1.28.py' von Waveshare.

  
  

1  from machine import Pin,I2C,SPI,PWM,ADC
2  import framebuf
3  import time
4  import init_lcd_1_28
5  import font
6
7  Vbat_Pin = 29
8
9  LCD = init_lcd_1_28.LCD_1inch28()
10 LCD.set_bl_pwm(65535)
11 qmi8658=init_lcd_1_28.QMI8658()
12 Vbat= ADC(Pin(Vbat_Pin))
13
14 while(True):
15     #read QMI8658
16     xyz=qmi8658.Read_XYZ()
17
18     LCD.fill(LCD.white)
19
20     LCD.fill_rect(0,0,240,40,LCD.red)
21     LCD.text("RP2040-LCD-1.28",60,25,LCD.white)
22
23     LCD.fill_rect(0,40,240,40,LCD.blue)
24     LCD.text("Waveshare",80,57,LCD.white)
25
26     LCD.fill_rect(0,80,120,120,0x1805)
27     LCD.text("ACC_X={:+.2f}".format(xyz[0]),20,100-3,LCD.white)
28     LCD.text("ACC_Y={:+.2f}".format(xyz[1]),20,140-3,LCD.white)
29     LCD.text("ACC_Z={:+.2f}".format(xyz[2]),20,180-3,LCD.white)
30
31     LCD.fill_rect(120,80,120,120,0xF073)
32     LCD.text("GYR_X={:+3.2f}".format(xyz[3]),125,100-3,LCD.white)
33     LCD.text("GYR_Y={:+3.2f}".format(xyz[4]),125,140-3,LCD.white)
34     LCD.text("GYR_Z={:+3.2f}".format(xyz[5]),125,180-3,LCD.white)
35
36     LCD.fill_rect(0,200,240,40,0x180f)
37     reading = Vbat.read_u16()*3.3/65535*2
38     LCD.text("Vbat={:.2f}".format(reading),80,215,LCD.white)
39
40     LCD.show()
41     time.sleep(0.1)
  

Anhand des Fotos lassen sich die Programmzeilen und die Funktion gut erkennen.
  • 16: der Sensor wird gelesen.
  • 18: Display wird weiss dargestellt
  • 20, 21: rotes Recheck mit dem Text 'RP2040-LCD-1.28' in weiss
  • 23, 24: blaues Rechteck mit dem Text 'Waveshare'
  • 26-29: türkisfarbenes Rechteck mit den Werten des ACC-Sensors
  • 31-34: graues Rechteck mit den Werten des Gyro-Sensors
  • 36-38: cyanfarbenes Rechteck mit der Batteriespannung

  • Mit diesen Kenntnissen bauen wir jetzt das Display für den Schrittzähler auf. Aufgefallen ist, dass Farbhintergründe verwendet wurden, die in der 'init-Datei' gar nicht definiert wurden. Es lassen sich nämlich die hexadezimalen Werte auch direkt angeben. Z.B. beim Rechteck:

    LCD.fill_rect(xa,ya,xe,ye,0x1805)

    Aber auch bei den anderen Zeichenobjekten oder bei Text geht das. Beim Text hatte ich schon darauf hingewiesen, dass auch die Schriftgröße von 1 bis 3 veränderlich sein soll. Mit Hilfe von zwei Funktionen (printstring und printchar) wird aus der Anweisung

    LCD.text("Textstring",x0,y0,Farbe)

    die Anweisung

    printstring("Textstring",x0,y0,Größe,Farbe)

    Wenn Sie sich die [cmap] in der Datei 'font.py' ansehen, können auch deutsche Umlaute ä, ö, ü und ß dargestellt werden. Es werden dafür die Codes von Zeichen verwendet, die sonst wohl nicht gebraucht werden. Das Programm 'schrittzaehler.py' sieht bis hier dann so aus:

      
      
    
    1   from machine import Pin,I2C,SPI,PWM,ADC
    2   import framebuf
    3   import time
    4   import init_lcd_1_28
    5   import font
    6   import math
    7
    8   Vbat_Pin = 29
    9
    10  LCD = init_lcd_1_28.LCD_1inch28()
    11  LCD.set_bl_pwm(65535)
    12  qmi8658=init_lcd_1_28.QMI8658()
    13  Vbat= ADC(Pin(Vbat_Pin))
    14
    15  LCD.white    = 0xffff
    16  LCD.black    = 0x0000
    17  LCD.gray     = 0x0300
    18  LCD.darkgray = 0xc618
    19  LCD.red      = 0x07E0
    20  LCD.green    = 0x001f
    21  LCD.glade    = 0x0134
    22  LCD.blue     = 0xf800
    23  LCD.yellow   = 0xE0FF
    24  LCD.cyan     = 0x780F
    25  LCD.purple   = 0x7be0
    26  LCD.creme    = 0x7BEF
    27  LCD.beige    = 0xAFE5
    28  LCD.brown    = 0x8059
    29
    30  def printchar(letter,xpos,ypos,size,color):
    31      origin = xpos
    32      charval = ord(letter)
    33      index = charval-32
    34      character = font.cmap[index]
    35      rows = [character[i:i+5] for i in range(0,len(character),5)]
    36      for row in rows:
    37          for bit in row:
    38              if bit == '1':
    39                  LCD.pixel(xpos,ypos,color)
    40                  if size==2:
    41                      LCD.pixel(xpos,ypos+1,color)
    42                      LCD.pixel(xpos+1,ypos,color)
    43                      LCD.pixel(xpos+1,ypos+1,color)
    44                  if size==3:
    45                      LCD.pixel(xpos,ypos+1,color)
    46                      LCD.pixel(xpos,ypos+2,color)
    47                      LCD.pixel(xpos+1,ypos,color)
    48                      LCD.pixel(xpos+2,ypos,color)
    49                      LCD.pixel(xpos+1,ypos+1,color)
    50                      LCD.pixel(xpos+2,ypos+2,color)
    51              xpos+=size
    52          xpos=origin
    53          ypos+=size
    54
    55  def printstring(string,xpos,ypos,size,color):
    56      if size == 1:
    57          spacing = 8
    59          spacing = 14
    60      if size == 3:
    61          spacing = 22
    62      for i in string:
    63          printchar(i,xpos,ypos,size,color)
    64          xpos+=spacing
    65
      

    Hinweisen möchte ich noch einmal auf die Zeilen 10 bis 12. Dort wird das Display initialisiert und aus Bequemlichkeit habe ich in den Zeilen 15 bis 28 eine ganze Reihe an Farben definiert. Nachfolgend wird auch noch eine Funktion zur Darstellung eines Kreises definiert, der z.B. den Laufbalken für die Schritte abrundet. Zum Verständnis des weiteren Quelltextes geben die Kommentarzeilen entsprechend Aufschluss. Ergänzen Sie diesen Teil und schon kann das Experimentieren beginnen.

      
      
    
    66  def circle(x,y,r,c):
    67      LCD.hline(x-r,y,r*2,c)
    68      for i in range(1,r):
    69          a = int(math.sqrt(r*r-i*i))
    70          LCD.hline(x-a,y+i,a*2,c)
    71          LCD.hline(x-a,y-i,a*2,c)
    72
    73  current_time = time.localtime()
    74  hour = current_time[3]
    75  minute = current_time[4]
    76  second = current_time[5]
    77
    78  # Hintergrund
    79  LCD.fill(LCD.darkgray)
    80  LCD.fill_rect(0,130,240,120,LCD.creme)
    81  # Balken für Schritte
    82  circle(50,130,20,LCD.green)
    83  circle(190,130,20,LCD.glade)
    84  LCD.fill_rect(50,110,140,40,LCD.glade)
    85
    86  step = 3
    87  ziel = 8000
    88  wert = -1
    89  prozent = step / ziel * 100
    90
    91  while(True):
    92      #read QMI8658
    93      xyz=qmi8658.Read_XYZ()
    94      # Display wird x-Achse bewegt
    95      #wert_0 = (-2)*xyz[0]
    96      # Display wird y-Achse bewegt
    97      wert_1 = (-2)*xyz[1]
    98      # Display wird z-Achse bewegt
    99      wert_2 = (-2)*xyz[2]
    100     # Spannung in % anzeigen anzeigen
    101     LCD.rect(105,10,30,10,LCD.white)
    102     LCD.rect(135,12,2,5,LCD.white)
    103     LCD.fill_rect(107,12,24,6,LCD.glade)
    104     reading = Vbat.read_u16()*3.3/65535*2
    105     printstring(str(int(reading/4.5*100)) + "%",110,30,1,LCD.white)
    106     # Zeit anzeigen
    107     printstring("Trainingszeit:",30,55,2,LCD.beige)
    108     if second == 59:
    109         printstring(zeit,70,80,3,LCD.darkgray)
    110     current_time = time.localtime()
    111     hour = current_time[3]
    112     minute = current_time[4]
    113     second = current_time[5]
    114     zeit = str(hour) + ":" + str(minute)
    115     if minute < 10:
    116         zeit = str(hour) + ":0" + str(minute)
    117     printstring(zeit,70,80,3,LCD.white)
    118     # Sensorwert im Terminal sehen
    119     #print(wert_1,",",wert_2)
    120     if wert_2 > 2 or wert_1 > 1.8:
    121         # Laufbalken
    122         LCD.fill_rect(50,110,int(prozent*1.3),40,LCD.green)
    123         printstring(str(step-1) + "/" + str(ziel),65,155,2,LCD.creme)
    124         meter = int((step-1)*0.762)
    125         printstring("s="+str(meter)+"m",75,180,2,LCD.creme)
    126         cal = int(int((step-0.38)*0.38)*4.18)/1000
    127         printstring(str(cal)+"kJ",75,205,2,LCD.creme)
    128         #time.sleep(0.5)
    129         step += 1
    130         prozent = step / ziel * 100
    131         printstring(str(step) + "/" + str(ziel),65,155,2,LCD.black)
    132     printstring("Schritte",70,120,2,LCD.white)
    133     meter = int(step * 0.762)
    134     printstring("s="+str(meter)+"m",75,180,2,LCD.black)
    135     cal = int(int(step * 0.38)*4.18)/1000
    136     printstring(str(cal)+"kJ",75,205,2,LCD.black)
    137
    138     LCD.show()
    139     time.sleep(0.2)
      

    Mit dem Ergebnis der Experimente war ich noch nicht zufrieden. Z.B. wurden die Schritte in bestimmten Positionen auch im Ruhezustand weitergezählt. Außerdem hat sich für mich die Funktion des ACC-Sensors noch nicht voll erschlossen. Deshalb habe ich das Programm von der Inbetriebnahme (siehe weiter oben) noch einmal zur Hand genommen, um die Werte des Sensors in allen möglichen Positionen aufzunehmen. Dafür werden in entsprechenden Größen ACC_x, ACC_y und ACC_z angezeigt. Die gelesenen Werte werden zur besseren Weiterverarbeitung mit 10 multipliziert. Hier ist der Programmcode:

      
      
    
    1  from machine import Pin,I2C,SPI,PWM,ADC
    2  import framebuf
    3  import time
    4  import init_lcd_1_28
    5  import font
    6
    7  Vbat_Pin = 29
    8
    9  LCD = init_lcd_1_28.LCD_1inch28()
    10 LCD.set_bl_pwm(65535)
    11 qmi8658=init_lcd_1_28.QMI8658()
    12 Vbat= ADC(Pin(Vbat_Pin))
    13
    14 def printchar(letter,xpos,ypos,size,color):
    15     origin = xpos
    16     charval = ord(letter)
    17     index = charval-32
    18     character = font.cmap[index]
    19     rows = [character[i:i+5] for i in range(0,len(character),5)]
    20     for row in rows:
    21         for bit in row:
    22             if bit == '1':
    23                 LCD.pixel(xpos,ypos,color)
    24                 if size==2:
    25                     LCD.pixel(xpos,ypos+1,color)
    26                     LCD.pixel(xpos+1,ypos,color)
    27                     LCD.pixel(xpos+1,ypos+1,color)
    28                 if size==3:
    29                     LCD.pixel(xpos,ypos+1,color)
    30                     LCD.pixel(xpos,ypos+2,color)
    31                     LCD.pixel(xpos+1,ypos,color)
    32                     LCD.pixel(xpos+2,ypos,color)
    33                     LCD.pixel(xpos+1,ypos+1,color)
    34                     LCD.pixel(xpos+2,ypos+2,color)
    35             xpos+=size
    36         xpos=origin
    37         ypos+=size
    38
    39 def printstring(string,xpos,ypos,size,color):
    40      if size == 1:
    41         spacing = 8
    42     if size == 2:
    43         spacing = 14
    44     if size == 3:
    45         spacing = 22
    46     for i in string:
    47         printchar(i,xpos,ypos,size,color)
    48         xpos+=spacing
    49
    50 while(True):
    51     #read QMI8658
    52     xyz=qmi8658.Read_XYZ()
    53
    54     LCD.fill(LCD.white)
    55
    56     LCD.fill_rect(0,0,240,40,LCD.red)
    57     LCD.text("RP2040-LCD-1.28",60,25,LCD.white)
    58
    59     LCD.fill_rect(0,40,240,40,LCD.blue)
    60     LCD.text("Waveshare",80,57,LCD.white)
    61
    62     LCD.fill_rect(0,80,240,120,0x1805)
    63     printstring("ACC_X={:+.2f}".format(10*xyz[0]),20,100-3,2,LCD.white)
    64     printstring("ACC_Y={:+.2f}".format(10*xyz[1]),20,140-3,2,LCD.white)
    65     printstring("ACC_Z={:+.2f}".format(10*xyz[2]),20,180-3,2,LCD.white)
    66     LCD.fill_rect(0,200,240,40,0x180f)
    67     reading = Vbat.read_u16()*3.3/65535*2
    68     LCD.text("Vbat={:.2f}".format(reading),80,215,LCD.white)
    69     LCD.show()
    70     time.sleep(0.1)
      

    Als Ergenis ist eine Übersicht für die unterschiedlichen Positionen, wie das Display gehalten werden kann, herausgekommen, die ich in einer pdf-Datei gespeichert habe. Diese kann als pdf-Datei angesehen oder heruntergeladen werden. Ich hoffe, dass damit auch vielen anderen Usern weitergeholfen werden kann.

    Mit dieser weiterreichenden Erkenntnis habe ich dann das Programm ab der Variablendefinition in Zeile 86 wie folgt geändert bzw. ergänzt.

      
      
    
    86  zeit = ""
    87  step = 1
    88  stepstop = 0
    89  start = 0
    90  ziel = 8000
    91  wert = -1
    92  prozent = step / ziel * 100
    93
    94  while(True):
    95      #read QMI8658
    96      xyz=qmi8658.Read_XYZ()
    97      # Display wird rel. zur x-Achse bewegt
    98      wert_x = (10)*xyz[0]
    99      # Display wird rel. zur y-Achse bewegt
    100     wert_y = (10)*xyz[1]
    101     # Display wird rel. zur z-Achse bewegt
    102     wert_z = (10)*xyz[2]
    103     # Spannung in % anzeigen anzeigen
    104     LCD.rect(105,10,30,10,LCD.white)
    105     LCD.rect(135,12,2,5,LCD.white)
    106     LCD.fill_rect(107,12,24,6,LCD.glade)
    107     reading = Vbat.read_u16()*3.3/65535*2
    108     printstring(str(int(reading/4.5*100)) + "%",110,30,1,LCD.white)
    109     # Zeit anzeigen
    110     printstring("Trainingszeit:",30,55,2,LCD.beige)
    111     if second == 59:
    112         printstring(zeit,70,80,3,LCD.darkgray)
    113     current_time = time.localtime()
    114     hour = current_time[3]
    115     minute = current_time[4]
    116     second = current_time[5]
    117     zeit = str(hour) + ":" + str(minute)
    118     if minute < 10:
    119         zeit = str(hour) + ":0" + str(minute)
    120     printstring(zeit,70,80,3,LCD.white)
    121     #
    122     # Arm noch oben bewegen
    123     #
    124     if (abs(wert_x) < 7 and abs(wert_y) > 3 or abs(wert_x) < 7 and abs(wert_z) > 3) and stepstop == 0:
    125     #if (abs(wert_x) < 7 and abs(wert_y) > 3) and stepstop == 0:
    126     #if (abs(wert_x) < 7 and abs(wert_z) > 3) and stepstop == 0:
    127         start = time.ticks_ms()
    128         step += 1
    129         stepstop = 1
    130         # Laufbalken
    131         LCD.fill_rect(50,110,int(prozent*1.3),40,LCD.green)
    132         printstring(str(step-1) + "/" + str(ziel),65,155,2,LCD.creme)
    133         meter = int((step-1)*0.762)
    134         printstring("s="+str(meter)+"m",75,180,2,LCD.creme)
    135         cal = int(int((step-0.38)*0.38)*4.18)/1000
    136         printstring(str(cal)+"kJ",75,205,2,LCD.creme)
    137         prozent = step / ziel * 100
    138         printstring(str(step) + "/" + str(ziel),65,155,2,LCD.black)
    139         printstring("Schritte",70,120,2,LCD.white)
    140         meter = int(step * 0.762)
    141         printstring("s="+str(meter)+"m",75,180,2,LCD.black)
    142         cal = int(int(step * 0.38)*4.18)/1000
    143         printstring(str(cal)+"kJ",75,205,2,LCD.black)
    144     #
    145     # Arm wieder nach unten
    146     #
    147     if (abs(wert_x) > 7 and abs(wert_y) < 3 or abs(wert_x) > 7 and abs(wert_z) < 3) and stepstop == 1:
    148     #if (abs(wert_x) > 7 and abs(wert_y) < 3) and stepstop == 1:
    149     #if (abs(wert_x) > 7 and abs(wert_z) < 3) and stepstop == 1:
    150         if (time.ticks_ms() - start)> 1000:
    151             stepstop = 0
    152     LCD.show()
    153     time.sleep(0.2)
      



    Ich habe für die Bewegung zwei Richtungen gewählt, so als wenn man z.B. eine Fitnessuhr seitlich am Arm schwenkt oder den Arm nach vorn und hinten bewegt. Mit der so erreichten Funktionsweise kann ich leben. Wenn Sie die Anleitung nachvollziehen, rechnen Sie damit, dass die Sensoren eine gewisse Streuung haben und Sie nicht genau identische Werte bekommen. Aber die Tendenz sollte schon gleich sein.
    In der jetzigen Version wird auch nur noch gezählt, wenn eine Bewegung erfolgt und es ist jedes Mal eine Rückbewegung quasi in die Ausgangsrichtung erforderlich, bevor erneut ein Schritt gezählt wird. Dies erledigt die Variable 'stepstop'. Die Uhrzeit wird noch mit 'localtime()' bestimmt. Das geht natürlich nur, wenn das Gerät am PC angeschlossen ist. Geht auch anders, weiss ich, aber hier und jetzt noch nicht. Ist das Gerät an der Powerbank angeschlossen, zeigt es eben die 'Trainingszeit' bei Null angefangen an. Probieren Sie ein wenig mit dem Programm herum und lernen dabei das Display kennen. Genau das war nämlich das Anliegen dieser Anleitung.


    Viel Spass und Erfolg beim Ausprobieren.