Motor-Encoder erzeugt bei hohen Drehzahlen Fehlern
Hallo zusammen,
[right:abd365b507]http://3.bp.blogspot.com/_qPTJUGegS5w/RfvkFxfGqDI/AAAAAAAAABE/nWNJ4RsGsVU/s200/DSC00519.jpg[/right:abd365b507]
mein Bruder und ich habe Probleme mit unseren Encodern und wir wissen noch nicht einmal ob es ein Denk, Rechen oder Mechanischer Fehler ist. Die Encoder haben wir auf unserem Blog wsgs.blogspot.com ausführlich beschrieben.
Es handelt sich um Encoder für RB-40 Motoren, die am Ende des Motors befestigt werden. Zwei Gabellichtschranken und eine Schlitzscheibe erzeugen zwei um 90° verschobene Signale. Ein Schmitttrigger säubert die Signale für einen µC. Die Auswertung wird durch einen der neueren ATmega328P durchgeführt. Dessen Eingänge lassen sich als Interrupt für steigende und fallende Flanke konfigurieren. Bei jeder Flanke von Signal A oder B wird die Interrupt Service Routine gestartet und die Drehung ausgewertet.
[right:abd365b507]http://1.bp.blogspot.com/_qPTJUGegS5w/SW98EhOdfNI/AAAAAAAAAHs/1M6r8rg5IF8/s320/DSC01080_filtered.jpg[/right:abd365b507]
Die Rechnung:
Da ich mich schon einige male verrechnet habe wollte ich euch bitten über meine Rechnung zu schauen. Meist hilft es ja schon, wenn man es ausführlich hinschreibt.
Die Schlitzscheibe hat 32 schwarze Felder. Bei jedem Feld werden 4 Flanken erzeugt (steigend, fallend Lichtschranke A und steigend, fallend Lichtschranke B). Der Motor macht bis zu 5000 Upm.
Bild hier
Es werden also fast 11 tausend Interrupts pro Sekunde erzeugt. Der µC läuft deswegen mit 20Mhz und soll dabei zwei Motoren auswerten können (erst mal reicht einer).
Bild hier
Zwischen jedem Interrupt können also 1875 Maschienenbefehle ausgeführt werden. Nun hängt es von der ISR ab, wie viele Maschinenbefehle sie braucht und wie viele für andere Programmaufgaben übrig bleiben.
Die ISR
Die Interrupt Service Routine erzeugt zwei Werte die zum Test alle 100ms über UART ausgegeben werden.
Code:
public volatile long lEncoder;
public volatile long lError;
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++;
}
}
Das Problem:
Wenn ich jetzt die Geschwindigkeit des Motors über 2000Upm hoch drehe kommen immer mehr Fehler (lError steigt), bis keine Auswertung mehr möglich ist. Ist der µC zu langsam für die Aufgabe? Oder kann man ihn noch etwas endlasten, wir ISR in Assembler oder Vorteiler?
Vielen Dank schon mal für eure Mühe
Guß Xaver
Re: Motor-Encoder erzeugt bei hohen Drehzahlen Fehlern
Hi Xaver,
Zitat:
Zitat von Xaver
... Probleme mit ... Encodern ...
Mehrere Dinge verstehe ich nicht.
Gut, ich habe (noch) kein invertierendes Pendel aufgebaut, aber ich weiß, dass hier eine gute Auflösung benötigt wird. Mit meinen kleinen Gabellichtschranken löse ich eine Größenordnung weniger auf - 1500 Hz, allerdings wird bei mir nur (?) auf steigende Flanke getriggert. Die entsprechende Regelung läuft hervorragend.
Als Denkfehler sehe ich an, dass Du direkt am Motor die Drehzahl erfasst >>>um das Lagerspiel auszublenden<<<. Ok, dann regelst Du den Motor - und kannst bei genügend guter Auflösung innerhalb des Lagerspiels regeln - dabei bleiben die Räder stehen *ggggg* und nur das Getriebe ruckelt hin und her, bei 1:100 schon eine denkbare Geschichte. Das bringts doch nicht!
Zitat:
Zitat von wsgs.blogspot
... Dies sollte die größte Messgenauigkeit und schnellste Erfassung der Motoren ergeben, da das Lagerspiel nicht mit erfasst wird...
Wenn ich ein invertierendes Pendel aufbaue, würde ich erstmal auch nicht den Motor bzw. das Getriebe auf seine Abtriebsdrehzahl regeln (und schon garnicht ohne das Getriebespiel in die Regelung einzubeziehen), sondern eine Lageregelung aufbauen ungefähr so: kippt links => Motor rechts, kippt rechts => Motor links. Aber das ist ja DEIN Projekt.
Sehen wir doch mal, was die Regelung theoretisch bringt. Da Du keine Angabe über die Getriebeübersetzung machst, nehme ich versuchsweise an, dass Du ein Getriebe 1:100 hast. Du könntest also (nach Deinen Angaben: 32 Felder x 4 Flanken) über 12.000 ticks pro Radumdrehung auflösen (32 x 4 x 100). Geschätzter Raddurchmesser nach Deinem Blog-Bild: 60 mm => Auflösung theoretisch 15 tausendstel Millimeter (0,016). Wenn ich ohne Hemmungen sprechen darf: da vermute ich, dass das Unsinn ist - sorry - also: Frage: ist das nicht etwas hochgestochen? Wie mehrfach angedeutet: das Getriebespiel ist damit NICHT vom Erdboden - und es ist ausserhalb des angestrebten Regelkreises.
Zitat:
Zitat von Xaver
... Ein Schmitttrigger säubert die Signale für einen µC ...
Uuuuups - wusste garnicht, dass ich soooo schlampig arbeite: meine Gabellichtschranke geht mit einem nicht allzu kurzen Kabel - entlang der PwM-versorgten Motorzuleitung - ohne sonstwas zum µC. Störungen: nicht erkannt. Dein Aufbau ist ja vermutlich sehr sauber - aber ist das notwendig/erforderlich?
So, das waren nur meine ersten Eindrücke - die helfen Dir vermutlich garnicht. Also brauchen wir noch einen Rat:
Rat 1:
Zitat:
Zitat von Xaver
... Die Interrupt Service Routine erzeugt zwei Werte die zum Test alle 100ms über UART ...
Datenübertragung in einer ISR (? - wirklich in der ISR - oder doch ausserhalb?) von DER Frequenz. Junge Junge! Rechne mal den Zeitbedarf für die Datenübertragung. Oder - einfacher - schalte mal diese Datenübertragung ab und teste Deine Lichtschranke (Daten im Test abspeichern und offline übertragen).
Rat 2:
Lichtschranke 1 auf INT0, Lichtschranke 2 auf INT1. Triggern auf steigende Flanke. Nachteil: es könnte sein, dass Du so die Drehrichtungsumkehr schlechter mitbekommst. Vielleicht könntest Du nach dieser Methode aber erstmal das Ding nach Deinem Konzept zum Laufen bekommen - ist ja nur die halbe Interruptfrequenz.
Viel Erfolg - oder viel Glück