Hallo, ich habe einen Incrementalgeber und nutze den Compiler von Codevision und habe mir folgenden Code aus der Artikelsammlung "zusammengesucht". Leider funktioniert er komischerweise sporadisch, aber ich weiß nicht, was ich falsch mache. Sieht wer von euch einen Fehler?? volatile char enc_delta; flash char table[16] = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0}; void Incrementalgeber_auslesen(void) { static char last = 0; static char val; last = (last << 2) & 0x0F; if ( !INC_A_Maske) last |=1; if ( !INC_B_Maske ) last |=2; enc_delta += table[last]; if(val > enc_delta) { printf("Dec"); val = enc_delta; } if(val < enc_delta) { printf("Inc"); val = enc_delta; } return; }
Ach ja, die Funktion "Incrementalgeber_auslesen" rufe ich alle 50ms auf.
Wer soll nicht funktionierenden (was heißt überhaupt "funktioniert sporadisch"?), unvollständigen, unkommentierten, mies formatierten Quelltext unbekannter Herkunft nachvollziehen und versuchen zu verstehen? Wozu? Oder ist es ein HW-Problem? Bevor ich verstehe, wie das obige funktionieren sollte, wenn es denn funktionieren würde, habe ich es neu besser geschrieben.
Ich habe das Codebeispiel "Dekoder für Drehgeber mit wackeligen Rastpunkten" http://www.mikrocontroller.net/articles/Drehgeber nur Umgeschrieben (ohne Interrupt, da die Fkt sowieso alle 50ms aufgerufen wird). Hier ist mir anscheinend ein Fehler unterlaufen, die Hardware geht 100%.
Hatte das gleiche Problem, bei mir geht es nur dann, wenn die Auslesefunktion JEDE 1ms aufgerufen wird. Auch 10ms sind zu langsam und führen zu dem von Dir eschriebenen Fehlerbild
Jochen schrieb: > Ich habe das Codebeispiel > > "Dekoder für Drehgeber mit wackeligen Rastpunkten" > http://www.mikrocontroller.net/articles/Drehgeber > nur Umgeschrieben (ohne Interrupt, da die Fkt sowieso alle 50ms > aufgerufen wird). > > Hier ist mir anscheinend ein Fehler unterlaufen, die Hardware geht 100%. - Eine Überprüfung der Eingänge alle 50 ms erscheint mir sehr wenig, da dürfen sich die Eingänge wirklich nur sehr langsam ändern. Eine Periode der A/B Signale muß dann länger als 200 ms sein, das sind eine Frequenz von max. 5 Hz. Trifft das auf deine Drehgeber wirklich zu=? - Die Auswertung eines Drehgebers muss zu genauen Zeitpunkten erfolgen, sonst wird das Verhalten noch schlechter. Du sagst zwar, die Funktion wird alle 50 ms aufgerufen, aber wie willst Du das garantieren? Hast Du es gemessen? Dein Programm reagiert sicher auf verschiedene Ereignisse und erfüllt verschiedenen Aufgaben, z.B. Reaktion auf Tastendruck, Update des LCD Displays usw. Dies alles macht, dass deine Hauptschleife manchmal länger/manchmal weniger lang dauert. Gerade für diesen Zweck gibt es ja die Interrupt, nutze sie also.
Also, doch noch was. Ich nutze ja folgende Dekodertabelle: // Dekodertabelle für wackeligen Rastpunkt // halbe Auflösung int8_t table[16] PROGMEM = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0}; trotzdem wird jede Drehung um einen Rastpunkt doppelt gezählt. Wie muss ich die Dekodertabelle dann abändern? Und wie komme ich überhaupt auf die Tabelle?? DANKE
Gelesen ja, verstanden nicht so ganz. Weiß nicht, wie man auf die Dekodiertabelle kommt.
Ich beziehe mich i.F. auf den Quelltext darin "Drehgeber mit wackeligem Rastpunkt dekodieren". Das Prinzip ist, daß man zu jedem Zeitpunkt einen Zustand hat, der aus 2 Bits besteht: an/aus bzw. 0/1 für das eine Signal vom Drehgeber, sowie an/aus bzw. 0/1 für das andere. Dieser Zustand zu einem Zeitpunkt reicht aber nicht, um eine Drehung zu erkennen. Dazu muss man auch die beiden Bits vom vorherigen Zustand mit einbeziehen. Dadurch ergeben sich 16 verschiedene Möglichkeiten: 1. eben hatte ich für A den Wert 0 und für B den Wert 0, jetzt 0 und 0 2. eben hatte ich für A den Wert 0 und für B den Wert 0, jetzt 0 und 1 3. eben hatte ich für A den Wert 0 und für B den Wert 0, jetzt 1 und 0 4. eben hatte ich für A den Wert 0 und für B den Wert 0, jetzt 1 und 1 5. eben hatte ich für A den Wert 0 und für B den Wert 1, jetzt 0 und 0 6. eben hatte ich für A den Wert 0 und für B den Wert 1, jetzt 0 und 1 7. eben hatte ich für A den Wert 0 und für B den Wert 1, jetzt 1 und 0 8. eben hatte ich für A den Wert 0 und für B den Wert 1, jetzt 1 und 1 9. eben hatte ich für A den Wert 1 und für B den Wert 0, jetzt 0 und 0 10. eben hatte ich für A den Wert 1 und für B den Wert 0, jetzt 0 und 1 11. eben hatte ich für A den Wert 1 und für B den Wert 0, jetzt 1 und 0 12. eben hatte ich für A den Wert 1 und für B den Wert 0, jetzt 1 und 1 13. eben hatte ich für A den Wert 1 und für B den Wert 1, jetzt 0 und 0 14. eben hatte ich für A den Wert 1 und für B den Wert 1, jetzt 0 und 1 15. eben hatte ich für A den Wert 1 und für B den Wert 1, jetzt 1 und 0 16. eben hatte ich für A den Wert 1 und für B den Wert 1, jetzt 1 und 1 Für jeden dieser 16 Fälle kann man jetzt anhand der Signalketten (siehe Bild im Artikel!) entscheiden, wie der aktuelle Zustand im Vergleich zum vorherigen zu berücksichtigen ist: keine Bewegung (z.B. wenn der aktuelle Zustand gleich dem letzten ist), oder einen vorwärts oder einen rückwärts. Das könnte man jetzt mit vielen if-Entscheidungen machen, was aber viel Code produziert und auch nicht gut lesbar ist. Oder: man packt die 4 Bits (2 für den letzten Zustand, zwei für den aktuellen) in eine Zahl, das macht je nach den Bits einen Wert im Bereich 0 bis 15, und geht mit diesem Wert in eine Tabelle, in der für jede der 16 Möglichkeiten steht, welche Bewegung man hat: -1 für rückwärts, 0 für Stillstand, +1 für einen Schritt vorwärts. Welche Werte (-1, 0, +1) für welchen Fall (binär: 0000, 0001, 0010, 0011, ... 1111) einzutragen sind, muß man anhand der Signalketten sehen. Mehr steckt nicht dahinter.
PS: nicht alle der 16 Fälle sollten vorkommen. Es darf sich ja (wenn man schnell genug ausliest) immer höchstens ein Bit ändern. Ein Wechsel von 00 zu 11 beispielsweise darf nicht auftreten. Wenn man vertrauensselig ist, kann man einfach davon ausgehen daß es eh nicht vorkommt. Dann ist es egal, was an dieser Stelle in der Tabelle steht. Mit etwas Mehraufwand könnte man das aber auch zur Kontrolle verwenden, ob man schnell genug abtastet.
Vielen Dank Klaus Wachtler für diese Super Erklärung!!! Doch unter welchen Bedingungen kann es dann sein, dass ich die Drehung um ein Raster doppelt zähle. Ich habe mittlerweile eine Abtastrate von 5ms und Werte meist doppelt aus.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.