Im Unterverzeichnis Windows 7 Driver liegt der Treiber der seriellen USB-Schnittstelle für das gleichnamige Betriebssystem. Die anderen Dateien dienen dazu, einen Mac vom Zumüllen der winzigen Platte mit Dateien abzuhalten. Verwenden Sie ausschließlich Linux, dürfen Sie alle Dateien außer main.py und lib löschen, um so Platz zu schaffen.

Abbildung 2: Nach dem Einbinden des Trinket M0 als Laufwerk sehen Sie auf der kleinen Festplatte das Programm main.py, das der Controller nach dem Starten automatisch ausführt.
Da sich der Controller als normaler USB-Speicher am Hostrechner meldet, sollten Sie vor dem Abziehen das Laufwerk auswerfen beziehungsweise unter Linux mit dem Befehl aus Zeile 4 von Listing 1 aushängen. Das gilt auch, wenn Sie den Reset-Button betätigen: Er trennt das Board kurzzeitig vom Strom, was einem kurzen Ein- und Ausstecken entspricht.
Ohne das Aushängen führt das unter Linux dazu, dass der Trinket jetzt einen anderen Gerätenamen erhält, der Kernel aber immer noch meint, das alte Device wäre eingehängt. Falls das einmal passiert, reparieren Sie den Zustand mit dem Befehl aus der letzten Zeile von Listing 1.
Listing 1
### Trinket einhängen $ sudo mount -o sync /dev/sda1 /mnt ### Trinket aushängen $ sudo umount /mnt ### Trinket nach Reset aushängen sudo umount -f /mnt
Firmware-Update
Bei der Firmware des Trinkets handelt es sich um eine spezielle Python-Variante mit Namen CircuitPython. Dahinter verbirgt sich ein Fork von MicroPython, den Adafruit für seine Boards aktiv weiterentwickelt. Das Modell im Test hatte ab Werk die Version 2.0.0 an Bord, es stand als Update jedoch schon die Version 3.0.0 bereit. Für CircuitPython 4.0.0 lag zu Redaktionsschluss bereits eine Alpha-Version vor.
Für ein Firmware-Update drücken Sie nach dem Aushängen des Laufwerks mit dem Programm zweimal den Reset-Taster. Das Board wechselt dann in den Wartungsmodus, und es erscheint ein neues Laufwerk mit Label TRINKETBOOT. Unter Linux hängen Sie das Laufwerk wie oben beschrieben mit der Sync-Option ein.
Dann laden Sie via Github die aktuelle Firmware [2] herunter, eine Datei mit der Endung .uf2). Anschließend kopieren Sie diese per Kommandozeile oder über einen Dateimanager auf den Datenträger. Schließlich hängen Sie das Laufwerk wieder aus. Das Board führt nach dem Kopieren einen Reset durch, was die neue Firmware aktiviert.
Zumindest beim ersten Wechsel von CircuitPython 2 auf Version 3 müssen Sie außerdem die Bibliotheken im Unterverzeichnis lib/ des Laufwerks CIRCUITPY austauschen, da sich das Format geändert hat. Dazu laden Sie via Github das Bundle [3] mit der Bibliothek herunter, entpacken es und ersetzen alle Dateien in lib/ durch die neue Version. Ein solches Update empfiehlt sich auch bei unerklärlichen Problemen mit Programmen: Die Entwickler pflegen die Bibliotheken laufend.
Spannungsmessung
Als Anwendungsbeispiel dient ein kleines Programm [4] zum Messen von Spannungen (Listing 2). Den Pin 2 konfigurieren Sie dazu als analogen Input (Zeile 36).
Listing 2
import board
from digitalio import DigitalInOut, Direction, Pull
from analogio import AnalogOut, AnalogIn
import time
use_rtc = False
if use_rtc:
import busio as io
import adafruit_ds3231
i2c = io.I2C(board.SCL, board.SDA)
rtc = adafruit_ds3231.DS3231(i2c)
# ---- Konfiguration der Pins
# Rote LED
led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT
# Analoger Input auf D1
v_pin = AnalogIn(board.D1)
# Digitaler Input mit Pulldown auf D3
button = DigitalInOut(board.D3)
button.direction = Direction.INPUT
button.pull = Pull.DOWN
# Digitaler Input mit Pullup auf D4
# (Default ist keine serielle Konsole)
usbcon = DigitalInOut(board.D4)
usbcon.direction = Direction.INPUT
usbcon.pull = Pull.UP
# --- Analog-Input lesen und konvertieren
def get_voltage(pin):
mult = 5.0/3.0 # Faktor Spannungsteiler
return (pin.value*mult*3.3)/65536
# --- Startkonfiguration
active = False
is_pushed = False
use_usbcon = usbcon.value == 0
# --- Main-Loop
if use_usbcon:
print("# starting main-loop")
start = time.monotonic()
last = start
while True:
if button.value and not is_pushed:
active = not active # toggle state
is_pushed = True # check only rising
time.sleep(0.01) # debounce
elif not button.value and is_pushed:
is_pushed = False # button is released
if not active:
led.value = 0
continue
else:
led.value = 1
# Analogen Input lesen und jede Sekunde
# den Messwert auf die Konsole schreiben
now = time.monotonic()
if now - last >= 1:
voltage = get_voltage(v_pin)
if use_rtc:
t = rtc.datetime
if use_usbcon:
if use_rtc:
print("%04d%02d%02d-%02d:%02d:%02d %0.2f" % (t.tm_year,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min,t.tm_sec,voltage))
else:
print("(%0.2f,)" % voltage)
last = now
Dass der Trinket mit 3,3 Volt Betriebsspannung arbeitet, erleichtert zwar die Verbindung zum RasPi, schränkt den Spannungsbereich jedoch ein. Um trotzdem einen größeren Bereich zu messen, schließen Sie den Messpunkt über einen Spannungsteiler mit 10 kOhm gegen Pin 2 und 15 kOhm gegen Masse an (Abbildung 3). Das verringert die gemessene Spannung um den Faktor 15/(10+15), der Messbereich erweitert sich also auf 5,5 Volt (25/15*3,3V = 5,5V).

Abbildung 3: Mit einer zusätzlichen Schaltung erweitern Sie den Bereich für die Spannungsmessung am Trinket M0, der sich von Haus aus nur für Spannungen bis 3,3 Volt eignet.
Einen weiteren Pin konfigurieren Sie als digitalen Input (Zeilen 24 bis 26): Daran hängt ein Taster, mit dem Sie die Messung ein- und ausschalten. Ein zusätzlicher digitaler Input dient zum Aktivieren der seriellen USB-Konsole (ab Zeile 30 sowie ab Zeile 44).
Die serielle USB-Schnittstelle erleichtert zwar das Entwickeln von Programmen und das Übertragen von Messwerten an einen Host. Wenn sie dort aber niemand ausliest, blockiert irgendwann das Programm auf dem Trinket. Deshalb schreibt das Programm mit print() nur dann auf die Konsole, wenn Pin 4 mit GND verbunden ist.
Es wäre praktisch, das Messergebnis gleich auf einem Mini-Display zu visualisieren. Tatsächlich vermag das Board diverse Displays anzusteuern. Allerdings frisst schon der Code dafür so viel vom Hauptspeicher, dass für das Messprogramm kein Platz mehr bleibt. Daher sendet das Programm das Ergebnis über die serielle Konsole an den Host, an dem der Trinket hängt (Zeile 75).





