Dienstag, Februar 10, 2009

Die neuen Encoder am Oszi

Es war nicht gerade leicht die Lichtschranken an der Schlitzscheibe auszurichten, zumal bereits Bruchteile von Millimetern entscheidend waren. Auch musste die Scheibe exakt konzentrisch auf der Motorachse verklebt werden.

Klingt doch super, oder? Ähm, ährlich gesagt haben wir die Scheiben und die Lichtschranken einfach, so gut es geht nach Augenmaß ausgerichtet und schlicht gehofft, dass es schon klappen wird.

Beim Test der Motoren zeigte sich jedoch, dass bei hohen Drehzahlen sehr viele Fehler entstanden (Siehe Beitrag im RoboterNetz). Ohne gute Messgeräte, ist es aber schlicht nicht möglich die Signale zu überprüfen und den Fehler zu lokalisieren. So entschieden mein Bruder und ich uns am Freitag-Nachmittag einmal in unsere alte Uni zu fahren und mit einem Oszilloskop der Sache auf den Grund zu gehen.

Gleich der erste Motor machte auf uns einen sehr guten Eindruck. Die Flanken waren auch bei hohen Drehzahlen (ca. 6000 UPM) steil und gleichmäßig. Es war nur ein leichtes Zittern zu sehen und der kleinste Abstand zwischen zwei Flanken von Signal A und B lag bei 50 µS.

Motor A: A=5V/Div; B=5V/Div; 250µs
Motor A: A=5V/Div; B=5V/Div; 250µs

Der Zweite Motor war Leider nicht so gut. Das untere Signal hatte kürzere High Phasen und die Phasenverschiebung war manchmal so knapp, dass nur wenige µs zwischen den Flanken lag. Auch war zu erkennen, dass die Phasenverschiebung mal besser und mal schlechter war, was auf eine nicht kozentrische Schlitzscheibe schliessen lässt. Die ersten Versuche den Encoder gleich in der Uni auszurichten haben lieder nicht zum gewünschten erfolg geführt. Also werden wir zu Hause in vertrauter Umgebung einen neuen Versuch starten und bei der nächsten Gelegenheit wieder am Oszi testen.

Freitag, Januar 09, 2009

Encoder Auswertung

Ausgangssituation

An den Motoren sind Lichtschranken und Schlitzscheiben zur Erfassung der Drehung angebracht. Jeder Motor hat dabei zwei Gabellichtschranken (A und B) die ein um 90° versetztes Signal liefern. Ein Mikrocontroller soll nun diese Signale auswerten.

Schematischer Ablauf der Auswertung

Für die Auswertung eines Encoders soll ein Interrupt bei jeder steigenden und fallenden Flanke der Signale A und B am Mikrocontroller ausgelöst werden. Innerhalb einer Interrupt Service Routine (ISR) werden die Signale ausgewertet und die zurückgelegten Umdrehungen des Motors ermittelt. Durch die Auswertung beider Flanken von zwei Gabellichtschranken, ergibt sich eine vierfache größere Genauigkeit als Schlitze auf der Scheibe sind. Der Nachteil ist aber auch eine höhere rechen Belastung des Mikrocontrollers.

Für einen Motor mit max 5000 UPM und einer Schlitzscheibe mit 32 Strichen ergibt sich:

5000 upm∙36 Striche ∙4 Flanken = 12kHz

Da der µC die Auswertung für zwei Motoren machen muss, müssen 24.000 ISR pro Sekunde verarbeitet werden.

Bei jedem Interrupt werden die Zustände der beiden Signale erfasst und gespeichert (kleines a und b). Dabei durchläuft die Signalabfolge genau 4 Phasen (s. Bild oben) bis die Abfolge wieder von Forn beginnt. Bei jedem Interrupt weren die zuvor gespeicherten und neuen (großes A und B) Zustände verglichen. Die Signale a, b und A, B können zusammen 16 verschiedene Werte annehmen, je nachdem, ob das Sibnal 1 oder 0 ist.

Da sich von der einen auf die andere Phase nur ein Signal ändern darf, sind in den 16 möglichen Werten einige die ungültig. Das nebenstehende KV-Diagramm zeigt alle möglichen Zustände, wobei A und B die aktuellen und a und b die Signale der vorhergehenden Messung darstellen. Die Signale mit einem Ausrufezeichen stehen für LOW und die ohne für HIGH.

Zur Veranschaulichung des KV-Diagrams, hier einmal ein Beispiel: Im zweiten dunkel grauen Feld oben links (das mit der 1) ist das Signal B HIGH und hat sich nicht geändert (kleines b war auch HIGH), wobei A von LOW auf HIGH gewechselt hat. Dies ergibt dann eine Drehung des Motors um genau einen Flanke(Schritt). Bei negativen Schritten hat sich der Motor in die entgegengesetzte Richtung gedreht und bei 0 gar nicht.

Programmstruktur

Die alten und neuen Signale werden bei jedem Interrupt in einer Variablen (bPhase) gespeichert, welche genau dann genau die 16 möglichen Werte darstellt. Mit diesem Wert wird aus einer festen Tabelle (aSteps) der entsprechende Schritt ermittelt. Die Tabelle ergibt sich aus dem KV-Diagramm.










Quellcode

 
#DEFINE IS_SET_MOT1_SIG_A (PINC & (1<< PINC1)
#DEFINE IS_SET_MOT1_SIG_B (PINC & (1<< PINC2)
#DEFINE IS_SET_MOT2_SIG_A (PINC & (1<< PINC3)
#DEFINE IS_SET_MOT2_SIG_B (PINC & (1<< PINC4)
#DEFINE INV -128
typedef union {
 struct {
  unsigned Signal_A :1;   // neues Signal A
  unsigned Signal_B :1;   // neues Signal B
  unsigned AltSignal_A :1;  // altes Signal a
  unsigned AltSignal_B :1;  // altes Signal b
 } x;
 uint8_t bRow;
} tPhase;
Encoder
{
// Member Variablen
long lEncoder; // enthält die gezählten Flanken des Motors
long lError; // enthält die gezählten Fehler des Motors
tPhase bPhase; // enthält das vergangenen und neuen Signale

// Funktionen
void ISR(); // Interrupt Service Routine
long GetEncoder(); // gibt die Anzahl der Flanken zurück
long GetError(); // gibt die Anzahl der Fehler zurück
void Reset(); // setzt die Flanken und Fehler auf Null zurück


ISR(PCINT0_vect)
{
// lookup table
 static const int8_t aSteps[] = { 0, -1, 1, ENC_INV, 1, 0, ENC_INV, -1, -1, ENC_INV, 0, 1, ENC_INV, 1, -1, 0 };
 int8_t iStep = 0; // Schrittweite des Motors

 // alte Phase um zwei Bit nach links verschieben
 bPhase.bRow = (bPhase.bRow << 2);
 // alles ausser a und b löschen
 bPhase.bRow &= 0x0C;    // 0000 1100 = 0x0C
 // Signal A einlesen
 bPhase.x.Signal_A = IS_SET_MOT1_SIG_A ? true : false;
 // Signal B einlesen
 bPhase.x.Signal_B = IS_SET_MOT1_SIG_B ? true : false;

  // Schrittweite aus Tabelle auslesen
 iStep = aSteps[bPhase.bRow];
 if (iStep != ENC_INV)
 {
  lEncoder += iStep;
 }
 else
 {
  lError++;
 }
}
 

Reichweite

In den Variablen lEncoder_R und lEncoder_L werden die zurückgelegten Drehungen der Motoren gespeichert. Diese Werte sind auch außerhalb der ISR verfügbar und können so für eine Streckenmessung oder eine Drehzahlregelung verwendet werden. Nun ist es aber auch wichtig zu überprüfen wie weit man mit einer Streckenmessung kommt. Bei meinem Roboter speichere ich die zurückgelegten Drehungen, genauer gesagt die gezählten Flanken in einer 64bit Variablen. Diese hat einen Wertebereich von -2.174.483.648 bis +2.174.483.647. An den Motoren ist ein Getriebe mit einer Übersetzung von 1/30 direkt angebracht und zu den Reifen noch einmal zwei Zahnräder mit 45/60 Zähnen. Jeder Reifen hat einen Radumfang von ca. 31cm.

Encoder Hardware

Encoder Hardware

Viele von euch, die in der Freizeit gerne an Robottern basteln, standen schon sicher irgend wann einmal vor dem Problem die Drehzahl der Reifen erfassen zu wollen. Nicht immer hat man das Glück einen Motor mit angebauten Drehgeber zu besitzen oder den Platz mal eben schnell etwas zurecht zu friemeln.

Mein Bruder und ich standen vor einiger Zeit vor diesem Problem. Für unseren balancierenden Roboter brauchten wir eine sehr gute erfassung der Drehzahl, um die Motoren für das Balancieren auch richtig regeln zu können. Wir endschieden uns daher dafür die Drehzahl direkt an den Motoren mit Hilfe einer Gabellichtchranke zu erfassen. Dies sollte die größte Messgenauigkeit und schnellste Erfassung der Motoren ergeben, da das Lagerspiel nicht mit erfasst wird. Leider haben die Motoren (vom Typ RB-40) am hinteren Ende keine verlängerte Welle, sondern nur einen kleinen Nupsi der etwas über das Lager hinausragt. Eine Schlitzscheibe zu befestigen schien also so gut wie unmöglich.

Das zweite Problem war der geringe Platz den wir für die Lichtschranke hatten. Wir Ihr im Beitrag Alu und Glas sehen könnt, haben wir bereits ein fetiges und sehr schönes Chassi und so bleibt hinter den Motoren gerade einmal 14mm Platz um die Lichtschranke und eventuel auch etwas Elektronik zu befestigen.

Im März 2007 starteten wir bereits unseren ersten Versuch dieses Problem zu lösen. Damals scheiterten wir knapp an der zu schlechten Auflösung der Lichtschranken.

Die neuen Encoder

Für die neuen Encoder verwenden wir daher zwei Lichtschranken ROHM RPI 243 von Pollin, welche nur wenige Milimeter groß sind. Anstelle der Lochraster Platinen erstellten wir "echte" Platinen und verwendeten ausschliesslich SMD-Bausteine. Der Aufbau wurde wie im ersten Versuch beibehalten.

Die Encoder bestehen aus zwei Platinen die zusammengesteckt werden können. Auf der einen Platine befinden sich zwei Gabellichtschranken und einige Widerstände zur Ansteuerung. Rechts ist diese Platine einmal bgebildet. Gut zu erkennen ist die Aissparung in der Mitte für das Motorlagen. Die großen Kupferflöchen sind für die Spannungsversorgung der Motoren. Im Hinteren Teil befinden sich die beiden Lichtschranken. Mit Hilfe eines Spigels und der Handykamera konnten wir die Richtige Pohling der IR-LEDs testen.

Sonntag, November 02, 2008

Neue Motor-Encoder

Encoder für RB-40 Motoren
  • Neue Gabellichtschranken ROHM RPI 243 von Pollin
  • Die Lichtschranke wurde mit 120 Ohm für die LED und 2.2k für den Transistor nach dem Datenbatt ausgelegt.
  • alles in SMD, damit es noch flacher wird
  • Schmitt-Trigger  (74ls14) von Conrad Mir hat der Verkäufer nichts ahnend als TTL verkauft. Die Herauskommende HIGH-Pegel liegen nur bei 3,4 V und mussten durch einen zusätzlichen Pull-Up Widerstand (4,7k) auf einen für CMOS (µC) gültigen Pegel gebracht werden.
  • Neues Platinen Layout mit endlang des Motor herausgeführten Steckern für die sensor-Platine und umgebauten Schraubklemmen für den Motor-Anschluss. Der Motorenanschlus wurde durch 100n und 47n Fahrad Kondensatoren bereists auch der Platine entstört.
  • Gesammter Aufbau ist nur 8mm dick
  • Er besteht aus zwei Platinen die durch Steckverbinder aus Prätzisions-Sockelleisten erstellt wurden.
Aufbau der Platinen
Befestigung der Schlitz-Scheibe
Tests im Labor

Samstag, März 17, 2007

Fehlerhaftes Signal

Bei der Entwicklung meines zweiten Encoders ist mir ein Fehler unterlaufen, den ich nicht leicht finden konnte.

Mein Roboter ist mit zwei Motoren ausgestattet, die je einen neuen Encoder bekommen haben. Über eine serielle Verbindung lasse ich mir die Drehzahlen der Motoren am PC ausgeben.

Diese Daten habe ich in eine Exceltabelle gebracht und musste leider feststellen, dass ein Encoder schlechte Signale liefert.

Auf den Bildern ist so eine Messreihe zu sehen, bei der die Motoren mit konstanter Geschwindikeit drehen. Eigentlich sollte dann der Encoderwert nur +/- 1 springen.



Nachdem ich die Schaltung noch einmal intensiv nach Fehler durchsucht hatte und ich keinen Fehler feststellen konnte habe ich mir die Signale an einem Oszi angesehen. Das obere Bild zeigt den heilen Encoder mit zwei um 90° phasenverschobenen Signalen. Ein Highlevel bedeutet, dass der Transistor Licht bekommen hat. Ein Lowlevel bedeutet, er wurde abgeschattet.
Das untere Bild zeigt die Signale des defekten Encoder.
Es ist deutlich zu sehen, dass die Abschattung nur sehr kurz ist und beim oberen Signal sogar manchmal ausfällt.
Dies führt dazu, dass die Auswertung kurzzeitig ein Rückwärtsdrehen erkennt und so die Signale stark schwanken.

Der Grund dafür war, dass ich zwei IR Leuchten verwendet habe. Sie erzeugten so viel Licht, dass die Transistoren nur einen kurzen Moment aus gingen. Wenn die Lochscheibe dazu noch etwas eierte, wurden Signale ganz ausgelassen. Ich habe eine IR-LED ausgelöten und nun funktioniert auch mein zweiter Encoder tadellos. Mir war beim Messen am Oszi schon aufgefallen, dass der erste Encoder weniger Strom verbrauchte. Ich denke bei dem war zufälligerweise schon eine IR-LED defekt, weshalb er von anfang an so gut funktionierte :-).

zur Animation klick -->

Drehzahl Encoder für RB40 Motoren

Viele kennen sicher das Problem, dass man irgendwie die Drehzahl der Räder/ Motoren messen möchte.

Häufig habe ich gesehen, dass dies über eine Hell- /Dunkelerkennung am Antriebsrad gemacht wird. Teure Motoren hingegen haben einen Encoder direkt hinten bei den Anschlüssen. Ich habe mich mal daran versucht, auch einen Drehzahlmesser direkt an den Motoren zu bauen.

Als erstes habe ich mir zwei Platinen in Form der Motoren ausgeschnitten und in die eine Platine Löcher für das Motorlager und die Anschlüsse gebohrt. Anschließend habe ich zwei Aussparungen für Infrarottransistoren (LPT80) gefräst.



Auf der zweiten Platine habe ich an der gleichen Stelle auch eine Aussparung gefräst, dieses mal für die IR-Leds. Die Platinenverbinder bestehenen aus einzelnen IC-Sockestiften.






Nach einigen Versuchen und ein paar kaputten IR-Transistoren habe ich dann eine geeignete Schaltung gefunden und auf die Platinen gelötet. Sie besteht aus ein paar Vorwiderständen und einem Schmitttrigger. Auf dem vierpoligen Stecker befinden sich die Versorgungsspannung und zwei Phasensignale. Sie liefern mir zwei um 90° phasenverschobene Encodersignale.

Da die IR-Transitoren nicht durch Schlitzblenden abgedeckt sind, musste ich die Lochscheibe recht grob bemessen (vier Einteilungen).

Die Motoren lassen nicht gerade viel Platz zur Befestigung (gerade mal 14mm), also habe ich die Lochscheiben einfach auf das Wellenende geklebt.


Schafft der µC noch die Auswertung?
Die Motoren drehen mit maximal 6000 UPM und erzeugen pro Umdrehung 16 Flanken (je Sensor und je Hell- /Dukenwechsel); macht max. 96000 Flanken pro Minute, also 1600 Flanken pro Sekunde.
Die Abtastung der Signale sollte vom µC mindestens doppelt so schnell sein wie 3,2 kHz, am besten gleich 5kHz. Auf diese Frequenz habe ich mein Programm eingestellt und bin sehr zufrieden.

Sonntag, August 06, 2006

FPGA Spartan-3

So endlich sind die Klausuren durch und ein wirklich anstrengendes Semester (das 4.) findet damit seinen Abschluss. Jetzt habe ich endlich wieder die Zeit etwas zu programmieren und zu basteln. Endlich kann ich meine Geburtstagsgeschenke ausprobieren. In den letzten 6 Wochen kam ich leider nicht dazu. Seit dem 19.06. darf ich ein Spartan-3 von Xilinx mein eigen nennen. Cool :) !! (Danke schön noch einmal an dieser Stelle an meinen Bruder!) Mit Erstaunen durfte ich allerdings feststellen, dass das mitgelieferte Netzteil nur einen Amerikanischen Stecker hat, der nur zwei zu eng beieinander stehende flache Stecker hat. Nach ca. 10 Minuten Suchen im Haus nach einem passenden Adapter und 5 Minuten schauen, ob ich nicht ein vergleichbares Netzteil habe, gab ich auf. Habe aber eine schöne Entdeckung gemacht: Der Abstand der beiden Stegen ist der gleiche wie an einem Kaltgerätestecker, allerdings waren die Stege zu breit. Kurz etwas abgeschliffen und abgeschrägt - fertig! „Einem Ingenieur ist nichts zu schwör“ Jetzt probiere ich erstmal den FPGA aus.

Samstag, April 29, 2006

Sensorneuheiten

Unser kleiner Bot nimmt mit der Zeit richtig Form und Gestalt an. Da er ja balancieren soll,

Danke schön

Ich möchte hier einmal ganz, ganz lieb meiner Freundin danken, die für uns die Blogs Korrektur liest und Unmengen an Rechtschreibfehlern korrigieren muss. Danke schön!!!

Samstag, April 08, 2006

Fotos der Plexiglasbearbeitung

Auf den folgenden Bilder ist zu sehen, wie wir die Plexiglasteile bearbeitet haben:

Alu und Glas

Der nBot mit neuem Gesicht!!

Endlich sind die Aluteile fertig - sie sehen wirklich gut aus! Wir hatten aus Werkzeugmangel und damit verbundenen fehlenden Möglichkeiten, die drei von uns benötigten Aluminiumteile einer ansässigen Metallbe- und -verarbeitungsfirma in Auftrag gegeben. Nach einigen kleineren Verzögerungen (die Mitarbeiter hatten einfach viel zu tun) konnten wir die fertigen Aluteile abholen. Jetzt waren wir soweit, ein stabiles Grundgerüst zusammen zu bauen. Die Aluteile hat Olaf mit viel Mühe und Geduld glatt geschliffen, um kleine Kratzer und Verschmutzungen zu entfernen. Danach haben wir alles ausführlich poliert, jetzt sehen die Teile sehr edel aus! Bei eBay haben wir Plexiglas günstig ersteigert. Es ist 10mm dick und nicht in einem Baumarkt zu finden. Aus den Platten haben wir zuerst die Grundplatte hergestellt. Durch unsere besondere Anordnung des Werkstücks zur Stichsäge und den Einsatz einer Mittelpunktfixierung, ist es uns gelungen perfekte Rundungen auszuschneiden. Danach habe ich die Seiten geschliffen - erst grob, dann fein - und zum Schluss mit Zahnpasta und Wasser bearbeitet, bis sie ganz klar waren. Um den Rand wirklich richtig klar zu bekommen, benötigt man einen Bunsenbrenner, mit dem man vorsichtig über die Kanten geht!