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 eine Achse senkrecht nach unten zeigt, muss der Wert der Erdbeschleunigung, also 9.81 m/s2 gemessen, also umgefähr 981 zurückgegeben werden.

Programm:

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 bit ausgehend von der horizontalen Lage gegen USB-Anschluss bzw. gegen RGB-LED und beobachte dabei die Sensorwerte, die im Terminalfenster ausgeschrieben werden.

Im Programm fragst du einer Endlosschleife die Beschleunigung in x-Richtung alle 100 Millisekunden ab und schreibst sie mit print(acc) im Terminalfenster aus. Zudem zeigst du auf dem Display bei einem positiven Wert einen Pfeil ARROW_N und bei einem negativen Wert einen Pfeil ARROW_S.
 

Programm:

from calliope_mini import *

while True:
    acc = accelerometer.get_x()
    print(acc)
    if acc > 0:
        display.show(Image.ARROW_N)
    else:
        display.show(Image.ARROW_S)
    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.

Programm:

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.

 

Programm:

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.

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))