Roboter
Informationen und Anleitungen zu den Bauteilen und den Zusammenbau des SMARS-Roboters
- Allgemeine Hinweise
- Elektronische Bauteile für den Roboterbau
- Die LED
- Der Widerstand
- Der Raspberry Pi Pico
- Der Transistor
- Der Motortreiber
- Der Spannungswandler
- Das Wukong 2040 Board
- Programmierung des Raspberry Pi Pico mit Micropython
- Zusammenbau des SMARS-Roboters
- Das Steckbrett mit Raspberry Pi Pico und Abdeckplatte
- Gehäuse und Räder
- Anschluss der Motoren
- Der Ultraschallsensor
- Der komplette Roboter
- Der Kettenantrieb
- Zusammenbau von Crawly
- Zusammenbau von Walky
- Bibliotheken für die Roboter
- Motorsteuerung
- Ultraschallsensor
- Infrarotsteuerung
- Servosteuerung
- Das komplette Modul "robotlibrary"
- Codebeispiele
- Fehlerbehebung
- 3D-Konstruktionsdateien für die Roboter
Allgemeine Hinweise
Umgang mit Elektronikteilen
Die hier veröffentlichten Anleitungen sind nicht als alleinige Anleitung gedacht, sondern sollen immer zusammen mit dem Unterricht benutzt werden. Sie dienen als Gedächtnisstütze oder für diejenigen, die einzelne Stunden verpasst haben, als Möglichkeit, beim Aufbau aufzuholen.
Grundsätzlich gilt, dass alle verbauten elektronischen Teile sehr empfindlich gegen Verpolung und zu hohe Spannungen sind. Daher sollte man sich nach dem Hinzufügen eines Bauteils immer vergewissern, dass alles richtig angeschlossen ist. Am besten zeigt man die Anschlüsse immer noch jemand anderem.
Hier einige Beispiele für explodierende Elektronikteile:
Allgemeine Tipps für die Programmierung
- Python und Giropython definieren Programmierblöcke über Einrückungen. Es ist also wichtig, dass von Anfang an darauf geachtet wird, Einrückungen immer sauber und vor allem einheitlich zu machen. Bei einer falschen Einrückung taucht in der Fehlermeldung das Wort
Indent
auf. - Auch dürfen Blöcke nicht leer sein, da sonst die Einrückung nicht erkannt werden kann. Wenn man also Code schreibt und erst einmal etwas anderes implementieren möchte, dann schreibt man den Platzhalter
pass
in den Code. - Bevor man Code auf den Roboter lädt, muss dieser getestet werden. Dazu muss das Programm in Thonny gestartet werden, damit man Fehlermeldungen und Debug-Nachrichten lesen kann. Wer ungetesteten Code hochlädt und dann erwartet, dass der Roboter funktioniert, ist selber Schuld.
- Eine Python-Datei wird auf dem Pico automatisch gestartet, wenn sie
main.py
heißt. Das bedeutet aber auch, dass das Programm gestartet wird, wenn man den Pico am Rechner über USB einsteckt. Das kann beim Testen zeitraubend sein, da man immer erst das Programm beenden muss. In der Testphase bietet es sich also an, einen anderen Namen für die Startdatei zu wählen.
Elektronische Bauteile für den Roboterbau
Die LED
Die LED oder Leuchtdiode hat heute die Glühlampe fast vollständig verdrängt. Und das hat auch gute Gründe. Der Wirkungsgrad einer LED liegt bei 30–40 %. Der Wirkungsgrad einer Glühlampe liegt bei ca. 5 % ¹. Das heißt, dass eine LED 30–40 % der eingesetzten Energie in Licht umwandelt. Eine normale Glühlampe ist damit zu 95 % eine Heizung und nur zu 5 % ein Leuchtmittel. Die LED ist damit immer noch nicht perfekt, aber das Beste, das es zurzeit für die Lichterzeugung gibt. Außerdem lebt sie länger als die Glühlampe, die aufgrund ihrer Konstruktion schnell altert.
Die Polung der LED
Eine LED muss richtig gepolt werden, um zu leuchten. Wird sie verpolt, kann sie dabei kaputtgehen. Das lange Beinchen heißt Anode und ist die positive Seite. Die kurze Seite ist die Kathode und die negative Seite oder Masse. Eine LED muss immer zusammen mit einem Widerstand geschaltet werden.
Wie eine LED mit dem Pico an- und ausgeschaltet werden kann, steht hier
Der Widerstand
Der Widerstand ist dafür da, andere elektronische Bauteile vor Überlastung zu schützen. Es gibt ihn in mit sehr vielen verschiedenen Widerstandswerten. Diese sind mit einem Farbcode angegeben.
Der Raspberry Pi Pico
Der Pico ist das Herzstück des Roboters, denn er führt den Code aus, der den Roboter steuert. Der Pico wird mit Micropython programmiert, das eine kleinere Ausgabe des großen Pythons ist.
Der Pico ist, wie die meisten elektronischen Teile, sehr empfindlich gegen Verpolung oder Überlastung oder Kurzschlüsse. Daher muss man immer sehr sorgfältig alle Verbindungen überprüfen, bevor eine Spannung angelegt wird.
Detaillierter Pinout-Plan des Pico zum Download
Er wird über einen Mikro-USB-Anschluss an den Computer angeschlossen. Als Entwicklungsumgebung benutzen wir Thonny.
Um die Pin-Anschlüsse ansteuern zu können, muss zunächst aus der Bibliothek machine Pin importiert werden:
from machine import Pin
Nicht alle Pins haben dieselben Fähigkeiten. Welcher Pin was kann, steht im detaillierten Pinout-Plan. Generell sollten für den Roboterbau die angegebenen Pins verwendet werden. Diese sind auf jeden Fall geeignet für die benötigte Funktion und die Fehlersuche wird erleichtert, wenn man nicht jedes Mal auch die Zuordnung der Pins überprüfen muss.
Der Transistor
Das Schaltzeichen
Transistoren gibt es in vielen verschiedenen Ausfertigungen. Dies ist ein Beispiel.
Das heißt, mit einem Transistor kann man mit einer niedrigen Spannung eine größere Spannung regulieren. Das kann ein einfacher Schaltvorgang sein oder die relative Regelung einer Spannung. Damit ist der Transistor in seiner Grundfunktion ein Verstärker. In einer digitalen Schaltung wird der Transistor auch wieder nur an- oder ausgeschaltet. Die Regelung der Helligkeit einer LED oder der Geschwindigkeit eines Motors erfolgt genauso wie ohne Transistor.
Für den Roboterbau werden wir nicht direkt mit einem Transistor arbeiten. Sie sind aber Teil fast aller Bauteile, die verwendet werden.
Der Transistor ist die Grundvoraussetzung, dass es moderne Computer gibt.
Ein Transistor ist ein elektronisches Halbleiter-Bauelement zum Steuern oder Verstärken meistens niedriger elektrischer Spannungen und Ströme. Er ist der weitaus wichtigste „aktive“ Bestandteil elektronischer Schaltungen, der beispielsweise in der Nachrichtentechnik, der Leistungselektronik und in Computersystemen eingesetzt wird. Besondere Bedeutung haben Transistoren – zumeist als Ein/Aus-Schalter – in integrierten Schaltkreisen, was die weit verbreitete Mikroelektronik ermöglicht.
Die Bezeichnung „Transistor“ ist ein Kofferwort des englischen transfer resistor, was in der Funktion einem durch eine angelegte elektrische Spannung oder einen elektrischen Strom steuerbaren elektrischen Widerstand entspricht. Die Wirkungsweise ähnelt der einer entsprechenden Elektronenröhre, nämlich der Triode.
Quelle: Wikipedia: https://de.wikipedia.org/wiki/Transistor
Der Motortreiber
Aktuelle Variante
Dieser Motortreiber beinhaltet gleichzeitig einen Spannungswandler, der genau 5V Gleichspannung liefert.
Vorherige Variante
Dieser Typ Motortreiber ist häufiger mal durchgebrannt. Daher wurde er durch ein stärkeres Modell ersetzt.
Der Spannungswandler
Der Spannungswandler wird mittlerweile nicht mehr benötigt, da dieser im neuen Motortreiber integriert ist.
Mit dem Spannungswandler können wir eine Gleichspannung in eine niedrigere Spannung umwandeln. Da wir für die Motoren 6-9V benötigen, der Pico und die elektronischen Komponentenn aber nur 3,3V - 5 V vertragen, betreiben wir den Roboter mit einer 9V Batterie und nutzen den Spannungswandler für den Pico. Der Pico wiederum stellt 3,3V für den Betrieb der anderen Teile bereit.
Der Spannungswandler muss vor dem Anschluss an den Pico auf die richtige Spannung eingestellt werden. Dafür haben wir Spannungsmessgeräte.
Das Wukong 2040 Board
Das Wukong 2040 Board wird für die Roboter „Walky“ und „Crawly“ benötigt. Es bietet praktische Anschlüsse für bis zu 12 Servomotoren und 4 Motoren. Außerdem bietet es zwei farbige LEDs, zwei Druckknöpfe und einen Buzzer. Die Stromversorgung läuft über einen 3,7V-Akku, der in dem Board aufladbar ist.
Als Gehirn dient natürlich wieder ein Raspberry Pi Pico.
Programmierung des Raspberry Pi Pico mit Micropython
Schritt-für-Schritt-Anleitung, um einige der vielen Möglichkeiten des Picos kennenzulernen.
LEDs schalten
Die interne LED
Der Pico hat eine interne LED, die folgendermaßen angesteuert werden kann:
import utime
from machine import Pin
#led=Pin("LED", Pin.OUT) # Für den Pico mit eingebautem WLAN
led=Pin(25, Pin.OUT) # Für den Pico ohne WLAN
led.value(1)
utime.sleep(1)
led.value(0)
Soll die LED unabhängig vom Programmablauf blinken, dann kann man das mit einem Timer realisieren.
from machine import Pin,Timer
# led=Pin("LED", Pin.OUT) # Für den Pico mit eingebautem WLAN
led=Pin(25, Pin.OUT) # Für den Pico ohne WLAN
timer = Timer()
timer.init(freq=2, mode=Timer.PERIODIC, callback=lambda t: led.toggle())
Soll der Timer beendet werden, so kann man das mit dem Befehl timer.deinit()
erreicht werden.
Möchte man mehr Kontrolle haben oder komplexere Funktionen einbauen, dann geht das so:
import utime
from machine import Pin,Timer
# led=Pin("LED", Pin.OUT) # Für den Pico mit eingebautem WLAN
led=Pin(25, Pin.OUT) # Für den Pico ohne WLAN
led.value(1)
utime.sleep(1)
led.value(0)
def blink(timer):
led.toggle()
timer = Timer()
Timer().init(freq=2, mode=Timer.PERIODIC, callback=blink)
Ein Timer läuft auch nach dem Ende des Programms weiter. Also nicht wundern, wenn es weiter blinkt.
Aufgabe: Die LED zum Blinken bringen.
Eine externe LED
Das war zwar schon spannend, aber nun wollen wir eine externe LED an den Pico anschließen. Dazu benötigen wir eine LED, einen 100 Ω Widerstand sowie zwei Kabel. Stecke die Schaltung genau so zusammen, wie abgebildet. Achte vor allem darauf, dass die LED richtig herum ist.
Hier ist der dazugehörige Schaltplan:
Externe LED mit Transistor
Der Pico liefert an den Pins nur eine Spannung von 3,3 Volt und die Stromstärke ist auch nicht sehr hoch. Es ist leicht möglich, die Anschlüsse zu überlasten, zwar nicht mit nur einer LED, jedoch bleibt es dabei ja nicht. Daher müssen Transistoren verwendet werden.
Es gibt zwei mögliche Schaltungen für die LED mit Transistor. Der Unterschied ist nur, ob die Schaltung auf Anoden- oder auf Kathodenseite geschieht.
Regelung der Helligkeit
Egal, ob du die LED mit oder ohne Transistor betreibst, so ist die Helligkeit bislang immer die gleiche. Glühlampen lassen sich sehr einfach dimmen, indem man die Spannung regelt. Bei der LED funktioniert das nicht, da die Spannung an der LED immer dieselbe ist. Die LED ist nämlich kein ohmsches Bauteil. Außerdem haben wir mit dem Pico die Schwierigkeit, dass er ein digitales Gerät ist und bekanntermaßen kennen digitale Geräte nur 1 und 0 oder an und aus. Wie lässt sich damit also die Helligkeit regulieren?
Ampelschaltung mit LEDs
Ampelschaltung
Verwende die LED-Ampel, um eine Ampelschaltung zu programmieren. Schaltet dann mehrere Ampeln zu einer Kreuzung zusammen, indem ihr die Picos miteinander kommunizieren lasst. Dazu müsst ihr einen Pin auf dem Pico, der Befehle erhält, als Eingangspin definieren.
Empfange Daten auf Pin 16 und blinke mit der internen LED
from machine import Pin
sensor=Pin(16, Pin.IN, Pin.PULL_UP)
led=Pin(25, Pin.OUT)
while True:
while sensor.value():
led.value(1)
led.value(0)
Sende Daten mit Pin 15 und blinke mit der internen LED
import utime
from machine import Pin
#led=Pin("LED", Pin.OUT) # Für den Pico mit eingebautem WLAN
led=Pin(25, Pin.OUT) # Für den Pico ohne WLAN
sender=Pin(15,Pin.OUT)
while True:
led.value(1)
sender.value(1)
utime.sleep(1)
led.value(0)
sender.value(0)
utime.sleep(1)
Nur einer der beiden Picos muss über USB an Strom angeschlossen werden. Beide Programm werden unter dem Namen "main.py" auf dem Pico abgespeichert, dann laufen die Programme automatisch, sobald die Picos Strom bekommen.
Knopfsteuerung der Ampel
Für die Programmierung eines Ampelknopfes, muss man den Knopf entprellen, damit keine Geisterbewegungen registriert werden. Ein minimales Codebeispiel ist dieses:
from machine import Pin
import utime
button = Pin(15, Pin.IN, Pin.PULL_DOWN)
pressed = False
num_pressed = 0
last_pressed = 0
DEBOUNCE_WAIT = 100
def button_handler(pin):
global pressed, num_pressed, last_pressed #mit dem Befehl global teilt man Python mit, dass man die Variabel verwenden möchte, die außerhalb der Funktion initialisiert wurde.
while utime.ticks_diff(utime.ticks_ms(), last_pressed) < DEBOUNCE_WAIT: # Hier wird verhindert,dass mehrere Auslösungen hintereinander registriert werden.
pass
last_pressed = utime.ticks_ms()
if not pressed:
while utime.ticks_diff(utime.ticks_ms(), last_pressed) < DEBOUNCE_WAIT:
pass
if pin.value() == 1:
pressed=True #Damit kann im Programmablauf der Knopfdruck registriert werden.
num_pressed +=1
print(pin.value(), "number presses: ", num_pressed)
last_pressed = utime.ticks_ms()
pressed=False # Dies hier eher im weiteren Programmablauf verwenden.
button.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
# Hier weiterer Programmablauf
while True:
pass
Programmiergrundkurs in Python
Der Motor
Ein Motor wird genauso gesteuert wie eine LED. Man kann ihn entweder einfach an- und ausschalten, oder mithilfe der Pulsweitenmodulation die Geschwindigkeit regeln. Probiert es einfach einmal aus. Da ein Motor deutlich mehr Leistung hat als eine LED, kann man den Raspberry Pi Pico schnell überlasten. Daher betreiben wir den Motor nur über einen Transistor. Es sorgt dafür, dass das Steuersignal des Picos verstärkt von der 9V Batterie an den Motor geleitet wird. Aber Achtung: Der Motor ist für dauerhaft 6V ausgerichtet und sollte daher nicht zu lange mit 9V betrieben werden.
Für diese Schaltung könnt ihr die Schaltung der LED mit Transistor ohne den Widerstand verwenden.
Der Code für diese Steuerung ist genauso wie für eine LED. In dem Schaltbild wird der Pin 15 benutzt.
Richtungssteuerung
Wie könnte man nun die Drehrichtung des Motors ändern, ohne die Kabel umzustecken?
Überlegt erst einmal und dann schaut ihr euch das nächste Bauteil an:
Der Ultraschallsensor
Schließt den Ultraschallsensor an den Pico an:
Die Softwarebibliothek für den Ultraschallsensor
Der Infrarotsensor
Der IR-Sensor wird folgendermaßen an den Pico angeschlossen. Der OUT-Pin kann natürlich auch geändert werden.
So wird der Infrarotsensor ausgelesen:
from machine import *
import utime
# Der Pin für den Infrarotsensor wird initialisiert.
ir=Pin(16,Pin.IN,Pin.PULL_UP)
while True:
print(ir.value()) #Es wird einmal der Wert ausgegeben, der am Pin anliegt.
while ir.value() == 0: # Solange der Wert 0 bleibt, ändert sich die Anzeige nicht.
utime.sleep_ms(50)
print(ir.value()) # Ist/Wird der Wert 1, wird erneut auf der Konsole ausgegeben.
while ir.value() == 1:
utime.sleep_ms(50) # Solange der Wert 1 bleibt, ändert sich die Anzeige nicht.
Zusammenbau des SMARS-Roboters
In diesem Kapitel werden die mechanischen Aufbauschritte erklärt.
Das Steckbrett mit Raspberry Pi Pico und Abdeckplatte
Es gibt verschiedene Varianten von Platten, auf denen das Steckbrett aufgeklebt ist.
Aktuelle Variante
Diese Variante ist für den „Theo III“!!
In dieser Variante wird das Steckbrett quer aufgeklebt. Die Abdeckplatte wir von hinten in den Roboter eingeschoben.
Ältere Varianten
älteste Variante
Die ältere Variante wird von oben auf das Gehäuse gesteckt.
neuere Variante
Die neuere Variante wird von hinten in das Gehäuse eingeschoben.
Gehäuse und Räder
Es gibt mehrere Varianten von Gehäusen für die SMARS-Roboter. Das aktuellste ist der „Theo III“.
Theo III
Ein neu gedrucktes Gehäuse enthält noch einige Stützstrukturen um die Halterungen für die passiven Räder und in dem Schlitz für den Schalter. Diese müssen zunächst entfernt werden. Das Gehäuse wird mit den passiven Rädern montiert ausgeteilt. Diese sollten nicht mehr entfernt werden, da das Gehäuse dabei brechen kann. Generell ist darauf zu achten, dass die Seitenwände nicht belastet werden, da sie schnell abbrechen können.
Es gibt bei dem Gehäuse ein vorne und hinten. Hinter erkennt man an der Einprägung „Theo III“. Dort befindet sich auch der Schalter. Beim Einsetzen der Motoren ist darauf zu achten, dass der Motor mit den längeren Kabeln nach vorne kommt.
Für die aktiven Räder müssen zunächst die Motoren eingesetzt werden. Im Idealfall rasten die Motoren ein und sind dann schon fest. Wenn der 3D-Druck ungenau war, kann es sein, dass die Motoren nur sehr schwer einrasten oder gar nicht. Die Löcher an den Rädern, in die die Motorwellen eingesteckt werden, haben, genau wie die Motorwellen, eine abgeflachte Seite. Diese müssen zusammengebracht werden. Es kann sein, dass die Motorwelle nicht passt. In diesem Fall muss das Loch vorsichtig erweitert werden. Hier kann es schnell passieren, dass das Loch zu groß wird. Dann hilft nur noch Klebstoff.
Ältere Versionen
Gehäuse für Kettenfahrzeug
Das Gehäuse kann direkt nach dem Druck noch einige Rückstände der Stützstrukturen enthalten. Das bedeutet vor allem, dass die Löcher für die Motorwellen zu sind und dass die Aufnahme für die passiven Räder noch gesäubert werden müssen. Grundsätzlich muss man beim Entfernen von Material sehr vorsichtig sein, da man schnell zu viel weggenommen hat.
Als Erstes sollten die passiven Räder aufgesteckt werden. Dazu wird das Gehäuse hochkant flach auf die Tischfläche gelegt und dann werden die Räder aufgesteckt. Dies kann sehr schwer sein. Da die Gehäuse leicht brechen können, muss man darauf achten, keinen Druck auf die oberen Ränder auszuüben. Sind die Räder erst einmal aufgesteckt, sollten sie nicht mehr entfernt werden.
Gehäuse für Gummireifenfahrzeug
Diese Gehäuse sollten sofort einsatzbereit sein. Dennoch sollte man vorher schauen, ob es noch irgendwo Überbleibsel von Stützstrukturen gibt, die vorher entfernt werden sollten.
Die passiven Räder haben keine Gummireifen und werden mithilfe von kurzen Stiften auf den Achsen befestigt.
Aktive Räder an beiden Gehäusetypen
Die 9V-Batterie wird zwischen die Motoren gelegt. Der Clip sollte auch schon befestigt werden. Dabei ist darauf zu achten, dass sich die blanken Kabelenden nicht berühren können (Isolierband). Die Kabel der Motoren sollten durch die Halterungen für die 9V-Batterie geführt werden. Damit kann der SMARS Roboter schon auf eigenen Rädern stehen.
Anschluss der Motoren
Folgende Verbindungen werden benötigt, um die Motoren zum Laufen zu bringen:
Die 9V Batterie versorgt die Motoren mit Strom. Die vier Datenkabel IN1, IN2, IN3, IN4 steuern den Motor. Dabei sind IN1 und IN2 für den einen und IN3 und IN$ für den anderen Motor zuständig. Diese steuern die Brückenschaltung im Motortreiber. Die Richtungssteuerung erfolgt, indem die Signale an den Pins vertauscht werden. Ein Pin muss aus sein, der andere ist an. Wird dieser mithilfe der PWM-Modulation gesteuert, lässt sich auch die Geschwindigkeit regulieren. Hierfür kann dann die Bibliothek für die Motorsteuerung benutzt werden.
Der Ultraschallsensor
Der Ultraschallsensor wird von oben in die Halterung geschoben und danach wird das Gehäuse von vorne aufgesteckt. Die beiden Augen des Sensor schließen dann bündig mit dem Gehäuse ab. Die Halterung wird dann von oben auf das Gehäuse vorne oder hinten aufgeschoben und die Anschlüsse für die Kabel müssen nach oben geführt werden. Für den Betrieb des Ultraschallsensors verwendet man eine Bibliothek.
Für die neueste Version des Roboters (Theo III) gibt es verschiedene Varianten von Halterungen, die ein Verstellen und alternative Befestigungen ermöglichen.
Der komplette Roboter
Komplett zusammengebaut sollte der Roboter dann so aussehen (schematische Darstellung):
Neueste Version (Theo III)
Grundsätzlich müssen alle Bauteile auf die richtige Polung überprüft werden. Es reicht nicht, alles so zu stecken, wie es auf dem Schaubild steht, da es beim Steckbrett und den Bauteilen Abweichungen geben kann. Beim Verpolen gehen die Bauteile schnell kaputt und die Batterie läuft leer.
Deshalb lohnt es sich, alles gut zu überprüfen!
Ältere Version des Roboters (v1 und v2)
Der Kettenantrieb
Die Kette ist das mechanisch komplizierteste Element des SMARS-Roboters. Die einzelnen Kettenglieder (16 Stück pro Seite) werden mit Stücken von Filament zusammengesetzt. Dabei ist darauf zu achten, dass die Stücke nicht seitlich herausgucken und am Gehäuse hängenbleiben können. Eines könnte ein Stück heraus stehen bleiben, um die Kette einfacher aufmachen zu können.
Die Kette darf weder zu stramm noch zu locker sein. Eine zu kurze Kette zieht die Räder zusammen und der Motor kann diese Reibung nicht überwinden. Eine zu lockere Kette spurt leicht aus und setzt sich dann auf die Rauten auf den Rädern. Dann wird die Spannung auch zu stark. Es kann eine ganze Weile dauern, bis man eine gut funktionierende Kette zusammengebaut hat.
Außerdem werden sich die beiden Ketten nicht gleich schnell drehen, da die Motoren nicht miteinander synchronisiert sind. Hier kann man versuchen, die beiden Seiten mit unterschiedlichen Geschwindigkeiten zu betreiben, bis der Roboter möglichst geradeaus fährt.
Unterschiedlich lange Kettenglieder
Um die Kettenlänge anzupassen, gibt es unterschiedlich lange Kettenglieder. Diese sollten eins nach dem anderen in die Kette eingefügt werden, bis die richtige Länge erreicht ist. Zuviele Kettenglieder, die nicht die Standardlänge haben, können auch zu Problemen führen, da sie nicht mehr passgenau auf den Rädern sitzen.
Normale Länge
Die normal langen Kettenglieder sind an der vorderen Kante rechtwinklig geschnitten.
kürzere Länge
Die etwas kürzeren Kettenglieder haben auf der linken Seite eine Fase.
längere Länge
Und die längeren Kettenglieder sind rechts gefast.
Elastische Kette
Alternativ gibt es auch Ketten aus TPU, die elastisch sind.
Zusammenbau von Crawly
Der komplette Crawly
Komplett zusammengebaut sieht Crawly so aus.
Der Prototyp des Bewegungsablaufs sieht so aus:
1 Zusammenbau der Beine
2 Beine am Gehäuse befestigen
3 Anschlüsse und Software
Zusammenbau von Walky
Der komplette Walky
Komplett zusammengebaut sieht Walky so aus:
Der Prototype des Bewegunsablaufs sieht so aus:
1 Zusammenbau der Beine
2 Beine am Gehäuse befestigen
3 Anschlüsse und Software
Bibliotheken für die Roboter
Micropython Software-Bibliotheken für den Betrieb der Roboter.
Motorsteuerung
Speichere diesen Code auf dem Pico unter dem Namen "motor.py".
Motorbibliothek
from machine import Pin, PWM
import utime
MIN_DUTY = 0
MAX_DUTY = 60000
MAX_SPEED = 100
MIN_SPEED = 30
class Motor:
'''This class manages the motor. Don't edit!'''
def __init__(self, pinNo):
self.gpio = pinNo
self.speed=0
self.forward=True
self.pwm1=PWM(Pin(pinNo))
self.pwm1.freq(50000)
self.pwm1.duty_u16(0)
self.pwm2=PWM(Pin(pinNo+1))
self.pwm2.freq(50000)
self.pwm2.duty_u16(0)
self.speed_offset = 0
def set_speed(self,s):
'''Sets the speed of the motor. Checks for sensible input.'''
if s + self.speed_offset <= MIN_SPEED:
s = 0
self.reset_offset()
elif s + self.speed_offset >= MAX_SPEED:
s = MAX_SPEED
self.pwm1.duty_u16(int(MAX_DUTY*(s+self.speed_offset)/100))
self.speed=s
def change_speed(self,sc):
'''This defines an offset to the speed in motor. It is used with the remote control to turn the robot.'''
if self.speed + sc > MIN_SPEED and self.speed + sc < MAX_SPEED:
self.speed_offset += sc
self.set_speed(self.speed)
def reset_offset(self):
self.speed_offset = 0
def off(self):
self.pwm1.duty_u16(0)
self.speed = 0
def set_forward(self,forward):
'''Sets the motor to forward or backward without changing the speed. '''
if self.forward==forward:
return
self.pwm1.duty_u16(0)
self.pwm1,self.pwm2=self.pwm2,self.pwm1
self.forward=forward
self.set_speed(self.speed)
#self.pwm1.duty_u16(int(MAX_DUTY*(self.speed+self.speed_offset)/100)) # uncommenting this causes problems with the remote control. After changing
# the direction the robot would drive even if the remote control speed said 0.
Beispiel für die Anwendung dieser Bibliothek
Kopiere diesen Code in eine andere Datei auf dem Pico, z. B. „motortest.py“.
from motor import Motor
from utime import sleep, sleep_ms
motor = Motor(12)
motor.set_speed(70)
motor.set_forward(True)
sleep(1)
motor.off()
Ultraschallsensor
Ultraschallbibliothek
Speichere diesen Code auf dem Pico unter dem Namen "ultrasonic.py".
from machine import Pin
from time import sleep
import utime
class Ultra:
'''This class manages the ultrasonic sensor. It returns the distance to an obstacle in cm. '''
def __init__(self, pinNo):
self.trigger = Pin(pinNo, Pin.OUT) # to trigger a sound impulse
self.echo = Pin(pinNo+1, Pin.IN) # records the echo of the trigger pulse
def get_dist(self):
'''This returns the measured distance in cm. (float)'''
timepassed = 0
signalon = 0
signaloff = 0
self.trigger.low()
utime.sleep_us(2)
self.trigger.high()
utime.sleep_us(5)
self.trigger.low()
while self.echo.value() == 0:
signaloff = utime.ticks_us()
while self.echo.value() == 1:
signalon = utime.ticks_us()
timepassed = signalon - signaloff
distance = round((timepassed * 0.0343) / 2, 2)
# print("The distance from object is ", distance, "cm.") # for debugging purposes uncomment the line.
utime.sleep_ms(10) # Wait necessary or program halts
return distance
Beispiel für die Anwendung dieser Bibliothek
Kopiere diesen Code in eine andere Datei auf dem Pico, z. B. „ultratest.py“.
from ultrasonic import Ultra
from utime import sleep, sleep_ms
us = Ultra(16)
while True:
print(f"gemessene Entfernung: {us.get_dist()} cm.")
sleep(1)
Zum Fahren siehe Motorsteuerung.
Infrarotsteuerung
Ein Infrarotsensor kann zum Erkennen von Hindernissen oder der Verfolgung einer schwarzen Linie genutzt werden. Die folgende Klasse steuert den Sensor.
from machine import Pin,Timer
import micropython
micropython.alloc_emergency_exception_buf(100)
class IR:
'''This class manages the IR-sensor. Write your code in Robot.ir_detected()'''
def __init__(self, pinNo,callback_func):
self.out = pinNo
self.ir_detected = callback_func
self.ir = Pin(pinNo, Pin.IN, Pin.PULL_UP)
self.ir.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self.obstacle)
self.detected=False
self.timer = Timer()
def reset_detected(self,t):
self.detected = False
def obstacle(self, pin):
'''This is called on any change in the IR-sensor. '''
if not self.detected:
self.ir_detected(pin,self.out)
self.detected = True
self.timer.init(mode=Timer.ONE_SHOT, period=100, callback=self.reset_detected)
Der Code muss unter dem Dateinamen „infrared.py“ auf dem Pico gespeichert werden.
Der Infrarotsensor wird folgendermaßen im eigenen Programm eingebunden. Das Beispiel ist für zwei Infrarotsensoren.
from infrared import IR
IR_PIN_LEFT=0
IR_PIN_RIGHT=1
def ir_detected(pin, pinno):
print(f"Pin: {pin}, pin number: {pinno}")
if pinno == IR_PIN_LEFT:
print("links")
elif pinno == IR_PIN_RIGHT:
print("right")
ir_left = IR(0, ir_detected)
ir_right = IR(1, ir_detected)
Servosteuerung
Der Ultraschallsensor kann auch mit einem Servomotor drehbar gemacht werden. Die folgende Klasse steuert den Servomotor:
from machine import Pin, PWM
import utime
class Servo:
'''This class manages the servo motor that turns the ultrasonic sensor. You need a servo motor installed to get use out of this.
Don't use directly or edit.'''
def __init__(self,pin):
self.pin=PWM(Pin(pin))
self.pin.freq(50)
self.min=1350
self.max=8100
self.angle=0
def set_angle(self,a):
'''If installed, the servor motor will set the angle of the ultrasonic sensor. 90° ist straight ahead.'''
if a > self.angle:
for i in range(self._get_duty(self.angle),self._get_duty(a)):
self.pin.duty_u16(i)
elif a < self.angle:
for i in range(self._get_duty(self.angle), self._get_duty(a),-1):
self.pin.duty_u16(i)
self.angle = a
utime.sleep_ms(4)
def _get_duty(self,angle):
'''Internal function. Calculates the PWM duty for the given angle.'''
return round((self.max-self.min)/180*angle+self.min)
Dieser Code muss unter dem Dateinamen „servo.py“ auf dem Pico gespeichert werden.
Das komplette Modul "robotlibrary"
Dieses Modul, das von Github heruntergeladen werden kann, steuert die Roboter mit allen Peripheriegeräten (Motoren, Sensoren). Dazu muss das Paket heruntergeladen und entpackt werden. Das Verzeichnis „robotlibrary“ muss dann auf den Pico hochgeladen werden.
SMARS Roboter "Theo III"
Um das Modul zu benutzen, muss nur folgender Import gemacht werden: from robotlibrary.robot import Robot
.
Ein kurzes Codebeispiel, wie der Roboter funktioniert, ist in der Quelldatei zu finden.
Under construction:
Crawly
Crawly ist ein Roboter, der, ähnlich wie eine Schildkröte auf vier Beinen kriechen kann. Um Crawly zu steuern, muss nur folgender Import gemacht werden: from robotlibrary.crawly import Crawly
Ein kurzes Codebeispiel, wie der Roboter funktioniert, ist in der Quelldatei zu finden.
Walky
Walky ist ein Roboter, der, ähnlich wie ein Hund, auf vier Beinen laufen kann. Um Walky zu steuern, muss nur folgender Import gemacht werden: from robotlibrary.walky import Walky
Ein kurzes Codebeispiel, wie der Roboter funktioniert, ist in der Quelldatei zu finden.
Die Dokumentation für die Bibliothek ist unter docs
zu finden oder kann hier heruntergeladen werden: robotlibrary.pdf
Codebeispiele
Theo III
Best Practise
Effizienter Code
Auch wenn die Rechenleistung der Picos ausreichen sollte, ergibt es Sinn, sich über Effizienz Gedanken zu machen, da schwer zu erkennen ist, ob manche Probleme durch Überlastung des Prozessors hervorgerufen werden.
while True:
robot.drive()
if us.get_dist() > min_distance:
# stop or turn
robot.stop()
In diesem Beispiel wird in der Schleife der Befehl drive()
mit jedem Durchlauf aufgerufen, was nicht sonderlich effizient ist, da die Motoren weiterfahren, auch wenn das Programm gerade andere Befehle ausführt. Eine bessere Variante wäre diese:
robot.drive()
while us.get_dist() > min_distance:
pass
robot.turn()
Hier wird nur die Entfernung zum nächsten Hindernis überprüft. Sobald der Roboter zu nahe gekommen ist, wird die Schleife beendet und der Code wird weiter ausgeführt.
Fehlertoleranter Code
Die Sensoren, die wir benutzen, liefern nicht immer zuverlässige und korrekte Ergebnisse. Daher kann man sich nicht darauf verlassen, dass eine Messung ausreicht. Ist man auf genauere Ergebnisse angewiesen, kann es sinnvoll sein, die Ergebnisse von Sensormessungen (insbesondere des Ultraschallsensors) zu filtern. Dazu kann gehören, Extremwerte, die im vorliegenden Fall unwahrscheinlich sind, zu ignorieren oder Mittelwerte von mehreren Messungen zu bilden.
Beschleunigung mit Entfernungsmessung
obstacle_detected = False
new_speed = 100
speed_now = 0
min_distance = 15
while speed_now <= new_speed and not obstacle_detected:
#Set the speed for the motors, f. ex. motor.set_speed(speed_now)
utime.sleep_ms(10+int(speed_now/2))
speed_now += 1
if us.get_dist() < min_distance: # Adjust the code to your needs.
obstacle_detected = True
if obstacle_detected:
# Stop or turn or whatever
obstacle_detected = False
else:
# keep going
pass
Fehlerbehebung
Motoren
Motoren drehen sich nicht oder nur sehr schwer
Bei Kettenrobotern: Die Ketten sind zu stramm oder zu locker
Wenn die Ketten zu stramm sind, dann hat der Motor nicht genügend Kraft sich zu drehen. Ein Anzeichen dafür ist, wenn die Räder von der Ketten zusammengezogen werden, sodass die Achsen auf einer Seite nicht parallel sind. In diesem Fall sollten längere Kettenglieder eingefügt werden, bis die Kette gut sitzt.
Sind die Ketten zu locker, kann die Kette aus der Führung springen und auf den Führungsknubbeln aufsitzen. Dann muss die Kette wieder strammer gemacht werden.
Die Motoren drehen sich auch ohne Kette nicht
- Drehen sich beide Motoren nicht, kann es sein, dass die Stromversorgung nicht richtig angeschlossen ist. Es ist unbedingt darauf zu achten, dass der Motortreiber nicht falsch herum gepolt wird.
- Dreht sich nur ein Motor nicht, ist zunächst zu überprüfen, ob die Steuerpins auch korrekt mit dem Motortreiber verbunden sind.
- Ist dies der Fall, dann sollte überprüft werden, ob an den Anschlüssen für den Motor auch eine Spannung anliegt.
- Ist dies nicht der Fall, ist der Motortreiber eventuell kaputt.
Ein Motor dreht sich immer falsch herum
- Die Steuerpins sind verpolt
- Der Motor ist am Motortreiber verpolt.
- Es ist ein Fehler im Code
Es ist grundsätzlich sinnvoll, die Verkabelung der Steuerpins zu vertauschen, da man hierfür nicht mit dem Schraubendreher arbeiten muss. Das Ergebnis ist dasselbe.
Sobald der Pico Strom bekommt, dreht sich ein Motor und hört auch nicht mehr auf
- Der Pico ist womöglich beschädigt. Diesen mit dem Testprogramm und der Testplatine auf korrekte Funktion überprüfen.
Testprogramm
from machine import Pin, PWM
import utime
# Bestimme, welche Pins getestet werden sollen. Die Platine hat sieben LEDs. Somit können 7 Pins gleichzeitig getestet werden.
p_start = 11
p_end = 16
pins = list()
for i in range(p_start,p_end):
pins.append(PWM(Pin(i)))
# Die LEDs werden initialisiert. Hier nichts ändern.
#leds=[PWM(Pin(pins[0], Pin.OUT)), PWM(Pin(pins[1], Pin.OUT)), PWM(Pin(pins[2], Pin.OUT)), PWM(Pin(pins[3], Pin.OUT)), PWM(Pin(pins[4], Pin.OUT)), PWM(Pin(pins[5], Pin.OUT)), PWM(Pin(pins[6], Pin.OUT))]
# PWM Frequenz wird eingerichtet.
print("Der Test beginnt.")
for p in pins:
p.freq(2000)
# Zu Beginn werden alle LEDs ausgeschaltet.
for p in pins:
p.duty_u16(0)
# Die LEDs werden einzeln langsam aufgeblendet und abgeblendet. Gehen Sie ruckartig an und aus, dann ist PWM defekt.
for p in pins:
for i in range (65535):
p.duty_u16(i)
for i in range (65535, 0, -1):
p.duty_u16(i)
utime.sleep_ms(800)
# Alle LEDs blinken dreimal schnell hintereinander
for x in range(3):
for p in pins:
p.duty_u16(65535)
utime.sleep_ms(100)
for p in pins:
p.duty_u16(0)
utime.sleep_ms(100)
# Alle LEDs werden auf einer niedrigen Helligkeitsstufe angeschaltet und bleiben an.
for p in pins:
p.duty_u16(10000)
print("Der Test ist fertig.")
Der Ultraschallsensor funktioniert nicht
- Der Ultraschallsensor funktioniert am besten, wenn das Hindernis aus einem harten Material besteht, dass den Schall gut reflektieren kann. Ebenso kann es sein, dass das Hindernis sehr schräg steht und damit den Schall in eine andere Richtung reflektiert.
- Der SMARS reagiert nicht auf Hindernisse. In diesem Fall ist zunächst zu prüfen, ob auf Softwareseite alles in Ordnung ist. Zum Beispiel könnte der Code einer anderen Gruppe getestet werden, bei denen es funktioniert.
- Im nächsten Schritt sollte der Ultraschallsensor getestet werden. Dazu muss das Messprogramm von Thonny aus gestartet werden, damit die Messergebnisse angezeigt werden. Werden keine Messergebnisse gezeigt, dann zum nächsten Schritt.
- Es muss überprüft werden, ob die Pins für Trigger und Echo auch nicht vertauscht sind. Die beiden Pins lassen sich ohne Gefahr für den Pico vertauschen, sie funktionieren aber natürlich nur, wenn sie richtig herum sind.
- Funktioniert der Ultraschallsensor bei Start des Programms über Thonny aber nicht beim autonomen Start, dann muss überprüft werden, ob der Kondensator auch an der richtigen Stelle steckt.
- Wird das Programm als main.py ohne Thonny ausgeführt, kann es sein, dass der Code Fehler enthält, wenn er nicht vorher gut getestet war. Dann stürzt das Programm natürlich ab und es sieht nur so aus, als ob der Ultraschallsensor nicht funktionieren würde.
- In einigen Fällen hat der Ultraschallsensor auch Funktionsstörungen, die nach einigen Minuten Pause wieder behoben sind.
3D-Konstruktionsdateien für die Roboter
Die Dateien für "Theo III" sind nicht mit der originalen Version des SMARS-Roboters kompatibel, da das Gehäuse leicht verändert wurde. Die Dateien (.FCSTD) sind mit dem Programm "Freecad" zu bearbeiten.
Die Halterungen für "Theo III" sind mit den anderen Robotern "Crawly" und "Walky" kompatibel.
STL-Dateien können direkt in einem Slicer für den Druck auf einem 3D-Drucker vorbereitet werden.
Gute Tutorials für die Benutzung des Programms Freecad gibt es z.B. hier: https://www.youtube.com/@stolz3d
Das Chassis
Das Chassis (Theo III)
Das Modell enthält die nötigen Stützstrukturen und muss daher ohne weitere Stützstrukturen gedruckt werden.
Diese Version des Roboters hat etwas stärkere Vorder- und Rückseiten und einen Schlitz für einen Schalter.
Des Weiteren stehen die Räder 2 mm näher zusammen, was reichen sollte, um die Kettenspannung genügend zu reduzieren, damit sich die Motoren frei drehen können. Es könnte eher das Problem sein, dass die Ketten zu locker sind.
Die Steckbrettplatte
Die Steckbrettplatte für den Theo III
Auf der Steckbrettplatte wird das Steckbrett und der Motortreiber befestigt. Der Druck erfolgt ohne Stützstrukturen.
Diverse Halterungen
Konstruktionsdatei für den Ultraschallsensor-Halter
Der Druck erfolgt ohne Stützstrukturen.
Gehäuse für den Ultraschallsensor (Theo III) | druckbare Datei
Halterung für den Ultraschallsensor (Theo III) | druckbare Datei
Ultraschallhalter für allgemeinen Halter
Konstruktionsdatei für den IR-Sensor-Halter:
Der Druck erfolgt ohne Stützstrukturen. Die beiden Teile müssen korrekt auf der Druckplatte ausgerichtet werden. Dazu wird der allgemeine Halter benötigt.
IR sensor - Druckdatei mit richtiger Ausrichtung: IR-sensor.stl
Für diejenigen, die den IR-Halter selber konstruieren wollen, hier ist eine Konstruktionsskizze, die man benutzen kann:
Konstruktionsdatei für den Motor- und Batteriehalter
Motor- und Batteriehalter | druckbare Datei
Bemaßungen für Motor- und Batteriehalter
Allgemeine Halter
Allgemeiner Halter - Druckdatei: SMARS_v3_general_holder.stl
Allgemeiner Halter hoch - Druckdatei: SMARS_v3_general_holder_high.stl
Allgemeiner Halter hinten - Druckdatei: SMARS_v3_holder_rear.stl
Allgemeiner Halter für 2 IR-Sensoren
Allgemeiner Halter für 3 IR-Sensoren
Bemaßung der Halterung für eigene Designs.
Antrieb
Original Bauteile
Die folgenden Bauteile sind unverändert vom Original übernommen worden.