elektronische Wasserwaage
(spirit level)
- 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
elektronische Wasserwaage
(spirit level)
- 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
In dieser Anleitung geht es um die Nutzung des ACC-Sensors. Um eine waagerechte Fläche zu bestimmen, kommt es z.B. bei einer Wasserwaage
auf die Ausrichting in x-y-Richtung bezüglich des Koordinatensystems an. Eine kleine Wasserblase bewegt sich dabei in einem Glasröhrchen,
einer s.g. Libelle. Das werden wir auf unserem Display nachzubauen.
Los gehts
Zunächst installieren Sie die Firmware Micropython auf dem Pico-Display und speichern wie im vorigen Projekt (Inbetriebnahme und Schrittzähler) die beiden Dateien 'init_lcd_1_28.py' und 'font.py' (Download hier) auf dem Pico-Laufwerk. Diese beiden Dateien importieren wir in unser Programm 'wasserwaage.py' und haben es so von einer Vielzahl Programmzeilen befreit, welche die Übersichtlichkeit nicht gerade verbessern. Damit sieht das Programm bisher 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 import random 8 9 Vbat_Pin = 29 10 11 LCD = init_lcd_1_28.LCD_1inch28() 12 LCD.set_bl_pwm(65535) 13 qmi8658=init_lcd_1_28.QMI8658() 14 Vbat= ADC(Pin(Vbat_Pin)) 15 16 LCD.white = 0xffff 17 LCD.black = 0x0000 18 LCD.gray = 0x0300 19 LCD.darkgray = 0xc618 20 LCD.red = 0x07E0 21 LCD.green = 0x001f 22 LCD.glade = 0x0134 23 LCD.blue = 0xf800 24 LCD.yellow = 0xE0FF 25 LCD.cyan = 0x780F 26 LCD.purple = 0x7be0 27 LCD.creme = 0x7BEF 28 LCD.beige = 0xAFE5 29 LCD.brown = 0x8059 30
Die Zeilen 9 und 14 hätte wegfallen können, da die Spannung nicht ausgelesen werden soll. Aber wichtig sind die Zeilen 11 bis 13, da hier das Display und der Sensor initialisiert werden. In den Zeilen 16 bis 29 werden eine Reihe Farben definiert. Es folgen die Programmzeilen 31 bis 73.
31 def printchar(letter,xpos,ypos,size,color): 32 origin = xpos 33 charval = ord(letter) 34 index = charval-32 35 character = font.cmap[index] 36 rows = [character[i:i+5] for i in range(0,len(character),5)] 37 for row in rows: 38 for bit in row: 39 if bit == '1': 40 LCD.pixel(xpos,ypos,color) 41 if size==2: 42 LCD.pixel(xpos,ypos+1,color) 43 LCD.pixel(xpos+1,ypos,color) 44 LCD.pixel(xpos+1,ypos+1,color) 45 if size==3: 46 LCD.pixel(xpos,ypos+1,color) 47 LCD.pixel(xpos,ypos+2,color) 48 LCD.pixel(xpos+1,ypos,color) 49 LCD.pixel(xpos+2,ypos,color) 50 LCD.pixel(xpos+1,ypos+1,color) 51 LCD.pixel(xpos+2,ypos+2,color) 52 xpos+=size 53 xpos=origin 54 ypos+=size 55 56 def printstring(string,xpos,ypos,size,color): 57 if size == 1: 58 spacing = 8 59 if size == 2: 60 spacing = 14 61 if size == 3: 62 spacing = 22 63 for i in string: 64 printchar(i,xpos,ypos,size,color) 65 xpos+=spacing 66 67 def circle(x,y,r,c): 68 LCD.hline(x-r,y,r*2,c) 69 for i in range(1,r): 70 a = int(math.sqrt(r*r-i*i)) 71 LCD.hline(x-a,y+i,a*2,c) 72 LCD.hline(x-a,y-i,a*2,c) 73
Mit den beiden Funktionen 'printchar(letter,xpos,ypos,size,color)' und 'printstring(string,xpos,ypos,size,color)' wird der Micropython Befehl 'LCD.text(string,xpos,ypos,color)' ersetzt, um Text mit Hilfe der Zeichensatztabelle in der Datei 'font.py' in drei Schriftgrößen darzustellen. Da Micropython standartmäßig keine Kreise darstellt, werden die durch die Funktion 'circle(xpos,ypos,radius,color)' in den Zeilen 67 bis 72 realisiert. Wenn Sie nun die Zeilen 74 bis 94 eingeben, können Sie sehen, wie der Hintergrund aufgebaut wird, welcher von Zeile 93 aufgerufen wird.
74 def background(): 75 # Hintergrund 76 LCD.fill(LCD.glade) 77 LCD.fill_rect(0,180,240,140,LCD.beige) 78 LCD.fill_rect(0,120,240,140,LCD.beige) 79 circle(120,120,115,LCD.darkgray) 80 LCD.fill_rect(0,180,240,140,LCD.beige) 81 printstring("spirit level",40,185,2,0x000000) 82 printstring("by Pico",70,205,2,0x000000) 83 LCD.fill_rect(0,0,240,60,LCD.glade) 84 #LCD.line(0,120,20,120,LCD.green) 85 #LCD.line(220,120,240,120,LCD.green) 86 LCD.show() 87 88 xpos= 120 89 ypos= 120 90 radius = 120 91 a = 0 92 93 background() 94
Jetzt folgt die 'while' Schleife, in der zuerst der Sensor gelesen wird und je nach Achse einem Wert zugeordnet wird (Zeilen 97 bis 103).
In den Zeilen 104 bis 115 wird die 'Libelle' in dem sich gleich die 'Wasserblase bewegt dargestellt. Diese Zeilen befinden sich nicht in
der Funktion für den Hintergrund, da die 'Libelle' jedes Mal neu angezeigt werden muss, wenn sich die 'Wasserblase' darüber bewegt
hat.
Das Ausdrucken der x- und y-Werte in Zeile 116 ist in der Testphase sinnvoll, damit man die Sensorwerte besser versteht. Entsprechende Anpassungen
der Werte können in den Zeilen 117 bis 131 vorgenommen werden. Auch die Multiplikation mit 5 bei den gelesenen Sensorwerten in Zeile
99 und 101 dient der Kalibrierung.
95 while(True): 96 #read QMI8658 97 xyz=qmi8658.Read_XYZ() 98 # Display wird rel. zur x-Achse bewegt 99 wert_x = (5)*xyz[0] 100 # Display wird rel. zur y-Achse bewegt 101 wert_y = (5)*xyz[1] 102 # Display wird rel. zur z-Achse bewegt 103 #wert_z = (5)*xyz[2] 104 printstring("Messung",80,20,2,0xffffff) 105 printstring("aktiv",90,40,2,0xffffff) 106 LCD.show() 107 circle(xpos,ypos,20,LCD.darkgray) 108 circle(120,120,50,LCD.glade) 109 circle(120,120,48,LCD.darkgray) 110 LCD.line(50,120,100,120,LCD.green) 111 LCD.line(140,120,190,120,LCD.green) 112 LCD.line(120,60,120,100,LCD.green) 113 LCD.line(120,140,120,180,LCD.green) 114 circle(120,120,24,LCD.glade) 115 circle(120,120,22,LCD.darkgray) 116 print(wert_x,",",wert_y) 117 # Bewegung hoch 118 if wert_x > 0.15 and wert_y < 0.15: 119 ypos = ypos - 2 120 if ypos < 80: 121 ypos = 80 122 # Bewegung runter 123 if wert_x < - 0.15 and wert_y > - 0.15: 124 ypos = ypos + 2 125 if ypos > 160: 126 ypos = 160 127 # Bewegung rechts/links 128 if wert_x > - 0.15 and wert_y < - 0.15: 129 xpos = xpos -2 130 if wert_x > - 0.15 and wert_y > 0.15: 131 xpos = xpos + 2 132 b= random.randint(-2,1) 133 circle(xpos,ypos,20,LCD.beige) 134 circle(xpos,ypos,19,LCD.creme) 135 circle(xpos+b,ypos-2*b,6,LCD.beige) 136 circle(xpos+b,ypos-b,6,LCD.white) 137 time.sleep(0.01) 138 a+= 1 139 if a==30: 140 printstring("Messung",80,20,2,0x0134,) 141 printstring("aktiv",90,40,2,0x0134) 142 printstring("Messung",80,20,2,0xffffff) 143 printstring("in 2 sec",70,40,2,0xffffff) 144 LCD.show() 145 time.sleep(2) 146 xpos= 120 147 ypos= 120 148 radius = 120 149 a = 0 150 background() 151 LCD.show()
Damit die Wasserblase noch ein wenig 'lebendiger' wirkt, wird sie in den Zeilen 132 bis 137 per Zufallswert animiert. Nach 30 Messzyklen
wird eine Pause eingelegt und das Display neu angezeigt. In der aktiven Zeit kann die Bewegung der Blase schon bei einer leichten Neigung
beobachtet werden. Das heißt, wenn sie ruhig in der Mitte bleibt, befindet sich die Ebene unter dem Display in der Waage.
Durch ein kleines Gehäuse aus dem 3D Drucker steigert sich der Nutzwert dann noch einmal deutlich. Sie können sich die stl-Datei
hier herunterladen und selbst ausdrucken.
Schauen Sie sich auch das kurze Video zur Funktion der elektronischen Wasserwaage an.
Viel Spass und Erfolg beim Ausprobieren.
zurück zur Übersicht
Schauen Sie sich auch das kurze Video zur Funktion der elektronischen Wasserwaage an.
Viel Spass und Erfolg beim Ausprobieren.
zurück zur Übersicht