sensor

3. LAGESENSOR

 

 

DU LERNST HIER...

 

wie du mit dem Lagesensor Lageänderungen und Bewegungen des Calliope erfassen kannst.

 

 

SENSORWERTE

 

Der Lagesensor (Beschleunigungssensor) misst sowohl die konstante Erdbeschleunigung von rund 10 m/s2, die vertikal nach unten zeigt, als auch die Beschleunigungen, die durch Bewegungen zustande kommen.

Der Lagesensor ist auf dem Board gut sichtbar. Ähnliche Sensoren sind auch in den meisten Smartphones eingebaut.

Der Sensor misst die x-, y, und z-Komponente der Beschleunigung, aus welchen die Vorwärtsneigung (Pitch) und Seitwärtsneigung (Roll) berechnet werden kann.

 

Es ist ähnlich wie bei der Lageanzeige von Flugzeugen, die mit einem künstlichen Horizont angezeigt werden. Wenn man das Board nach vorne oder nach hinten neigt, ändert der Pitch-Winkel, bei der Seitwärtsneigung ändert der Roll-Winkel.

Im folgendem Programm verwendest du die Befehle accelerometer.get_x(), accelerometer.get_y() oder accelerometer.get_z() , die Werte im Bereich von ungefähr -2000 bis 2000 liefern (entspricht den Beschleunigungen -20 m/s2 bis 20 m/s2). Mit acceloremeter.get_values() erhältst du alle drei Werte in einem Tupel zurück.

Wenn die z-Achse senkrecht nach unten zeigt, muss der Wert der Erdbeschleunigung, also 9.81 m/s2 gemessen werden. Der Sensor gibt bei az umgefähr 981 zurück.

from calliope_mini import *

while True:
    ax = accelerometer.get_x()
    ay = accelerometer.get_y()
    az = accelerometer.get_z()
    a = accelerometer.get_values()
    print(ax, ay, az, a)
    sleep(500)
► In Zwischenablage kopieren

 

 

MUSTERBEISPIELE

 
Sensorwerte abfragen

Starte das unten stehende Programm, kippe den Calliope um den USB-Anschluss links und rechts und beobachte dabei die Sensorwerte, die mit print(acc) im Terminalfenster angezeigt werden.

Auf dem Display wird bei einem positiven Wert der Pfeil ARROW_E und bei einem negativen Wert der Pfeil ARROW_W angezeigt.


 
from calliope_mini import *

while True:
    acc = accelerometer.get_x()
    print(acc)
    if acc > 0:
        display.show(Image.ARROW_E)
    else:
        display.show(Image.ARROW_W)
    sleep(100)  
► In Zwischenablage kopieren

 

Wasserwaage-Libelle

 
Der Calliope soll wie eine Wasserwaage-Libelle funktionieren. Dabei verwendest du die Tatsache, dass die x- und y-Komponenten der Beschleunigungen ungefähr 0 sind, wenn sich das Board in waagrechter Lage befindet.
 


Es wird nur ein Pixel angezeigt, das sich je nach Neigung nach rechts, links, oben oder unten verschiebt. Ziel ist es, die Libelle so auszurichten, dass die mittlere LED leuchtet.

Im Programm verwendest du vier Bedingungen,  um den x- und y-Wert des Pixels zu bestimmen und löschst dann das Pixel bevor du das neue anzündest.

from calliope_mini import *

x = 1
y = 1

while True:
    accX = accelerometer.get_x()
    accY = accelerometer.get_y() 
    if accX > 100 and y < 4:
        y += 1
    elif accX < -100 and y > 0:
        y -= 1
    elif accY > 100 and x < 4:
        x += 1
    elif accY < -100 and x > 0:
        x -= 1
    display.clear()
    display.set_pixel(x, y, 9)
    sleep(100)
► In Zwischenablage kopieren

Pitch und Roll

Im Modul cputils befinden sich zwei Funktionen, die aus der Beschleunigunskomponenten Pitch bzw. Roll berechnen.

Du verwendest in deinem Programm die Funktion getRoll(), die den Rollwinkel in Grad zurückgibt und machst die Rollposition auf dem Display sichtbar. Drehst du den Calliope nach rechts, so erscheint auf dem Display ein Rechtspfeil, drehst du ihn nach links, erscheint ein Linkspfeil.

 

from calliope_mini import *
from math import*

def getRoll(a):
    anorm = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])
    roll = asin(a[0] / anorm)
    return int(degrees(roll))

while True:
    a = accelerometer.get_values()
    roll = getRoll(a)
    print(roll)
    if roll >= 0:
        display.show(Image.ARROW_N)
    if roll <= 0:
        display.show(Image.ARROW_S)
    sleep(0.3)
► In Zwischenablage kopieren

 

 

MERKE DIR...

 

Mit dem Beschleunigungssensor kannst du die Bewegungen und die Lage des Calliope erfassen. Meist werden die Sensorwerte in einer Messschleife regelmässig alle 10 - 100 Millisekunden abgefragt. Man nennt dies auch Pollen der Sensorwerte.

 

 

ZUM SELBST LÖSEN

 

 

1.
Ergänze das erste Beispiel so, dass auch die Drehung des Calliope in der y-Richtung gemessen und mit den passenden Pfeilen Image.ARROW_N, bzw.Image.ARROW_S angezeigt wird. Beachte, dass die Werte nicht eindeutig < 0 bzw. < 0 ausfallen. Eine Möglichkeit ist es., die passenden Pfeile anzuzeigen, wenn der Sensorwert < 100 bzw. < -100 ist. Dann kannst du den Calliope eideutig in einer Richtung kippen.

2.

Durch Kippen des Calliope sollen alle Pixel am Rand einzeln eingeschaltet werden.

 

 

3.

Du willst das "Schütteln" des Calliope messen. Dazu holst du mit a = accelerometer.get_values() die Beschleunigungskomponenten, betrachtest aber nur den Betrag b der x- und  y-Komponenten, der sich wie folgt berechnet

b = √ a[0] * a[0] + a[1] * a[1]

a) Schreibe im Terminalfenster den Betrag in einer Endlosschleife 50x pro Sekunde aus.

b) Führe nach Start des Programm die Messungen nur während 1 Sekunde aus und schreibe das Maximum von b aus.

c) Schreibe das Maximum als Integer auf dem Display aus (als Scrolltext).
Anleitung: Um aus b einen Integer zu machen, verwendest du n = int(b). Für den Display musst du daraus mit s = str(n) einen String (Text) machen.

d) Mache daraus ein "Schüttelspiel", bei dem derjenige gewinnt, der am stärksten schüttelt. Die Messung soll aber erst beim Erscheinen das Zeichens > nach einer zufälligen Zeit von 3-6 Sekunden beginnen und man darf vorher nicht bereits schütteln.

 
     

 

 

 

3-1
Fachliche Hinweise:

Unter der Beschleunigung versteht man allgemein die Änderungsrate  der Geschwindigkeit, eindimensional also

wo v die Geschwindigkeit ist.

3-2
Fachliche Hinweise:

Aus den drei Beschleunigungskomponenten kannst du die Winkel Pitch und Roll berechnen.

def getPitch(a):
    pitch = atan2(a[1], a[2])
    return int(degrees(pitch))

def getRoll(a):
    anorm = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])
    roll = asin(a[0] / anorm)
    return int(degrees(roll))