Da ich in letzter Zeit wieder etwas mehr Freiraum hatte, habe ich den Bau meines Roboters fortgesetzt. Den ersten Fehlschlag erlebte ich bei der Verwendung von Steppern als Antriebsmotoren. Diese hielten leider nicht, was ich mir von ihnen versprochen hatte, ihr Drehmoment war zu niedrig, so dass erste Fahrversuche an einer Teppichkante scheiterten ;-)
Doch das sollte der Sache keinen Abbruch tun, es wurden RB35 Motoren und ein paar Getriebe bestellt (www.embedit.de). Diese zeigten schon in ersten Versuchen, dass sie mehr als ausreichend waren, meine kleine Versuchsplattform durch die Gegend zu fahren. Zur Ansteuerung verwende ich den unter der Rubrik Mechanik erwähnten Baustein L293D.
Das Gehirn von Homer bildet ein ATMEGA32L mit 16MHz, es sollten also mehr als genug Leistungsreserven aus rechentechnischer Sicht verfügbar sein. Die Programmierung dieses Controllers unterscheidet sich im Prinzip in fast keinem Punkt zu der des ATMEGA8, welcher hier bereits vorgestellt wurde.
Als Benutzerinterface dient ein HD44780 LCD mit 4*16 Zeichen.
Die Augen des Roboters bilden vorerst zwei SHARP GP2D120 Infrarotsensoren, welche ein distanzproportionales Analogsignal an ihrem Ausgang zur Verfügung stellen. Zusätzlich verfügt er über mehrer Näherungsschalter auf Basis des IS471F zur Kollisionserkennung und -vermeidung.
Motorisiert ist er wie bereits erwähnt mit Hilfe von zwei DC-Motoren (hinten rechts und links) sowie eines Stützrades (vorne Mitte).
Hier eine schematische Zeichnung:

Wie ersichtlich ist, sind 6 Infrarot-Kollisionssensoren vorgesehen. Diese ziehen jeweils etwa 10mA Strom, was bei 5V Betriebsspannung einen Leistungsumsatz von 50mW je Sensor bedeutet. Insgesamt kommen so also 0,3W zusammen.
Für die beiden Sharp Sensoren sind jeweils etwa 26mA zu veranschlagen. Daraus folgt eine Leistung von gesamt 5V*26mA*2=0,26W.
Meine Schaltung mit ATMega32 und LCD zieht gesamt etwa 100mA, wobei man diesen Wert schon fast als worst case betrachten kann. Hier kommen also noch einmal 0,5W zusammen.
Gesamt lässt sich ein Strom von 212mA ausrechnen. Da für den 12V Bleigel-Akku zusätzlich ein Spannungsregler benötigt wird um die 5V Logikspannung bereitzustellen, muss mit einer Leistung von 12V*212mA=2,544W gerechnet werden. Diese muss vom Akku bereitgestellt werden.
Zusätzlich wird natürlich noch Motorleistung benötigt, denn nur "rumstehen und gucken" ist auf Dauer nicht wirklich prickelnd ;-)
Einfache Tests mit den Motoren ergaben einen Leerlaufstrom von etwa 100mA, bei normaler Last etwa 150-200mA und unter Volllast (kurz vor Stillstand) etwa 400mA. Im weiteren wird mit 250mA je Motor gerechnet, was wieder fast einer worst case Betrachtung entspricht. Gesamt ergeben sich also 0,5A unter Last, das entspricht bei 12V einer Leistung von 6W.
Da der von mir benutzte Akku eine Kapazität von 1,3Ah hat, bedeutet das bei einem Nennstrom der Schaltung von ca. 750mA, dass mein Roboter mindestens 1,3Ah/0,75=1,73h also eine Stunde und 45 Minuten "durcharbeiten" können müsste, was ich als durchaus ausreichend betrachte.
Es darf allerdings nicht verschwiegen werden, dass ein solcher Bleiakku auch mit einem Gewicht von 0,6kg zu Buche schlägt. Das ist im Vergleich zu anderen Akkusorten (vgl. Racing-Packs mit NiCd bzw. NiMh) nachteilig. Für ihn spricht der gute Preis, die einfach Handhabung und die Tatsache, dass er im Prinzip über keinen Memory-Effekt verfügt.
Ein ähnlicher Akku mit 2,2Ah ist mit einem Gewicht von 0,8kg im Handel verfügbar. Dies entspräche bereits einer Betriebsdauer von beinahe 3 Stunden.

Die Pinbelegung des ATMega32 sieht nun wie folgt aus:

Wie ersichtlich ist, sind die zunächst zahlreich erscheinenden Pins des Atmels relativ schnell erschöpft. Pin 1-4 dienen dem Festlegen der Drehrichtung der beiden Motoren. Pin 14,15,20 und 21 können noch zur Benutzerführung mittels Taster bzw. als Status-Anzeige mittels LEDs genutzt werden. Pin 16 und 17 dienen der Drehzahlerfassung der Motoren über auf den Wellen befestigte Encoderscheiben in Verbindung mit Gabellichtschranken. Pin 18 und 19 dienen der Drehzahlstellung. Die Pins 39 und 40 werden zur Abstandsmessung verwendet. Pin 38 soll ständig den Akku auf eine bestimmte Mindestspannung prüfen, so dass ab einer bestimmten Entladung die Motoren abgestellt und ein Warnsignal (Pin 29 --> Status-LED) ausgegeben werden kann. Pin 36 und 37 werten den Motorstrom ständig aus, um eine eventuell von den Sensoren nicht erkannte Kollision zu erkennen (Motorstrom würde steigen). Mit den Pins 22-28 wird leider fast ein kompletter Port "nur" für das Benutzerinterface LCD genutzt. Diese ist jedoch meiner Meinung nach zum Debuggen und für Statusmeldungen unerlässlich.

Motorsteuerung:    siehe Seite Mechanik

IS471F:                siehe Seite Sensorik

Encoder:
Als Radencoder habe ich die GP1A71R von Sharp verwendet. Dies ist hauptsächlich darin begründet, dass ich keine Lust hatte, selbst auf Pappscheiben entsprechende Segmente zu malen, da dabei keine entsprechend hohe Wegauflösung zu erwarten ist. Die Encoder von Sharp werden mit einer 120er Teilung ausgeliefert. Dies sollte eine ausreichende Wegauflösung gewährleisten. Hauptzweck der Encoder ist die Realisierung einer simplen Geradeausfahrt (ansonsten durch Ungleichheiten der Motoren unmöglich) sowie von Kurvenfahrten. Der Anschluss der Sensoren kann dem beiliegenden Datenblatt entnommen werden. Es muss für eine Betriebsspannung und Masse gesorgt werden. Die integrierte LED benötigt zusätzlich noch einen Widerstand von etwa 190Ω (oder etwas größer). Es können dann zwei Signale abgegriffen werden. Beide geben eine zur Rotationsgeschwindigkeit proportionale Rechteckfunktion aus, welche jedoch untereinander um 90° verschoben ist. So ist eine zusätzliche Bestimmung der Drehrichtung möglich, welches jedoch hier nicht nötig sein sollte, schließlich legt das Motorprogramm bereits die Drehrichtung fest.

Drehzahlstellung:    siehe Beispielprogramm zum Thema PWM sowie Seite Timer

Sharp:                    siehe Seite ADC sowie Sensorik

Akkuüberprüfung:
Die Akkuüberprüfung erfolgt durch einen Spannungsteiler von zwei Widerständen mit den Werten 22kΩ und 68kΩ. Diese dienen dazu, die 12V Spannung des Akkus auf eine für den ADC taugliche herunter zu skalieren.

LCD:                    siehe Seite LCD

Chassis:
Das Chassis habe ich mir aus einer Kunststoffplatte mit einer Stichsäge zurecht gesägt. Das ist meiner Meinung nach für einen Prototypen kein schlechtes Material, da es sehr leicht ist, einfach zu bearbeiten, gut zu kleben bzw. zu schrauben. Als Räder verwende ich welche aus dem Modellbau, die ich bei Conrad bestellt habe. Die sind zwar relativ teuer, allerdings haben sie einen geringeren Durchmesser, laufen absolut rund und ihr Bohrungsdurchmesser war kleiner als der meiner Motorwellen. So reichte ein leichtes Aufbohren der Räder aus, um sie in Form einer Presspassung auf der Welle zu befestigen. Diese Lösung ist zwar nicht unbedingt elegant aber funktioniert zuverlässig.

 

Die Programmierung:

Was einem bei der ersten Probefahrt sofort ins Auge sticht ist die Kurvenfahrt des Roboters, obwohl an beiden Motoren dieselbe Spannung anliegt. Das liegt daran, dass vergleichsweise günstige Motoren verwendet wurden. Ich denke, dass sich dieser Effekt mit dem Kauf teurer (drehmomentstarker) Schrittmotoren bzw. DC-Motoren minimieren ließe. Allerdings kann man sich diese Ausgaben auch schenken und auf vergleichsweise günstige Radencoder (Gabellichtschranke + Encoderscheibe) zurückgreifen. Diese Zählen nun beständig die Impulse bei laufendem Motor. Anhand der gezählten Impulse muss nun Einfluss auf die Motorgeschwindigkeiten (also Spannungen) genommen werden, so dass sie im Falle einer Geradeausfahrt annähernd auf beiden Seiten gleiche Werte annehmen.
Ohne näher auf die Regelungstechnik einzugehen kann die Regelstrecke mit einem IT1-Verhalten klassifiziert werden.

Die obige Grafik zeigt die schematisierte Sprungantwort des Systems. Sprungantwort heißt, dass ich an den Eingang (also die Motorklemmen) eine definierte Spannung anlege und diese konstant halte. Nun wird betrachtet, wie sich der Ausgang (also die Encoder) verhält. Diese zählen erwartungsgemäß beständig aufwärts. Da der Motor näherungsweise PT1-Verhalten hat, also auf eine Spannung an den Klemmen leicht verzögert (also träge) reagiert, ergibt sich für die Regelstrecke das obige Aussehen. Wäre der Motor sofort auf seiner "Nenndrehzahl", so würde sich eine Gerade direkt durch den Ursprung ergeben, der Bogen im unteren Bereich könnte entfallen.

Die Zeitkonstante wird durch die Mechanik des Motors bestimmt, die elektrischen Zeitkonstanten können vernachlässigt werden. Einschlägiger Literatur kann entnommen werden, dass man für eine IT1-Strecke am besten einen PI-Regler verwenden sollte. Ein D-Anteil ist überflüssig, könnte aber nachträglich noch hinzugefügt werden.
Die Basis für einen Regelvorgang bildet immer ein Sollwert-Istwert Vergleich. Der Sollwert wird vorgegeben, den Istwert kann man mittels der Radencoder erfassen. Als Sollwert könnte beispielsweise angenommen werden, dass sich das Rad in einer bestimmten Zeitspanne, also meinetwegen 0,125s, um eine bestimmte Anzahl an Encoderschritten, also beispielsweise 5, gedreht haben soll.
Die von mir verwendete Reglerstruktur hat das folgende Aussehen:

Regelfaktor = KP*(Ist - Soll) + KI*((Ist - Soll)*Zeitintervall)

Hierbei stellen KP und KI die Proportional- bzw. Integralverstärkung dar. Der Regelfaktor ist ein direktes Maß für die Abweichung und demzufolge notwendige Nachregelung. Sind Ist- und Sollwert identisch wird er logischerweise Null. Dieser Regelfaktor muss für jede Seite (Motor rechts bzw. Motor links) getrennt berechnet werden.

Wählt man nun die Abtastzeit ausreichend fein, so erhält man eine kontinuierliche Rotation der Motorwellen. Bei praktischen Versuchen zeigte sich, dass die oben angegebene Formel noch kein ausreichend gutes Ergebnis zur Verfügung stellt. Was fehlt ist ein zusätzlicher Vergleich der absoluten Encoderwerte der rechten bzw. linken Seite. Summiert man die Abweichung zwischen beiden Seiten multipliziert mit einem bestimmten Faktor zusätzlich zum Regelfaktor, so erhält man eine nahezu perfekte Geradeausfahrt.

Die bereits erwähnte Abtastzeit sollte relativ genau sein. Deshalb liegt die Verwendung eines Timers nahe. In dessen ISR wird dann die eigentliche PI-Regler Funktion aufgerufen.

Die im folgenden verlinkte C-Datei demonstriert die Implementierung meines PI-Reglers. Die header-Datei motor.h habe ich zunächst nicht mit verlinkt, da sie je nach verwendetem Motor bzw. Treiberschaltkreis bei jemand anderem soundso nicht arbeiten würde. Entscheidend ist alleine ihre Funktionalität. Sie ist so gestaltet, dass ihr zwei Parameter übergeben werden. Einmal der gewünschte Motor (0 = links, 1 = rechts) sowie die Geschwindigkeit (0 = Stillstand, 100 = max. mögliche Geschwindigkeit).

pi_regler.c

Die Veröffentlichung der gesamten Software zu meinem Robo erübrigt sich, da bezweifelt werden kann, dass sie jemandem einmal nützt. Von mir gelöste Aufgaben lagen darin, geradeaus zu fahren, Kollisionen zu vermeiden oder wenigstens zu erkennen und entsprechende Maßnahmen zu ergreifen. Mit Hilfe der Sharp-Sensoren war auch die Wandverfolgung nicht weiter schwierig. Für weitere Herausforderungen hat mir dann doch irgendwo die Inspiration gefehlt, weshalb ich mich danach wieder anderen Projekten zugewandt habe.
 

Zurück zur Startseite.