Code: Alles auswählen
def gestureDataProcess(self, gestureData, gestureDataCount): # returns the gesture value
Gesture_Vertical = 0
Gesture_Horizontal = 0
for i in range((gestureDataCount-5), (gestureDataCount-1)):
print('GestureData (U-D-L-R) Nr.', i, '=', gestureData[i][0], gestureData[i][1], gestureData[i][2], gestureData[i][3])
Gesture_Vertical += gestureData[i][0] - gestureData[i][1] # U-D
Gesture_Horizontal += gestureData[i][2] - gestureData[i][3] # L-R
# print('Horizontal=', Gesture_Horizontal, ', Vertical=', Gesture_Vertical)
if abs(Gesture_Vertical) > abs(Gesture_Horizontal):
if Gesture_Vertical < 0: # U-D > 0
gesture = self.gesture_FORWARD # local
else:
gesture = self.gesture_BACKWARD
else:
if Gesture_Horizontal > 0: # L-R > 0
gesture = self.gesture_TO_RIGHT
else:
gesture = self.gesture_TO_LEFT
return gesture
Nun wertet die Methode gestureDataProcess diese 4 UDLR-Sets aus; dabei richtet sie sich nach dem rechten Teil der folgenden Tabelle:
Diese wurde bereits in dem oben erwähnten Beitrag hinreichend erläutert. Das Ergebnis dieser Analyse wird schließlich in Form eines Gesten-Wertes zwischen 0 und 3 zurückgegeben:
gesture_FORWARD = 0
gesture_BACKWARD = 1
gesture_TO_RIGHT = 2
gesture_TO_LEFT = 3
Das gesamte Programm zur Gestenerkennung sieht dann folgendermaßen aus:
Code: Alles auswählen
# APDS9960_Gesture.py
# Das Modul APDS9960.py basiert auf dem APDS9960-Modul von Rune Langøy und wurde
# mit Hilfe von https://subscription.packtpub.com/book/iot-&-hardware/9781789958034/7/ch07lvl1sec62/constructing-the-gesture-controller
# für die Gestenerkennung erweitert.
# Ausgabe der Geste durch Pfeile auf dem Display des TTGO
import gc
gc.enable()
gc.collect()
import machine
from time import sleep_ms
import APDS9960
import utime
import st7789
spi = machine.SPI(1, baudrate=20000000, polarity=1, sck=machine.Pin(18), mosi=machine.Pin(19))
display = st7789.ST7789(spi, 135, 240, reset=machine.Pin(23, machine.Pin.OUT), cs=machine.Pin(5, machine.Pin.OUT), dc=machine.Pin(16, machine.Pin.OUT), backlight=machine.Pin(4, machine.Pin.OUT), rotation=3)
display.init()
display.fill(0)
# Funktion zum Zeichnen der Pfeile:
def pfeil(direction): # gesture_FORWARD = 0; gesture_BACKWARD = 1; gesture_TO_RIGHT = 2; gesture_TO_LEFT = 3;
poly_liste = 4*[0]
poly_liste[0] = [(0,30), (-20,30), (-20,0), (-40,0), (0,-30), (40,0), (20,0), (20,30), (0,30)]
poly_liste[1] = [(0,-30), (-20,-30), (-20,0), (-40,0), (0,30), (40,0), (20,0), (20,-30), (0,-30)]
poly_liste[2] = [(-30,0), (-30,-20), (0,-20), (0,-40), (30,0), (0,40), (0,20), (-30,20), (-30,0)]
poly_liste[3] = [(30,0), (30,-20), (0,-20), (0,-40), (-30,0), (0,40), (0,20), (30,20), (30,0)]
display.fill_polygon(poly_liste[direction], 120, 70, st7789.RED)
# I2C und APDS9960-Modul initialisieren:
i2c = machine.I2C(1, sda=machine.Pin(22), scl=machine.Pin(21))
apds9960=APDS9960.APDS9960(i2c) # apds9960 instanziieren
g = apds9960.gesture
p = apds9960.prox
# Initialisierung der Gesture-Parameter:
g.enableSensor() # GEN: Gesture Enable
p.enableSensor() # PEN: Proximity Enable
p.eProximityGain = 3 # maximale Verstärkung
g.gain = 3
g.waitTime = 0
# Thresholds festlegen
PROXIMITY_THRESHOLD_COUNT = 40 # Proximity-Sensor aktiviert GMODE
g.GEntry = PROXIMITY_THRESHOLD_COUNT # aktiviert GMODE automatisch gemäß Datasheet S. 16 links oben (wenn PDATA > GPENTH)
GESTURE_EXIT_THRESHOLD_COUNT = 30
g.GExit = GESTURE_EXIT_THRESHOLD_COUNT # setzt GMODE zurück, wenn alle 4 Bytes eines Data-Sets unter GEXTH sind
gestureDetectedTime = utime.ticks_ms()
gestureDetected = False
g.gestureDataClear()
while True:
# result = g.detect(printOn = True) # Gestenwerte detektieren/auswerten und sämtliche U-D-L-R-Sets am Terminal ausgeben
result = g.detect() # Gestenwerte detektieren/auswerten ohne Ausgabe sämtliche U-D-L-R-Sets
if result == g.gesture_TO_LEFT:
gestureDetected = True
gestureDetectedTime = utime.ticks_ms()
print('Nach Links')
print()
pfeil(g.gesture_TO_LEFT)
elif result == g.gesture_TO_RIGHT:
gestureDetected = True
gestureDetectedTime = utime.ticks_ms()
print('Nach Rechts')
print()
pfeil(g.gesture_TO_RIGHT)
elif result == g.gesture_FORWARD:
gestureDetected = True
gestureDetectedTime = utime.ticks_ms()
print('Vorwärts')
print()
pfeil(g.gesture_FORWARD)
elif result == g.gesture_BACKWARD:
gestureDetected = True
gestureDetectedTime = utime.ticks_ms()
print('Rückwärts')
print()
pfeil(g.gesture_BACKWARD)
# nach 1,5 Sekunden ohne neue Geste zurücksetzen und Display löschen...
if (utime.ticks_ms() - gestureDetectedTime) > 1500:
gestureDetected = False
display.fill(0)
gc.collect()
sleep_ms(20)
Einige Erläuterungen sind noch erforderlich:
- Das Programm gibt den Gestentyp sowohl als Text (mit einigen zusätzlichen Informationen) auf dem Terminal als auch in Form eines Pfeils auf dem Display des TTGO an.
- Eine neue Geste sollte erst dann erfolgen, wenn der Pfeil auf den Display verschwindet; das ist 1,5 Sekunden nach dem Erfassen der vorangegangenen Geste.
- Wenn Sie kein Display einsetzen können oder wollen, löschen Sie die entsprechenden Befehle für das Display oder kommentieren Sie sie aus.
- In dem Programm benutzen wir die High-Level-Methode detect der Gesture-Klasse. Diese funktioniert fast genauso wie die Funktion detect, welche in dem oben erwähnten Beitrag schon ausführlich vorgestellt wurde. Der wesentliche Unterschied besteht darin, dass g.detect selbst schon die High-Level-Methode g.gestureDataProcess aufruft. Das Ergebnis dieser Gestenanalyse wird dann von g.detect als Rückgabewert benutzt. Mit anderen Worten: g.detect() erledigt sowohl das Erfassen der Gesten-Daten als auch die Analyse dieser Daten.
In der Anlage finden Sie:
- das Modul APDS9960.py
- das Programm APDS9960_Gesture.py zur Gestenerkennung
- Ein kurzes Video, welches den TTGO beim Erkennen von Gesten zeigt
.