Leguino

tl;dr? Zum GitHub-Projekt zur LEGO®-Robotik mit Arduino.

(Hinweis: LEGO® ist ein Markenzeichen der LEGO Group, die weder diese Website sponsort, noch autorisiert oder unterstützt.)

Einleitung

LEGO® Mindstorms ist eine wunderbare Plattform, um sich spielerisch der Robotik und Programmierung zu nähern. Kinder können ihre vorhandene LEGO®-Sammlung um Motoren und Sensoren ergänzen, und die grafische Programmier-Umgebung ist auf der einen Seite leicht zu verstehen, auf der anderen Seite enthält es bereits Konzepte wie Befehle, Schleifen, Verzweigung, Variablen und Ereignisse.

LEGO® Mindstorms ist jedoch (vor allem für den wissbegierigen Nachwuchs) nicht ganz günstig. Mein Sohn hatte zwar mittlerweile bereits eine schöne Sammlung LEGO®-Technic-Modelle mit Motoren, Lichtern und Schaltern, aber ohne Sensoren oder gar Programmierung.

Aber er hatte Interesse daran.

Also dachte ich mir: Versuchen wir mal die Lücke zu schließen und eine Open-Source-Plattform zu gründen, die auf LEGO®-Technic basiert, kostengünstig ist (Ziel <100€) und leicht verständlich. Hierfür schien Arduino bestens geeignet, aus folgenden Gründen:

  • Ein Arduino Nano kostet unter 20€, teilweise sogar unter 10€
  • Er lässt sich mit der LEGO®-Technic-Batterie betreiben
  • Er startet (im Gegensatz z.B. zum Raspberry Pi) in unter einer Sekunde, ein Umstand, der in Modellen mit einschaltbarer Batterie wichtig ist
  • Er hat genug Ein-/Ausgänge für ca. 10 Geräte

Die Programmierung erfolgt in C, was nicht so intuitiv ist, was man aber mit einer eigenen grafischen IDE (oder zumindest einer besseren API) kompensieren kann. Wir haben uns zunächst für Letzteres entschieden (siehe später).

Stromversorgung

Um sich der Sache experimentell zu nähern, eignen sich die Conrad-Breadboards hervorragend, Versuchs-Platinen zum Stecken, die das Standard-Lochmaß von 1/10-Zoll verwenden. Hierzu gibt es Drahtbrücken, die man in die Shield-Anschlüsse des Arduino stecken kann:

Auf der LEGO®-Seite müssen wir etwas improvisieren, da die Stecker und Geräte nicht zum Basteln ausgelegt sind. Von LEGO® gibt es Verlängerungskabel, die sich hierfür super eignen. Trennt man sie in der Mitte auf, erhält man einen Stecker und eine Buchse, jeweils mit offenen Drahtenden:

LEGO®-Technic verwendet 4-polige Kabel mit einer interessanten Belegung: 2 Drähte entsprechen Plus- und Minuspol der Batterie, wenn diese eingeschaltet ist, keine Spannung, wenn sie ausgeschaltet ist, und umgekehrte Polung (Minus und Plus), wenn sie rückwärts eingeschaltet ist. Die anderen beiden Drähte verhalten sich genauso, nur sind diese immer gleich gepolt (Plus und Minus).

An wechselnde Polung werden typischerweise Motoren angeschlossen, damit man mit den Schaltern die Drehrichtung steuern kann. (LED-)Lampen beispielsweise werden jedoch an die gleichpoligen Drähte angeschlossen.

Letztere Belegung ist auch für unser Projekt sehr praktisch, da wir hier unseren Arduino anschließen können.

Motoren und Lampen steuern

Als nächstes wollen wir mit dem Arduino LEGO®-Motoren und Lampen steuern. Hier haben wir drei Herausforderungen:

  • Die Ströme sind für den Arduino zu hoch (er liefert maximal 40mA pro Pin).
  • Die Spannung stimmt nicht (der Arduino liefert 5V, LEGO hat 9V).
  • Motoren benötigen steuerbare Pol-Umkehr (s.o.)

Die ersten beiden Probleme lassen sich mit MOSFETs lösen, Transistoren, die nahezu verlustfrei fremde Spannungen durchschalten können und dabei nahezu keinen Steuerstrom verbrauchen. Außerdem kann man die MOSFETs mit PWM betreiben, einer Technik, die durch schnelles Ein- und Ausschalten fast stufenlos verminderte Leistung ermöglicht, ohne dass Verlustleistung entsteht.

Für die Pol-Umkehr nehmen wir bistabile Relais, damit wir nur während des Richtungswechsels Strom verbrauchen. Legt man ein bistabiles Relais eine Spannung an, schaltet es auf die eine Position, nimmt man die Spannung weg, bleibt es aber in dieser Position. Eine umgekehrte gepolte Spannung schaltet es wieder in die andere Position.

Um einen MOSFET zu steuern, benötigen wir einen Arduino-Pin, für das Relais zwei:

Wenn wir stets ein Relais zur Zeit wechseln, können wir für 3 Relais mit 4 Pins auskommen:

Wir wollen 3 umkehrbare, sowie 2 nicht umkehrbare Ausgänge anbieten, da wir damit den Arduino ideal ausnutzen können. Alle 5 Ausgänge sollen PWM-steuerbar sein.

Wir schließen die MOSFETs und Relais daher wie folgt an:

  • Pin 2: Relais common
  • Pin 3: MOSFET A
  • Pin 5: MOSFET B
  • Pin 6: MOSFET C
  • Pin 7: Relais A
  • Pin 8: Relais C
  • Pin 9: Relais B
  • Pin 10: MOSFET D
  • Pin 11: MOSFET E

Die Relais werden wie folgt angesteuert, um sie jeweils auf Vorwärts oder Rückwärts umzuschalten, bzw. sie so zu belassen, wie sie sind:

Pin 7 (A) Pin 9 (B) Pin 8 (C) Pin 2 (common) Effekt
0 0 0 0 keiner (stabil)
1 0 0 0 Relais 1 vorwärts
0 1 1 1 Relais 1 rückwärts
0 1 0 0 Relais 2 vorwärts
1 0 1 1 Relais 2 rückwärts
0 0 1 0 Relais 3 vorwärts
1 1 0 1 Relais 3 rückwärts

Sensoren

Nun kommen wir zu den Sensoren. Hierfür verwenden wir die Analog-Eingänge des Arduinos. Dies hat folgende Vorteile:

  • Die Eingänge verstehen ein breites Spektrum an Spannungen von 0V bis 5V.
  • Wir brauchen keine Ausgänge belegen.

Allerdings sind die Analog-Eingänge träger als die digitalen. Dies nehmen wir in Kauf.

Wir können verschiedene Sensoren an die Eingänge anschließen:

  • Taster und Schalter
  • Drehregler
  • IR-Lichtschranken
  • Ultraschall-Entfernungs-Sensoren
  • uvm.

Die Eingänge sind (wie meist bei Mikro-Controllern) hochohmig, d.h. man darf sie nicht offen betreiben, ansonsten kommt es aufgrund der Umgebungsstrahlung zu Messfehlern. Für einen Taster oder Schalter verwendet man daher Pull-Up- oder Pull-Down-Widerstände:

Alle Arduinos haben mindestens 6 Analogeingänge, daher wollen wir diese Zahl als Design-Grundlage nehmen.

Fernbedienung, Reset, Play

Damit die Steuerung nicht sofort bei Stromversorgung startet, und damit wir eine unkontrolliert laufende Steuerung abbrechen zu können, spendieren wir noch zwei feste Taster, nämlich Reset/Stopp (rot) und Play (grün), die wir mit dem Aruduino-Reset-Pin, sowie einem Digitaleingang verbinden.

Außerdem ist es praktisch, die Schaltung per Fernbedienung steuern zu können. Hierfür schließen wir einen IR-Sensor mit Digitalausgang ebenfalls an einen Digitalpin an. Hierfür existiert bislang jedoch noch keine Programmierung im Leguino-Projekt, nur Erfahrung in anderen Projekten.

Gesamt-Schaltplan

Insgesamt sieht so also nun die Gesamtverdrahtung und Pin-Belegungn aus:

Gehäuse

Nachdem wir nun die Schaltung und Verdrahtung zusammenhaben, brauchen wir noch ein Case, das sich in die LEGO®-Welt einreiht.

Für die Analog-Eingänge brauchen wir außerdem eine eigene Steckerart, da LEGO®-Technic wie oben erwähnt nur Aktoren (Motoren, Lichter) vorsieht, sowie fest verdrahtete Schalter nutzt. Wir wählen Modelleisenbahn-Stecker, da diese günstig, kombinierbar und gut handhabbar sind.

Die 2×1-Lochsteine lassen sich mit etwas aufbohren mit Modelleisenbahn-Steckern versehen, aber auch Taster und LEDs lassen sich in ihnen unterbringen. Die Ausgänge setzen wir auf unser Case einfach oben drauf.

Hier ein paar Bilder vom Aufbau des Cases, bis hin zur Fertigstellung:

Kosten

Folgende Kosten entstehen beim Bau in etwa:

  • Arduino Nano: 12€
  • Relais: 10€
  • MOSFETs: 5€
  • Div. weitere Elektronik: 25€
  • LEGO®-Gehäuse: 5€
  • Power-Functions-Stecker: 20€
  • Summe: Ca. 80€

Damit haben wir das Ziel, unter 100€ zu bleiben, erreicht.

Software

Nachdem wir die Hardware für das Leguino-Projekt realisiert haben, kommen wir zur Software.

Wie bereits erwähnt, wäre die direkte Programmierung mit Arduino-C-Code zwar möglich, aber wenig intuitiv. Teilweise müssen drei Pins für einen Ausgang angesteuert werden, und dabei sind Zustände zu speichern (ist das Richtungs-Relais bereits korrekt gepolt?). Andere gleichzeitig angesteuerte Ausgänge müssen berücksichtigt werden, denn das gleichzeitige Ansteuern von zwei Relais mit unterschiedlciher Richtung ist mit unserer Schaltung nicht möglich.

Außerdem ist es angenehm, in angeschlossenen Geräten zu denken, z.B.:

  • Licht an bzw. aus
  • Motor vorwärts, stopp, halbe Fahrt, rückwärts etc.
  • Kettenantriebe bestehen sogar aus zwei Ausgängen:
    • Volle Fahrt vorwärts bzw. rückwärts
    • Halbe Fahrt nach links
    • Auf der Stelle rechts herum drehen
    • Stopp

Ebenso wünscht man sich zeitliche Steuerung, beispielsweise „2 Sekunden Fahrt“ oder „Licht blinkt einmal pro Sekunde“, ohne die Hauptschleife der Programmierung mit entsprechender Kontrollfluss-Logik zu belasten.

Dasselbe gilt für die Eingäge. Eine starke Sprache ist wünschenswert, die Fragen zulässt wie:

  • Wurde der Taster gedrückt?
  • Welche Stellung hat der Regler?
  • Welche Entfernung hat ein Gegenstand von dem Ultraschall-Sensor?

Folgende API wollen wir daher für Ausgänge (Motoren, Lichter, etc.) anbieten:

Und diese API soll es für Sensoren geben:

Ein einfaches Programm, das diese APIs verwendet, könnte so aussehen:

Beispiele für jede Art von Aktor und Sensor sind im GitHub-Projekt enthalten.

Projekt „Roboter-Hund“

Folgenden Roboter haben mein Sohn und ich mit Leguino gebaut. Er hat Entfernungssensoren und nähert sich damit seinem vorliegenden Objekt auf 30cm wie ein Hündchen seinem Herrchen.

Projekt „Süßigkeiten-Automat“

Für ein Schulprojekt hat mein Sohn eine Maschine gebaut, die bei Geldeinwurf Süßigkeiten ausspuckt. Damit hatte er sogar 2 Stände an Schule und Forschungsanstalt, die Erlöse gingen in ein Projekt zur Rettung von Bienen.

Download und Mitmachen

Lust, das Projekt nachzubauen? Oder Verbesserungen, Erweiterungen, Fotos beisteuern?Alle Source-Codes, Schaltpläne und Anleitungen sind als GitHub-Projekt veröffentlicht:

https://github.com/TheReincarnator/leguino

Viel Spaß beim Downloaden und Forken!