Nach langer langer Pause hier mal ein Update:
Vor Kurzem habe ich meinen zwischenzeitlich auf den Dachboden verbannten Probot rausgekramt, da mich die Bastellaune packte.
Wem der folgende Text zu lang ist bitte runterscrollen zu "Meine Vermutungen"
Nach etlichen Stunden des Messens und Grübelns habe ich die Ursache gefunden, warum er keine Verbindung mehr zum PC herstellen konnte. Es lag an defekten Mikrotastern, die den Reset- und Boot-Pin des Controllers auf Masse ziehen müssen beim einschalten, um so die PC-Verbindung zu ermöglichen.
Von diesem Teilerfolg beflügelt habe ich mich wieder mit der Optimierung der Motorsteuerung und der Odometrie beschäftigt und bin auf etliche Probleme gestoßen.
Ziel ist es, eine Funktion mit PID-Regler zu programmieren, die es ermöglicht per Eingabe entsprechender Variablen den Roboter zu steuern. Eine Funktion, die mir als Grundlage dient, ist in der Originalbibliothek des Probots bereits vorhanden, "GO_TURN(Distanz, Drehung, Geschwindigkeit)".
In Anlehnung an den PID-Regler "nach Waste" für den Asuro habe ich das Programm umgeschrieben und auf meine Bedürfnisse angepasst. Generell funktioniert es so:
- Distanz (in cm) = abhängig vom Vorzeichen der Variablen vorwärts/rückwärts eine bestimmte Strecke fahren.
Die Motor-Dir Pins des Motortreibers L293 werden hierzu entsprechend auf High oder Low gesetzt.
Die Messung/Berechnung der Strecke erfolgt per Vergleich des SOLL- und IST-Wertes für die notwendige Anzahl an "Encoder-Ticks" der Odometrie des Probots, z.B. 100cm = 500 Ticks. Diese werden per ISR erfasst.
- Drehung (in Grad) = wie zuvor, jedoch für links/rechts auf der Stelle drehen
- Geschwindigkeit (0-255) = SOLL-Wert Startgeschwindigkeit, Ansteuerung des Enable Pins eines L293 per PWM, der die Motoren antreibt. Ab einem bestimmten Minimalwert wird nach unten begrenzt, da die Räder sonst stillstehen.
- Bedingt durch die Verbindung der einzelnen Komponenten ist aktives Bremsen durch kurzschließen der Motor-Dir Pins am L293 aktuell nicht möglich. Sollte es sich im späteren Verlauf zeigen, dass dies sinnvoll oder notwendig ist, kann ich am Controller problemlos weitere Pins nutzen.
Nun zu meinem Problem und den Lösungsansätzen:
Grundsätzlich funktioniert das Programm so wie es soll, allerdings fährt der Roboter keine Gerade, sondern einen betrunkenen Bogen, sprich die Korrekturwerte für den P, I und D Anteil passen nicht. Zum Testen und Debuggen habe ich in den Code der Mainfunktion Textausgaben eingefügt, um folgende Werte die innerhalb des Programmablaufes relevant sind im PC-Terminal anzeigen zu lassen:
- Encoder Count Left und Right (IST-Werte) / Encoder Count Gesamt (SOLL-Wert),
errechnet aus (Summe Left+Right)/2
- Error (Encoder Count Right abzgl. Encoder Count Left)
- aus Error berechnete Stellgrößen für P, I und D-Anteil
- Anzahl der Schleifen, sprich wie oft die While Schleife für den Regler insgesamt durchlaufen wurde bis der SOLL-Wert für die zurückgelegte Strecke erreicht wurde.
Hierbei trat nun folgendes Problem auf:
Es hat sich gezeigt, dass bei bestimmten PWM-Frequenzen, jedoch nicht wirklich reproduzierbar, die Odometrie des Probots falsche Werte liefert. Einer der beiden Sensoren meldet sobald die Motoren anlaufen direkt in der ersten Schleife z. B. einen Wert von 200-300 Ticks und der andere 0 Ticks. Die Räder drehen sich aber noch nicht einmal!
Dadurch wird die While Schleife verlassen und die Funktion als erledigt angesehen, da die Gesamtticks bereits den SOLL-Wert überschreiten.
Eine Recherche im C-Control Forum ergab, dass dieser Effekt anscheinend durch einen Konstruktionsfehler des Probots entsteht. Auf der Motorplatine verlaufen die Leiterbahnen für die Signale der Radencoder in Teilbereichen direkt über den Leitungen für die Motoransteuerung, auf denen das PWM-Signal übermittelt wird (Oberseite und Unterseite der Platine). Das PWM-Signal beeinflusst dadurch die Encodersignale und zusätzliche Interrupts werden hierdurch ausgelöst. Um das Problem zu umgehen wird vorgeschlagen, die Leiterbahnen zu kappen und ein geschirmtes Kabel direkt von den Sensoren zu den Pfostensteckern zu legen, die Motor- und Controllerplatine verbinden. Weiterhin wird u.a. auch in dem Probot-Buch empfohlen zwischen den Sensoren und dem Controller Schmitt-Trigger einzubauen, um die Signalflanken schön rechteckig zu formen.
Beide Tipps habe ich nun bereits umgesetzt. Die Signale der Encoder werden in ein IC vom Typ 4093 (HCF4093B) gegeben, dass an den Ausgängen 0 oder 5 Volt an den Controller überträgt.
Außerdem habe ich den originalen Encoder-Sensor bestehend aus einem Fototransistor und einer IR-Diode, die im 90° Winkel zueinander angeordnet sind und auf eine Schwarz-Weiß Zählscheibe mit 8er Teilung blicken, gegen einen CNY70 auf der Unterseite der Platine ausgetauscht. Auch die Zählscheibe habe ich gegen eine mit 32er Teilung aus bedruckter Transparentfolie mit einem Hintergrund aus Alufolie getauscht, um die Auflösung zu erhöhen. Um ein brauchbares Low-Signal für den Schmitt-Trigger zu erhalten musste ich außerdem den Vorwiderstand der beiden in Reihe geschalteten IR-LEDs aus den beiden CNY70 von 220 auf 100 Ohm reduzieren.
Wenn der Fototransistor durchsteuert zieht er den Eingang vom Trigger nun auf Low (ca. 1,2 Volt), wenn er sperrt liegt am Triggereingang >4,2 Volt an.
Durch Messen (Multimeter) und einen manuellen Check der Interruptfunktionen hat sich gezeigt, dass die Interrupts durch händische Drehen des Rades nun zuverlässig ausgelöst werden.
Ein Problem behoben, nächstes Problem folgte direkt im Anschluss:
Die oben beschriebene GO-TURN Funktion liefert mir nun nur noch Werte von 0 für alle Regel- und Stellgrößen!?
Der Encoder-Count links und rechts wird nicht erhöht und die Abbruchbedingung für die While Schleife somit nicht erreicht. Auch der Regler kann mit einem Error von 0 natürlich nichts regeln.
Sprich die Räder drehen sich permanent. Allerdings gibt es nun auch keine Störungen mehr durch das PWM-Signal.
Aber es würde ja auch keinen Spaß machen und man würde nichts dazu lernen, wenn alles auf Anhieb klappt.
Meine Vermutungen:
1. Ist es möglich, dass durch die 4-fach höhere Auflösung der Ablauf der Encoder-ISR (jeweils eine für das linke bzw. rechte Rad) gestört wird, da die Interrupts schneller ausgelöst werden als die ISR sie abarbeiten kann? Die Scheibe ist 32 fach (16x schwarz/16xAlufolie) aufgeteilt und der Interrupt wird bei jeder steigenden und fallenden Flanke ausgelöst, sprich bei jedem Wechsel von schwarz zu weiß und umgekehrt. In der ISR selbst werden nur die Variablen für den Zählstand um 1 erhöht und das Interruptflag gelöscht. Hat bei einer geringeren Auflösung mit Original-Encodern funktoiniert.
2. Kann es sein, dass durch die schnelle Drehung der Zählscheibe bei Antrieb per Motor keine brauchbaren Pegel mehr für den Schmitt Trigger verfügbar sind? Also der Pegel iwo im Bereich der Hysterese des Schmitt-Triggers dümpelt, so dass er nicht "durchschaltet". Als Laie stell ich mir das als "50% graue Scheibe" vor.
Für etwaige Denkanstöße und Winks mit Zaunpfählen danke ich im Voraus!
Werde heute Abend mal Scheiben mit geringerer Auflösung probieren und versuchen per Multimeter die Frequenz zu messen (habe in dem Ding eine Funktion für Anzeige in Hertz).
Lesezeichen