Microbit programmieren

Der micro:bit ist ein Microcontroller (eine Art Mini-Computer), der speziell für den Schulbetrieb entwickelt wurde und mit Python programmiert werden kann.

Er verfügt über eine Vielzahl an Komponenten, die man mit seinem Code ansteuern kann. Mit Display und Lautsprecher kann der Microbit Bild und Ton ausgeben. Zur Eingabe von Daten sind auf dem Microbit zwei Tasten, das Touch-Logo und mehrere Sensoren eingebaut. Auf dieser Seite lernst du die wichtigsten Funktionen kennen, um Display, Lautsprecher, Tasten und Sensoren anzusteuern.

Eine kurze Übersicht zu den wichtigsten Funktionen in englischer Sprache findest du im Microbit-Python-Guide

In der Microbit-Micropython-Dokumentation findest du alle Informationen zur Programmierung des Micro-Bit.

Für die Programmierung des Microbits gibt es zwei Möglichkeiten:

  1. Online-Editor:
    1. Verwende Chrome Browser
    2. Vergleich zum Mu-Editor (unten):
      1. Pro: unkompliziert, keine Installation nötig, schnelles Laden auf micro:bit
      2. Contra: Speichern/Laden ist deutlich umständlicher
    3. Tipp zum Speichern::
      1. Kopiere deinen Code jeweils in ein Word Dokument.
      2. Verwende z.B. folgende Vorlage: Template Aufgaben
      3. Bonus bei diesem Vorgehen: schöne Übersicht von allen deinen Codes!
  2. Offline-Editor:
    1. Lade hier die Installationsdatei herunter.
    2. Installiere den Editor gemäss den Anweisungen.
    3. Verbinde den Microbit über das USB-Kabel mit deinem Computer.
    4. Für macOS-User: Stelle sicher, dass die Applikationen „Mu-Editor“, „sh“, „Terminal“ vollen Schreibzugriff haben (unter Systemeinstellungen –> Sicherheit…).
    5. Starte den Editor.
    6. Klicke auf den Mode-Button oben links und wähle den Modus „BBC micro:bit“.
    7. Schreibe untenstehende Code-Zeilen.
    8. Klicke auf die „Flash“-Taste und warte, bis dein Code auf den Microbit geladen ist: Wenn dein Microbit nun „Hello, World!“ anzeigt, kannst du mit dem Programmieren beginnen.
from microbit import *
display.scroll("Hello, World!")

Wir schauen uns kurz die beiden Code-Zeilen des Hello-World-Beispiels an:

from microbit import *
display.scroll("Hello, World!")
  • Die Zeile from microbit import * bedeutet, dass alle Microbit-Funktionen und -Objekte importiert werden sollen. Diese Zeile brauchen wir für jedes Microbit-Programm.
  • Die zweite Zeile sagt dem Display, dass es die Zeichenkette „Hello, World!“ als Laufschrift anzeigen soll – oder etwas genauer formuliert: Vom display-Objekt wird die Funktion scroll() aufgerufen und dieser Funktion wird die Zeichenkette „Hello, World!“ übergeben.

Über das display-Objekt kannst du auf weitere Display-Funktionen zugreifen. Wenn du im Mu-Editor display und dann einen Punkt eintippst, erhältst du eine Liste mit allen Display-Funktionen. Die wichtigsten sind clear() zum Löschen des Displays und show() zur Anzeige von einem oder mehreren Bildern.

Folgender Code zeigt ein Herz auf dem Display:

from microbit import *
display.show(Image.HEART)

Über das Image-Objekt kannst du auf eine Reihe von vordefinierten Bildern zugreifen.

Hier findest du eine Übersicht über die Bilder und eine Anleitung zum Erstellen von eigenen Bildern und Animationen.

In Python kannst du auf einfache Weise Listen erstellen, das hast du hier gelernt. Im folgenden Code wird eine Liste von Bildern erstellt und angezeigt.

from microbit import *
 
my_images = [Image.HAPPY, Image.SMILE, Image.SAD, Image.CONFUSED]
 
display.show(my_images)

Die Funktion show() merkt, dass sie es hier mit einer Liste zu tun hat und zeigt nun jedes Bild der Liste nacheinander.

Du kannst der Funktion weitere Parameter übergeben:

display.show(my_images, delay = 500, loop = True)
  • Mit dem Parameter delay gibst du an, wie lange (in Millisekunden) jedes Bild angezeigt werden soll.
  • Wenn du den Parameter loop auf „True“ setzt, wird die Animation endlos wiederholt.

Der Microbit kann über die Tasten A und B sowie per Touch-Logo bedient werden. Mit den Funktionen is_pressed() bzw. is_touched() kannst du fragen, ob die jeweilige Taste gedrückt ist. Das folgende Programm zeigt je nach betätigtem Bedienelement ein anderes Bild auf dem Display:

from microbit import *
 
while True:
    if button_a.is_pressed():
        display.show(Image.HAPPY)
    if button_b.get_presses():
        display.show(Image.SAD)
    if pin_logo.is_touched():
        display.show(Image.HEART)

Mit while True: wird eine Endlos-Schleife eröffnet: Der Code darunter wird endlos wiederholt:

  • Zuerst wird gefragt, ob die Taste A gerade gedrückt wird: Falls ja, soll das Display das Bild HAPPY anzeigen.
  • Dann wird gefragt, wie oft Taste B gedrückt worden ist: Falls mehr als Null mal, soll das Display das Bild SAD anzeigen.
    • Hinweis: get_presses() gibt eine Zahl zurück - Python wandelt die Zahl in einen Wahrheitswert (Wahr oder Falsch) um, wobei Null mit False übersetzt wird und jede andere Zahl mit True.
  • Dann wird gefragt, ob das Logo gerade berührt wird: Falls ja, soll das Display das Bild HEART anzeigen.
  • Dann springt das Programm wieder zum ersten Punkt – und so weiter und so fort.

Beachte, dass es für Tasten drei Befehle gibt: is_pressed(), get_presses() und was_pressed().

  • is_pressed() gibt True zurück, wenn die Taste im Moment der Abfrage gedrückt ist, aber sagt nichts darüber aus, ob sie in der Vergangenheit gedrückt worden ist.
  • was_pressed() gibt True zurück, falls die Taste seit dem letzten Aufruf der Funktion gedrückt worden ist, also auch, wenn die Taste bereits wieder losgelassen wurde.
  • get_presses() funktioniert ähnlich wie was_pressed, aber gibt die Anzahl Klicks seit dem letzten Funktionsaufruf zurück. Der Funktionsaufruf setzt den Zähler wieder auf Null zurück.

Diese If-Abfragen erfolgen so schnell, dass die Endlos-Schleife jede Sekunde mehrere tausend Mal durchlaufen wird. Du kannst also jederzeit eine Taste drücken und das Bild wird sofort angepasst – probiere es aus!

Zusätzlich befinden sich unten am micro:bit Pins, die man verwenden kann. Probiere folgenden Code aus:

# Imports go at the top
from microbit import *
 
while True:
    if pin0.is_touched():
        display.show(Image.HAPPY)
    else:
        display.show(Image.SAD)

Sobald du nun den Stromkreis zwischen Ground (GND) und Pin 0 schliesst (beide gleichzeitig berühren oder mit Kabel verbinden), sollte nun ein Happy-Smile angezeigt werden.

Für mehr Infos siehe hier: https://microbit-micropython.readthedocs.io/en/latest/pin.html

Auf der Rückseite des Microbits befindet sich unten links ein Beschleunigungssensor. Der Beschleunigungssensor misst die Beschleunigung, die der Microbit in x-, y- und in z-Richtung erfährt. Du kannst dir eine Drohne vorstellen: Wenn sie immer vorwärts und rückwärts fliegt, beschleunigt sie in x-, wenn sie seitwärts hin und her fliegt in y- und wenn sie hoch oder runter fliegt in z-Richtung.

Folgender Code liest alle 100 ms die Werte aus dem Beschleunigungssensor und sendet sie über USB:

from microbit import *
 
while True:
    sleep(100)
    print(str(accelerometer.get_values()))

Innerhalb der Endlos-Schleife while True werden zwei Befehele ständig wiederholt:

  • sleep(100) lässt das Programm während 100 Millisekunden in der Funktion sleep() verharren,
  • in der zweiten Zeile sind gleich drei Funktionen ineinander verschachtelt:
    1. Die Funktion get_values() gibt die drei Werte vom Beschleunigungssensor für die $x-,y-$ und $z-$Achse zurück,
    2. die Funktion str() wandelt diese Zahlenwerte in eine Zeichenkette (engl. String) und
    3. die Funktion print() sendet diese Zeichenkette über USB, sodass sie am verbundenen Computer angezeigt werden kann.

Probiere es aus: Lade obigen Code auf den Microbit und starte im MU editor den Plotter (Button „Plotter“ oben Mitte). Es werden drei Kurven angezeigt. Wenn du den Microbit wild schüttelst – achte auf das Kabel und darauf, dass du nicht deinen Laptop mitreisst – dann bewegen sich alle drei Kurven.

Versuche jetzt, den Microbit so zu bewegen, dass jeweils nur eine der drei Kurven ausschlägt.

Zur Info:

  • Die Funktion get_values() gibt Werte in der Einheit mg zurück, $1000$ mg entsprechen 1 g: $1 g = 9.81 \text{m}/\text{s}^2$.
  • Standardmässig beträgt der Messbereich des Beschleunigungssensors +/- 2 $g$.
  • Mit get_values() erhältst du die Beschleunigungen $a_x,a_y,a_z$ für die drei einzelnen Koordinaten. Die Gesamtbeschleunigung (Betrag der Beschleunigung) ist dann gegeben durch den Satz von Pythagoras in 3D: $$a = \sqrt{a_x^2 + a_y^2 + a_z^2}$$ Achtung: Dieser Wert ist immer positiv. Du verlierst damit also sämtliche Informationen über die Richtung der Beschleunigung.

Mit dem Beschleunigungssensor können auch bestimmte Gesten (engl. gestures) erkannt werden – zum Beispiel, ob der Microbit geschüttelt wurde („shake“), ob er nach oben („face up“) oder nach unten („face down“) gedreht ist usw. Folgender Code zeigt ein Happy Face, wenn der Microbit nach oben gedreht ist, sonst ein Sad Face:

from microbit import *
 
while True: 
    if accelerometer.is_gesture("face up"):
        display.show(Image.HAPPY)
    else:
        display.show(Image.SAD) 

Die Funktion is_gesture() gibt True zurück, wenn der Beschleunigungssensor die in den Klammern angegebene Geste erkannt hat. Sonst gibt sie False zurück.

Hier findest du eine Übersicht über Funktionen des Beschleunigungssensors.

Hier findest du eine Übersicht über alle Gesten und eine Anleitung dazu, wie du aus deinem Microbit einen Magic8Ball programmieren kannst.

Auf der Rückseite des Microbits befindet sich in der Mitte der „Lautsprecher“ (engl. speaker). Dieser klingt nicht wirklich laut, aber dank folgender Software-Module kannst du viel damit machen:

  • Das Modul music stellt dir eine Reihe von vordefinierten Melodien zur Verfügung. Du kannst auch selber Melodien erstellen.
  • Mit dem Modul speech kann dein Microbit einen Text sprechen oder gar singen. Allerdings lässt die Qualität noch zu wünschen übrig. Für bessere Audio-Qualität schliesst du den einen Kanal eines alten Kopfhörers an den Pins 0 und GND an.

Folgender Code spielt einen Ton, wenn die Taste A gedrückt wird:

from microbit import *
import music
 
while True:
    if button_a.is_pressed():
        music.pitch(440, 100)
  • Die Zeile import music importiert das Modul music. Dieses enthält die Funktionen pitch(), play() und weitere Funktionen.
  • Der Funktion pitch() wird die Frequenz des Tons in Hertz und die Dauer des Tons in Millisekunden übergeben.
  • Wenn du kurz testen willst, welche Frequenz wie klingt, klicke hier.

Das Modul music enthält schon ein paar vordefinierte Melodien. Folgender Code spielt eine solche Melodie ab:

from microbit import*
import music
 
music.play(music.PRELUDE)

Melodien selber erstellen

Du kannst auch selbst Melodien erstellen, wie in folgendem Code:

from microbit import*
import music
 
my_melody = ['g3:4', 'g3:4', 'b3:4', 'g3:4','c4:4', 'f4:4', 'c4:4', 'g3:8']
 
music.set_tempo(bpm = 180) # 120 Schläge pro Minute wäre Standard
music.set_tempo(ticks = 8) # 8 Schläge pro Takt ist Standard
 
music.play(my_melody)
  • Die Liste my_melody enthält jede zu spielende Note und deren Dauer; es gilt die Notation NOTE[Oktave][:Dauer], also zum Beispiel 'c4:8' für die Note C in der vierten Oktave, die acht Schläge lang gespielt wird.Hier eine Übersicht über die Noten und Oktaven.
  • Mit der Funktion set_tempo() kann das Tempo (beats per minute) oder die Taktart verändert werden.
  • Die Funktion play() spielt die Melodie ab.

Probiere das Programm aus und verändere die Melodie, du kannst auch Noten hinzufügen oder weglassen.

Melodien anders abspielen

Dir ist vielleicht aufgefallen, dass manche Melodien nicht so klingen, wie sie sollten. Hier zum Beispiel die Melodie für das Lied Frère Jacques (Bruder Jakob):

# Frère Jacques:
melody_jacques = ['c4:4', 'd4:4', 'e4:4', 'c4:4','c4:4', 'd4:4', 'e4:4', 'c4:4',
                 'e4:4', 'f4:4', 'g4:8', 'e4:4', 'f4:4', 'g4:8',
                 'g4:2', 'a4:2', 'g4:2', 'f4:2', 'e4:4', 'c4:4',
                 'g4:2', 'a4:2', 'g4:2', 'f4:2', 'e4:4', 'c4:4',
                 'c4:4', 'g3:4', 'c4:8', 'c4:4', 'g3:4', 'c4:8']

Wenn die Funktion play() Melodien abspielt, werden die einzelnen Töne unmittelbar aufeinanderfolgend, also ohne Zwischenpause wiedergegeben. Falls zwei gleiche Töne aufeinanderfolgen (wie in Frère Jacques beispielsweise der 4. und 5. Ton), klingt das wie ein einziger, langer Ton. Hierzu gibt es mindestens zwei Lösungen:

  1. Mit der Note r (für engl. rest) können Pausen in die Melodie eingebaut werden: 'r:2' macht eine Pause von zwei Schlägen. Dann sollten aber auch die anderen Ton-Dauern angepasst werden.
  2. Da die Melodie als Liste vorliegt, kannst du sie Ton für Ton abspielen und jeweils dazwischen eine ganz kurze Pause einbauen. Zum Beispiel so:
note = 0
while True:
    music.play(melody_jacques[note])
    sleep(30)
    if(note < len(melody_jacques)-1):
        note += 1
    else:
        note = 0
  • In obigem Code wird zuerst eine Variable note für die Auswahl der Note auf 0 gesetzt.
  • In der Endlos-Schleife (while True:) wird nun in jedem Durchgang eine Note aus der Liste melody_jacques gespielt.
  • Dann wird 30 ms lang gewartet.
  • Schliesslich wird die Variable note erhöht oder – falls Sie bereits der Zahl des letzten Elements der Liste melody_jacques entspricht – auf 0 gesetzt.

Mikrophon

Mit microphone.sound_level() kann die Umgebungslautstärke abgefragt werden. Der Rückgabewert ist zwischen 0 (Stille) und 255 (sehr laut).

Auf der Rückseite des Microbits siehst du oben links eine goldene Leitung, die rechtwinklig hin- und her verläuft (mäanderförmig).

BLE-Antenne auf dem Microbit

Das ist die Antenne, mit der dein Microbit elektromagnetische Wellen (Funkwellen, engl.: radio waves) senden und empfangen und damit über BLE kommunizieren kann. BLE steht für Bluetooth Low Energy, eine Weiterentwicklung der Bluetooth-Funktechnologie, die dein Smartphone nutzt, um sich beispielsweise mit kabellosen Kopfhörern zu verbinden. BLE braucht weniger Energie als Bluetooth, weil es weniger Daten sendet. BLE ist daher nicht geeignet, Musik zu senden – das wären zu viele Daten. Für kleine Textnachrichten aber eignet sich BLE sehr gut.

Hier ein einfaches Programm, das einen Text senden, empfangen und anzeigen kann:

from microbit import *
import radio
 
while True:
    message_in = radio.receive()
    if message_in:
        display.scroll(message_in)
 
    if button_a.is_pressed():
        radio.send("Ciao!")
  • Zuerst muss das Radio-Modul mit dem Befehl import radio geladen werden.
  • In der Endlosschleife wird zuerst die Funktion radio.receive() aufgerufen. Diese Funktion schaut, ob eine Nachricht angekommen ist. Falls ja, gibt sie die empfangene Nachricht zurück, falls nein, gibt sie None (gleichbedeutend mit 0 oder False) zurück. Der zurückgegebene Wert wird in der Variable message_in gespeichert.
  • Jetzt wird mit der If-Abfrage geprüft, ob eine Nachricht angekommen ist (wenn message_in = None ist, dann ist die Bedingung nicht erfüllt).
  • Falls ja, wird diese Nachricht mit der Funktion scroll() angezeigt.
  • Wenn die Taste A gedrückt wird, wird die Nachricht „Ciao!“ gesendet.
  • Achtung: Wenn mehrere Gruppen im gleichen Raum arbeiten lohnt es sich, nur auf einer bestimmten Frequenz resp. in einer bestimmten Gruppe Nachrichten zu senden und empfangen. Für eine private Kommunikation gibt es zwei Möglichkeiten:
    • Ihr könnt auf einer anderen Frequenz senden: mit dem Befehl radio.config(channel = x) wählt ihr einen Kanal zwischen 0 und 83 (für x setzt ihr die Kanal-Nummer ein). Standardmässig ist der Kanal = 7 (und die Frequenz damit 2407 MHz).
    • Ihr könnt Nachrichten herausfiltern, indem ihr mit dem Befehl radio.config(group = x) eine eigene Gruppe-Nr. zwischen 0 und 255 wählt (standardmässig ist die Gruppe 0). So werden eure Nachrichten mit einer spezifischen Adresse versehen und eure Microbits schauen nur nach Nachrichten mit dieser Adresse.

Mit radio.send() und radio.receive() können nur Strings versendet und empfangen werden. Aus diesem Grund kann man also Bilder nicht direkt versenden. Zum Beispiel resultiert radio.send(Image.HAPPY) in einem Fehler. Es gibt aber einen Workaround:

  1. Konvertiere das Bild in einen String: s = repr(Image.HAPPY)
  2. Entferne alles, so dass String noch die Form s = '00000:00000:00900:00000:00000' hat.
  3. Versende diesen String.
  4. Wandle den empfangenen String mit Image() wieder in ein Bild um und zeige es an.

Bisher haben wir mit message_in = radio.receive() Nachrichten empfangen. Es gibt aber noch eine zweite Möglichkeit: Mit radio.receive_full() empfängt man nicht nur die eigentliche Textnachricht, sondern auch die Signalstärke. Diese ist auch ein Indiz für die Distanz zwischen zwei micro:bits.

Das folgende Code-Beispiel zeigt, wie man die Textnachricht und die Signalstärke aus der erhaltenen Nachricht herauslesen kann:

message_full = radio.receive_full()
if message_full:
    text = message_full[0]
    signal_strength = message_full[1]

Die Signalstärke (hier signal_strength) ist einfach eine Zahl, die grösser wird, je stärker das Signal ist. Tipp: Printe die Signalstärke in die Konsole (print(signal_strength) und Show serial klicken, um Konsole anzuzeigen) und verfolge, wie sich der Wert verändert, wenn die Distanz verändert wird.

Probiert das Programm zu zweit aus:

  • Ladet obiges Programm auf eure Microbits und schaut, ob ihr euch via Microbit gegenseitig „Ciao!“ sagen könnt.
  • Achtung: Wenn andere im gleichen Raum ebenfalls das Programm ausprobieren, empfangen sie ebenfalls eure Nachrichten (und ihr ihre). Um dies zu verhindern, habt ihr mindestens zwei Möglichkeiten:
    • Ihr könnt auf einer anderen Frequenz senden: mit dem Befehl radio.config(channel = x) wählt ihr einen Kanal zwischen 0 und 83 (für x setzt ihr die Kanal-Nummer ein). Standardmässig ist der Kanal = 7 (und die Frequenz damit 2407 MHz).
    • Ihr könnt Nachrichten herausfiltern, indem ihr mit dem Befehl radio.config(group = x) eine eigene Gruppe-Nr. zwischen 0 und 255 wählt (standardmässig ist die Gruppe 0). So werden eure Nachrichten mit einer spezifischen Adresse versehen und eure Microbits schauen nur nach Nachrichten mit dieser Adresse. Wähle nur eine der beiden Möglichkeiten aus.

In diesem Kapitel 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.

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:
    # Distanz messen
    pin1.write_digital(1)   # Pin 1 (Trigger) HIGH für...
    utime.sleep_us(10)      # ...10 µs...
    pin1.write_digital(0)   # ...und wieder LOW.
    echo_pulse = machine.time_pulse_us(pin2, 1) # Messe, wie lange der Echo-Impuls an Pin 2 dauert.
    distance = echo_pulse * 0.017 # Rechne Zeit in Distanz um.
 
    # Ausgabe
    display.scroll(distance) # Ausgabe auf LED-Matrix
    print(distance) # Ausgabe in Konsole
 
    sleep(500)

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.

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:

I2C_ADDR = 16 # Adresse des Motor-Controllers
while I2C_ADDR 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
    i2c_buf = bytearray([motors, direction, speed])
    if motors == 0:  # left motor
        i2c_buf[0] = 0x00
        i2c.write(I2C_ADDR, i2c_buf)
    if motors == 1:  # right motor
        i2c_buf[0] = 0x02
        i2c.write(I2C_ADDR, i2c_buf)
    if motors == 2:  # both motors
        i2c_buf[0] = 0x00
        i2c.write(I2C_ADDR, i2c_buf)
        i2c_buf[0] = 0x02
        i2c.write(I2C_ADDR, i2c_buf)

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)

Für die einfachere Steuerung des Maqueen inklusive seiner Sensoren und Aktoren gibt es eine Schnittstelle auf Github.

Installation

Zur Installation des Codes lädst du maqueen.hex herunter und auf den Microbit drauf (an einfachsten: Datei auf die Seite ziehen).

  • Alternative: Lade maqueen.py und füge die Datei deinem Projekt hinzu.

Distanzmesser

Der Ultraschallsensor gibt die ungefähre Distanz bis zum nächsten Objekt wieder. Lies hier mehr dazu. Wenn du die distance() Funktion einbaust, kannst du vermeiden, dass der Roboter in Gegenstände fährt…

from maqueen import *
from microbit import *
 
robot = Maqueen()
front_sensor = robot.front_sensor
 
dist = 10
while True:
    newdist = int(front_sensor.distance() / 10)
    if newdist != dist:
        dist = newdist
        # Show distance in decimeters
        display.show(dist)
    sleep(100)

Motorsteuerung

Es gibt zwei Arten, wie die Motoren des Maqueen gesteuert werden können. Am einfachsten ist der Driver - die Funktionen drive, left, right setzen den Roboter in Bewegung und blockieren die Ausführung, bis die Bewegung zu Ende ist. Achtung: die Angaben zu Distanz (in cm) und Winkel (in Grad) werden je nach Batterieladestand nicht immer genau eingehalten!

from microbit import *
from maqueen import *
 
robot = Maqueen()
 
# High-level Driver interface:
# Fahre 20cm geradeaus, dann ein paar Kurven.
# Der Roboter stoppt automatisch nach jeder Funktion.
driver = robot.driver
driver.drive(20)
driver.left(90)
driver.right(180)
driver.left(90)

Die Driver-Steuerung ist ähnlich wie die Turtle-Bewegungen aus Programmieren 1, aber eignet sich weniger gut, um auf Ereignisse zu reagieren. Zum Beispiel möchten wir stoppen, wenn der Ultraschall-Sensor ein Hindernis detektiert.

Mit der Chassis-Schnittstelle kannst du den Roboter bis auf Weiteres in Bewegung setzen und erst auf ein bestimmtes Ereignis hin wieder stoppen:

from microbit import *
from maqueen import *
 
robot = Maqueen()
# Die Chassis-Funktionen setzen den Roboter in Bewegung 
# und kommen dann sofort zurück. Vergiss nicht, den Roboter
# wieder zu stoppen! Dazu könntest du den Ultraschall-
# Sensor benützen:
chassis = robot.chassis
 
chassis.forward(speed=100) # Vorwärts fahren mit Geschwindigkeit 100
chassis.stop() # Stoppen
chassis.left() # Links drehen

Front LEDs

Schalte die zwei roten LEDs auf der Vorderseite ein und aus mit der front_lights.set_lights Funktion:

from microbit import *
from maqueen import *
 
robot = Maqueen()
 
# Licht an
robot.front_lights.set_lights(1,1)
 
# Licht aus
robot.front_lights.set_lights(0,0)

Bottom LEDS

Du kannst die Farb-LEDs auf der Unterseite des Maqueens wie folgt kontrollieren. Die LEDs können im RGB-Farbraum (rot-grün-blau) programmiert werden. Jede Farbe kann Werte von 0 (aus) bis 255 annehmen.

from maqueen import *
 
robot = Maqueen()
leds = robot.bottom_leds
 
# Setze das erste LED auf rot:
leds[0] = (255,0,0)
# Setze das zweite LED auf weiss (= alle Farben auf voll):
leds[1] = (255,255,255)
# Die LEDs werden erst geändert, wenn show() aufgerufen wird:
leds.show()
 
# Alle 4 LEDS in magenta:
leds.fill((255,0,255))
leds.show()
 
# Licht aus!
leds.clear()

Boden-Farbe erkennen

Die read() Funktion gibt die Helligkeit des Bodens wieder. Beide Werte sind entweder 0 (= Boden ist schwarz oder kein Boden sichtbar) oder 1 (= Boden ist weiss / hell). Auf der Oberseite zeigen zwei kleine blaue LEDs den Zustand der Sensoren an. Kannst du den Roboter einer Linie folgen lassen, wenn du diesen Code einbaust?

from microbit import *
from maqueen import *
 
robot = Maqueen()
floor_sensor = robot.floor_sensor
 
left, right = floor_sensor.read() # left/right nehmen Wert 0 oder 1 an
  • gf_informatik/microbit_programmieren_grundlagen.1691420790.txt.gz
  • Zuletzt geändert: 2023-08-07 15:06
  • von hof