**Dies ist eine alte Version des Dokuments!**
Microbit mit Maqueen programmieren
Auf dieser Seite lernst du die wichtigsten Funktionen kennen, um mit dem Microbit das Fahrwerk Maqueen zu steuern. Du kannst den Microbit einfach in den dafür vorgesehenen Steckplatz stecken. Sobald du den Schalter hinten am Fahrwerk auf On stellst, wird der Microbit mit Strom versorgt.
Motoren ansteuern
Die beiden Räder des Maqueen-Fahrwerks werden von je einem Motor angetrieben. Die beiden Motoren werden über einen Motor Controller (MC) gesteuert:
Über zwei Leitungen (Pins zwischen „3V“ und „GND“) ist der Microbit mit dem Motor-Controller (MC) verbunden: Diese beiden Leitungen dienen der Kommunikation über die sogenannte I2C-Schnittstelle (I2C). Das ist eine serielle Schnittstelle, ähnlich wie USB. Auf diesem Weg sendet der Microbit dem Motor-Controller (MC) Befehle. Damit das funktioniert, muss der Microbit erst nach dem Motor-Controller suchen. Folgender Code ist dazu nötig:
i2cAddr = 16 # Adresse des Motor-Controllers while i2cAddr not in i2c.scan(): display.show(Image.SAD) display.show(Image.HAPPY)
Obiger Code ruft die Funktion i2c.scan()
so lange auf, bis der Motor-Controller an seiner Adresse gefunden wurde. Während der Suche wird ein Sad Face angezeigt; nach (erfolgreicher) Suche wird ein Happy Face angezeigt.
Jetzt können über I2C einzelne Nachrichten an die Adresse des Motor-Controllers gesendet werden. In diesen Nachrichten können wir dem MC mitteilen:
- welcher Motor drehen soll,
- in welche Richtung dieser drehen soll und
- wie schnell er drehen soll.
Folgende Funktion sendet abgängig von den Parametern die richtigen Nachrichten:
def motor_run(motors=0, direction=0x00, speed=0): # direction: 0 = forward, 1 = backward # speed range: 0...255 i2cBuf = bytearray([motors, direction, speed]) if motors == 0: # left motor i2cBuf[0] = 0x00 i2c.write(i2cAddr, i2cBuf) if motors == 1: # right motor i2cBuf[0] = 0x02 i2c.write(i2cAddr, i2cBuf) if motors == 2: # both motors i2cBuf[0] = 0x00 i2c.write(i2cAddr, i2cBuf) i2cBuf[0] = 0x02 i2c.write(i2cAddr, i2cBuf)
Du musst nicht jede Zeile dieser Funktion verstehen. Wichtig ist, dass du sie richtig verwendest: Hier eine kurze Übersicht:
- Mit dem Parameter
motors
wählst du die Motoren:- 0 für den linken Motor
- 1 für den rechten Motor
- 2 für beide Motoren
- Mit dem Parameter
direction
wählst du die Richtung:- 0 für vorwärts,
- 1 für rückwärts.
- Mit dem Parameter
speed
wählst du die Geschwindigkeit:- von 0 (stillstehend) bis 255 (schnell).
Wenn du zum Beispiel willst, dass der linke Motor mit der Geschwindigkeit 200 rückwärts dreht, dann rufst du die Funktion wie folgt auf:
motor_run(0, 1, 200)
Probiere es aus:
- Kopiere obige Code-Zeilen für die Suche nach dem Motor-Controller.
- Kopiere dann die Zeilen für die Definition der Funktion
motor_run
- Ergänze den Code so, dass Maqueen vorwärts fahren und stoppen kann:
- Wenn du Taste A drückst, soll Maqueen mit geringer Geschwindigkeit (50) vorwärts fahren.
- Wenn du Taste B drückst, soll Maqueen stoppen.
Aufgaben F
Aufgaben F1
Schreibe ein Programm, mit dem Maqueen möglichst schnell einen Halbkreis mit möglichst kleinem Radius fährt, sobald du die Taste A drückst.
Aufgaben F2
Speichere dein Programm aus Aufgabe F1 unter neuem Namen und erweitere es:
- Schreibe eine Funktion – zum Beispiel namens
turn(angle)
– die Maqueen um einen beliebigen Winkel dreht. Zum Beispiel:- Mit dem Aufruf
turn(90)
soll Maqueen um 90° nach rechts drehen, dann stoppen. - Mit dem Aufruf
turn(-120)
soll Maqueen um 120° nach links drehen, dann stoppen. - Mit dem Aufruf
turn(196)
soll Maqueen um 196° nach rechts drehen, dann stoppen. - etc.
Aufgaben F3
Speichere dein Programm aus Aufgabe F2 unter neuem Namen und erweitere es:
- Schreibe eine Funktion – zum Beispiel namens
drive(distance)
– die Maqueen um eine beliebige Strecke geradeaus fahren lässt. Zum Beispiel:- Mit dem Aufruf
drive(20)
soll Maqueen um 20 cm vorwärts fahren, dann stoppen. - Mit dem Aufruf
drive(-10)
soll Maqueen um 10 cm rückwärts fahren, dann stoppen. - Mit dem Aufruf
drive(13)
soll Maqueen um 13 cm vorwärts fahren, dann stoppen. - etc.
Aufgaben F4
Baue mit ca. vier Gegenständen eine kleine Slalom-Strecke. Speichere dein Programm aus Aufgabe F3 unter neuem Namen und erweitere es:
- Schreibe ein Programm, mit dem Maqueen die Slalom-Strecke (links vorbei, rechts vorbei etc.) fährt.
- Dazu misst du erst deine Strecke aus und planst eine Route, die du mit den Funktionen
turn()
unddrive()
programmieren kannst. - Sobald du Taste A drückst, soll Maqueen die Route abfahren.
- Programmiere, teste und optimiere dein Programm.
Ultraschall-Sensor auslesen
Wenn du den Ultraschall-Sensor auf das Maqueen-Fahrwerk steckst, sieht es so aus, als hätte der kleine Roboter nun zwei Augen:
Technisch gesehen sind die beiden Zylinder aber keine Augen: Der linke Zylinder ist eher ein Mund und der rechte ein Ohr. Mit dem linken werden Schallwellen ausgesendet (engl.: transmitted, deshalb steht da ein T); es wird quasi gerufen. Mit dem rechten Zylinder wird dann gehört; es werden also Schallwellen empfangen (engl.: received, deshalb steht da ein R).
Du kennst das vom Echo-Effekt: Du rufst ganz laut „Haaallooo!“ gegen eine Felswand und nach kurzer Zeit hörst du das Echo deines Rufs. Je weiter die Felswand entfernt ist, desto länger dauert es, bis du das Echo hörst, denn der Schall braucht seine Zeit, um von deinem Mund zur Felswand und zurück zu deinem Ohr zu gelangen.
Das heisst: Du könntest die Zeit zwischen Ruf und Echo stoppen und so auf die Distanz zwischen dir und der Felswand schliessen. Genau so funktioniert der Ultraschallsensor:
Auf der linken Seite des obigen Bildes siehst du, wie der Microbit mit dem Ultraschall-Sensor verbunden ist: Pin 1 ist mit dem Signal „Trigger“ verbunden, Pin 2 mit dem Signal „Echo“.
Auf der rechten Seite siehst du, wie es funktioniert: Wenn wir einen kurzen Impuls (10 µs = zehn Mikrosekunden) auf das Trigger-Signal geben, dann sendet der Ultraschall-Sensor Schallwellen in hoher, nicht hörbarer Frequenz (40 kHz) aus: Er „ruft“. Wenn der Ultraschall-Sensor nun das Echo seines Rufes „hört“, sendet er über das Echo-Signal einen Impuls zurück. Dieser Echo-Impuls ist so lange, wie es gedauert hat von „rufen“ bis „hören“.
Um nun eine Distanz zu messen, müssen wir nur ein kurzes Signal auf Pin 1 (Trigger) geben und dann an Pin 2 messen, wie lange das Echo-Signal dauert. Diese Zeit können wir in eine Distanz umrechnen: Der Schall legt ca. 340 Meter pro Sekunde zurück, das sind 0.034 cm pro Mikrosekunde. Angenommen, der Echo-Impuls ist 700 µs lang: Dann beträgt die Distanz 700 * 0.034 / 2 = 11.9 cm. Wir rechnen durch 2, weil der Schall die Distanz zweimal zurücklegt. Folgender Code misst die Distanz und zeigt sie auf dem Display an:
from microbit import * import utime import machine while True: pin1.write_digital(1) # Pin 1 (Trigger) HIGH für... utime.sleep_us(10) # ...10 µs... pin1.write_digital(0) # ...und wieder LOW. echoPulse = machine.time_pulse_us(pin2, 1) # Messe, wie lange der Echo-Impuls an Pin 2 dauert. distance = echoPulse * 0.017 # Rechne Zeit in Distanz um. display.scroll(distance)
Für die Funktion sleep_us
wird das Modul utime
benötigt; für die Funktion time_pulse_in
wird das Modul machine
benötigt. Verstehst du jede Zeile des Codes? Dann probiere den Code aus und überprüfe, ob die angezeigten Distanzen stimmen.
Aufgaben G
Aufgaben G1
Schreibe eine Funktion namens getDistance()
, welche die mit dem Ultraschallsensor gemessene Distanz zurückgibt.
- Baue in diese Funktion vor der return-Anweisung eine Verzögerung (sleep) von 10 ms ein. Damit wird verhindert, dass die Funktion innert weniger Millisekunden mehrmals aufgerufen wird, was die Ultraschall-Messung stören könnte.
Aufgaben G2
Speichere dein Programm aus Aufgabe F3 unter neuem Namen und ändere es:
- Füge deine Funktion
getDistance()
ein. - In der Endlosschleife fragst du Tasten und Ultraschall-Sensor ab.
- Wenn Taste A gedrückt wurde, soll Maqueen langsam (Geschwindigkeit 30) vorwärts fahren.
- Wenn die Distanz zu einem Objekt kleiner als 10 cm ist, soll Maqueen erst stoppen und dann eine 90°-Drehung machen.
Aufgaben G3
Speichere dein Programm aus Aufgabe G2 unter neuem Namen und ändere es:
- Ändere die Funktion zum Drehen (
turn()
) so, dass Maqueen auf der Stelle dreht. Setze die Geschwindigkeit für die Motoren auf 66. Passe den Faktor an, bis der Drehwinkel in etwa stimmt.
Aufgaben G4
Speichere dein Programm aus Aufgabe G3 unter neuem Namen und ändere es:
- Wenn Taste A gedrückt wurde, soll Maqueen langsam (Geschwindigkeit 30) vorwärts fahren.
- Wenn die die Distanz zu einem Objekt kleiner als 6 cm ist, soll Maqueen erst stoppen; dann eine Drehung um einen zufälligen Winkel zwischen 30° und 170 ° machen und danach wieder langsam (Geschwindigkeit 30) vorwärts fahren.
Setze nun Maqueen in eine Feld, in dem er von vier Seiten begrenzt ist und beobachte das Verhalten. Angenommen, Maqueen könnte staubsaugen: Wäre das schon ein guter Roboter-Staubsauger?
Aufgaben G5
Speichere dein Programm aus Aufgabe G4 unter neuem Namen und ändere es:
- Vor jeder Drehung soll der Microbit drei Mal „turn“ sagen.
Aufgaben H (Advanced)
Aufgabe H1
Du hast ja bereits den Code, um den Maqueen zu steuern (drive()
, turn()
, stop()
, getDistance()
). Lies nun das Kapitel Kapitel zum Funk-Steuerung und stelle sicher, dass du die Signalstärke auslesen kannst.
Löse damit gerüstet die folgende Aufgabe:
- der Roboter soll kollisionsfrei herumfahren (wie der Staubsaug-Roboter)
- der Roboter soll mittels Radio andere Roboter finden und möglichst nahe zu ihnen fahren. Sind die zwei Roboter nah genug, sollen sie anhalten und einen Tanz vorführen (z.B. sich im Kreis drehen).