Andreas Rozek
[ Impressum ]   [ Datenschutzerklärung ]   [ Kontakt ]   [ ]

Tutorial für den Browser

BoardControl Tutorial für den Browser

Um die JavaScript-Bibliothek aus dem BoardControl-Paket zur Fernsteuerung eines BBC micro:bit im Browser einsetzen zu können, muss zunächst das zugehörige Skript eingebunden werden:

<script type="application/javascript" src="Path-to-Script/BoardControl.js"></script>

Dadurch wird ein ein globales Objekt namens MicroBit angelegt, mit welchem jetzt gearbeitet werden kann.

Prüfung auf Verfügbarkeit

Zweckmäßigerweise sollte zu Beginn geprüft werden, ob WebBT tatsächlich unterstützt wird und zur Verfügung steht:

  if (! MicroBit.WebBTisSupported) {
inform user about missing Web Bluetooth support
}

if (! MicroBit.WebBTisAvailable) {
tell user to switch Bluetooth on
}

Instanzierung

Für die Steuerung jedes einzelnen BBC micro:bit wird zunächst je eine Instanz der Klasse MicroBit.Board erzeugt:

  let Board = new MicroBit.Board()

Von jetzt an sind die meisten Aufrufe asynchron. BoardControl verwendet Promises, die entweder direkt als solche eingesetzt oder (in moderneren Browsern) durch Aufrufe mit await ersetzt werden können. Da WebBT ohnehin nur von neueren Browsern bereitgestellt wird, nutzen die folgenden Beispiele das übersichtlichere await.

Nota bene: Falls Sie Promises lieber direkt (d.h. mit then und catch) einsetzen, sehen Sie sich bitte den Quelltext für das Komplettbeispiel an.

Herstellen einer Verbindung

Bevor ein Board ferngesteuert werden kann, muss sich der Browser damit verbinden:

  await Board.connect()

Dies startet den (vom Browser kontrollierten) Prozess der Koppelung mit einem passenden Bluetooth Peripherie-Gerät (in diesem Fall einem BBC micro:bit)

Sobald eine Verbindung zu einem Board besteht, kann es von der MicroBit-Instanz aus kontrolliert werden.

Device Information Service

Bevor Sie Daten zum Gerät selbst erfragen, sollten Sie prüfen, ob der "Device Information Service" überhaupt zur Verfügung steht:

  if (Board.DeviceInfoServiceIsSupported()) { insert your code here }

"Model Number String" und "Firmware Revision String" lassen sich anschließend wie folgt auslesen:

  let ModelNumber = await Board.ModelNumber()
let FirmwareRevision = await Board.FirmwareRevision()
Nota bene: sowohl die informelle Beschreibung des Bluetooth-Profiles [1] als auch dessen Spezifikation [2] sind hinsichtlich des "Device Information Service" fehlerhaft: statt angeblich 9 Charakteristiken werden nur 5 spezifiziert - und von diesen anstelle von 3 offenbar nur die zuvor gezeigten 2 implementiert

Accelerometer Service

Bevor Sie auf den Beschleunigungssensor (Accelerometer) zugreifen, sollten Sie prüfen, ob der "Accelerometer Service" überhaupt zur Verfügung steht:

  if (Board.AccelerometerServiceIsSupported()) { insert your code here }

Die derzeitige Beschleunigung (in Vielfachen der Erdbeschleunigung) entlang der drei Raumachsen erhalten Sie wie folgt:

  let {x,y,z} = await Board.AccelerometerData()

Das Intervall (in Millisekunden) für die laufende Übermittelung von Accelerometer-Messwerten erhalten Sie mittels

  let Interval = await Board.AccelerometerInterval()

Ändern können Sie dieses Intervall durch

  await Board.AccelerometerInterval(Interval)

Zulässige Werte für Interval sind 1, 2, 5, 10, 20, 80, 160 und 640.

Event Handling

Eine laufende Übertragung von Messwerten starten Sie durch Registrieren eines Event Handlers

  Board.on('AccelerometerData', (Data) => { insert your code here })

Sobald der letzte Event Handler für das Event AccelerometerData wieder entfernt wurde, endet die laufende Übertragung von Accelerometer-Messwerten

  Board.off('AccelerometerData')

Magnetometer Service

Bevor Sie auf das Magnetometer zugreifen, sollten Sie prüfen, ob der "Magnetometer Service" überhaupt zur Verfügung steht:

  if (Board.MagnetometerServiceIsSupported()) { insert your code here }

Die derzeitige magnetische Flussdichte (in Mikro-Tesla) entlang der drei Raumachsen erhalten Sie wie folgt:

  let {x,y,z} = await Board.MagnetometerData()

Den Winkel (in Grad) zwischen der y-Achse des BBC micro:bit und der magnetischen Nordrichtung erhalten Sie durch

  let Bearing = await Board.MagnetometerBearing()

Das Intervall (in Millisekunden) für die laufende Übermittelung von Magnetometer-Messwerten erhalten Sie mittels

  let Interval = await Board.MagnetometerInterval()

Eigentlich sollte der Aufruf nur einen der Werte 1, 2, 5, 10, 20, 80, 160 bzw. 640 liefern, aber offenbar hält sich die Implementierung nicht an die Spezifikation und liefert auch andere Intervalle.

Ändern können Sie dieses Intervall durch

  await Board.MagnetometerInterval(Interval)

Zulässige Werte für Interval sind 1, 2, 5, 10, 20, 80, 160 und 640.

Event Handling

Eine laufende Übertragung von Messwerten starten Sie durch Registrieren eines Event Handlers

  Board.on('MagnetometerData', (Data) => { insert your code here })
Board.on('MagnetometerBearing', (Bearing) => { insert your code here })

Sobald der letzte Event Handler für die Events MagnetometerData bzw. MagnetometerBearing wieder entfernt wurde, endet die laufende Übertragung der jeweiligen Messwerte

  Board.off('MagnetometerData')
Board.off('MagnetometerBearing')

Den aktuellen Zustand der Magnetometer-Kalibrierung können Sie nicht auslesen, wohl aber eine Kalibrierung anstoßen

  await Board.MagnetometerCalibrationState(1)

oder sich über Änderungen des Zustandes informieren lassen

  Board.on('MagnetometerCalibrationState', (State) => { insert your code here })

Temperature Service

Bevor Sie die Prozessor-Temperatur erfragen, sollten Sie prüfen, ob der "Temperature Service" überhaupt zur Verfügung steht:

  if (Board.TemperatureServiceIsSupported()) { insert your code here }

Die derzeitige Chip-Temperatur (in °C) erhalten Sie wie folgt:

  let Temperature = await Board.Temperature()

Das Intervall (in Millisekunden) für die laufende Übermittelung von Temperatur-Messwerten erhalten Sie mittels

  let Interval = await Board.TemperatureInterval()

Ändern können Sie dieses Intervall durch

  await Board.TemperatureInterval(Interval)

Zulässige Werte für Interval liegen im Bereich 0 bis 65535.

Event Handling

Eine laufende Übertragung von Messwerten starten Sie durch Registrieren eines Event Handlers

  Board.on('Temperature', (Temperature) => { insert your code here })

Sobald der letzte Event Handler für das Event Temperature wieder entfernt wurde, endet die laufende Übertragung von Temperatur-Werten

  Board.off('Temperature')

Button Service

Bevor Sie Tastenzustände erfragen, sollten Sie prüfen, ob der "Button Service" überhaupt zur Verfügung steht:

  if (Board.ButtonServiceIsSupported()) { insert your code here }

Den Zustand der linken Taste erhalten Sie dann mittels

  let ButtonA = await Board.ButtonA()

und den der rechten Taste durch

  let ButtonB = await Board.ButtonB()

Die gelieferten Werte sind entweder 0, 1 oder 2 und haben folgende Bedeutung:

  • 0 = nicht gedrückt,
  • 1 = gedrückt,
  • 2 = lange gedrückt.

Event Handling

Durch Registrieren eines entsprechenden Event Handler können Sie automatisch über Zustandsänderungen einer Taste informiert werden:

  Board.on('ButtonA', (ButtonState) => { insert your code here })
Board.on('ButtonB', (ButtonState) => { insert your code here })

Sobald der letzte Event Handler für ein solches Event wieder entfernt wurde, endet die automatisierte Mitteilung

  Board.off('ButtonA')
Board.off('ButtonB')

LED Service

Bevor Sie auf die LED-Matrix zugreifen, sollten Sie prüfen, ob der "LED Service" überhaupt zur Verfügung steht:

  if (Board.LEDServiceIsSupported()) { insert your code here }

Den aktuellen Zustand der LEDs erhalten Sie dann mittels

  let Bitmask = await Board.LEDMatrix()

Numeriert man die LEDs in x-Richtung von links nach rechts ab 0 und in y-Richtung von oben nach unten ebenfalls ab 0, so gehört zur LED an der Stelle x,y das Bit

  let Bit = (4-y)*5 + (4-x)

Den Zustand der LED an der Stelle x,y erhalten Sie somit durch

  let LED = (Bitmask & (1 << (4-y)*5 + (4-x))) !== 0

Ist das Ergebnis true so leuchtet die betreffende LED, anderenfalls ist sie dunkel.

Auf dieselbe Weise können Sie eine neue Bitmask erstellen, mit der Sie festlegen, welche LEDs leuchten sollen und welche nicht, und diese wie folgt an das Board schicken:

  await Board.LEDMatrix(Bitmask)

Textausgabe

Bis zu 20 ASCII-Zeichen können Sie durch die LED-Matrix laufen lassen:

  await Board.LEDText('Hello, World!')

Das Intervall zwischen den einzelnen Anzeigeschritten der Laufschrift (in Millisekunden) erfahren Sie durch

  let ScrollDelay = await Board.LEDScrollDelay()

und setzen es mittels

  await Board.LEDScrollDelay(ScrollDelay)

Zulässige Werte für ScrollDelay liegen im Bereich 0 bis 65535, voreingestellt sind 100 Millisekunden.

IO Pin Service

Bevor Sie auf die GPIO-Anschlüsse zugreifen, sollten Sie prüfen, ob der "IO Pin Service" überhaupt zur Verfügung steht:

  if (Board.IOPinService()) { insert your code here }

Die Richtungseinstellungen für die Pins 0...19 erfahren Sie durch

  let PinDirections = await Board.IOPinDirections()

Die Einstellung für einen einzelnen Anschluss n erfahren Sie mittels

  let PinDirection = PinDirections & (1 << n)

Ist das Ergebnis 0, so ist der Pin auf Ausgabe geschaltet, anderenfalls auf Eingabe.

Auf ähnliche Weise können Sie auch die Richtungen der Anschlüsse einstellen, allerdings immer nur für alle gemeinsam:

  await Board.IOPinDirections(PinDirections)

Die Moduseinstellungen für die Pins 0...19 erfahren Sie durch

  let PinModes = await Board.IOPinModes()

Die Einstellung für einen einzelnen Anschluss n erfahren Sie mittels

  let PinMode = PinModes & (1 << n)

Ist das Ergebnis 0, so arbeitet der Pin digital, anderenfalls analog.

Auf ähnliche Weise können Sie auch die Modi der Anschlüsse einstellen, allerdings immer nur für alle gemeinsam:

  await Board.IOPinModes(PinModes)

Die Werte aller auf Eingabe programmierten Pins erfahren Sie durch

  let PinDataList = await Board.IOPinData()

Das Ergebnis ist eine Liste von Objekten mit den Feldern Pin und Value: das Feld Pin gibt an, welcher Anschluss ausgelesen wurde, und Value enthält den gelesenen Wert.

  for (let i = 0, l = PinDataList.length; i < l; i++) {
let PinData = PinDataList[i]
console.log('Value of Pin ',PinData.Pin,' = ',PinData.Value)
}

Für digitale Pins ist Value entweder 0 oder 1, für analoge Pins bewegt er sich im Bereich 0...255.

Auf ähnliche Weise können Sie eine Liste für diejenigen auf Ausgabe programmierten Anschlüsse zusammenstellen, deren Werte Sie ändern möchten:

  let PinDataList = [
{ Pin:0, Value:0 }, // switch off analogue/digital pin 0
{ Pin:1, Value:1 }, // switch on digital pin 1
{ Pin:2, Value:128 } // set analogue pin 2 to 50%
]
await Board.IOPinData(PinDataList)

Event Handling

Eine laufende Übertragung von Änderungen an den auf Eingabe gestellten Anschlüssen starten Sie durch Registrieren eines Event Handlers

  Board.on('IOPinData', (PinDataList) => { insert your code here })

Sobald der letzte Event Handler für das Event IOPinData wieder entfernt wurde, endet die laufende Übertragung von Änderungen

  Board.off('IOPinData')

PWM-Ausgabe

Bis zu zwei Pins können zudem in einen PWM-Ausgabemodus versetzt werden und Pulsweiten-modulierte Signale ausgeben. Sie müssen dazu nur definieren

  • welcher Pin ein PWM-Signal ausgeben soll (zulässig sind die Pins 0...4 und 10)
  • wie hoch die Periodendauer sein soll (0...4294967295 Mikrosekunden) und
  • wie hoch die relative Tastdauer sein soll (0...1024, 0 schaltet PWM ab, 1024 = 100%)
  let PWMDataList = [
{ Pin:0, Period:25, Value:0 }, // switch off PWM for pin 0
{ Pin:1, Period:25, Value:512 } // 40kHz signal on pin 1 with 50% duty cycle
]
await Board.IOPinPWMControl(PWMDataList)

Die Belegung der einzelnen Anschlüsse und deren Bedeutung finden Sie in [3]

Abb. 1: Anschlussbelegung eines BBC micro:bit
Abb. 1: Anschlussbelegung eines BBC micro:bit

Literaturhinweise

[1] Lancaster University
BBC micro:bit Bluetooth Profile
(siehe https://lancaster-university.github.io/microbit-docs/ble/profile/)
Der BBC micro:bit stellt über Bluetooth LE eine Reihe von Services bereit, mit deren Hilfe der Einplatinen-Computer gesteuert werden kann. Auf der genannten Seite finden Sie eine vereinfachte Beschreibung dieser Dienste
[2] Lancaster University
Bluetooth Developer Studio Level 3 Profile Report
(siehe https://lancaster-university.github.io/microbit-docs/resources/bluetooth/bluetooth_profile.html)
Der BBC micro:bit stellt über Bluetooth LE eine Reihe von Services bereit, mit deren Hilfe der Einplatinen-Computer gesteuert werden kann. Auf der genannten Seite finden Sie eine Spezifikation des zugehörigen Bluetooth-Profiles.
[3] Micro:bit Educational Foundation
Edge Connector & micro:bit pinout
(siehe https://tech.microbit.org/hardware/edgeconnector/)
Die genannte Seite informiert über die Belegung der Anschlüsse auf dem Platinenstecker eines BBC micro:bit sowie deren interne Verwendung und Beschaltung.