Forum: Compiler & IDEs Drehgeber aus Artikelübersicht


von Jochen (Gast)


Lesenswert?

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;
}

von Jochen (Gast)


Lesenswert?

Ach ja, die Funktion "Incrementalgeber_auslesen" rufe ich alle 50ms auf.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Jochen (Gast)


Lesenswert?

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%.

von Volker (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

Welches beschriebene Fehlerbild? :-)

von Klaus F. (kfalser)


Lesenswert?

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.

von Jochen (Gast)


Lesenswert?

Vielen Dank, funktioniert nun mit der schnelleren Abtastung!

von Jochen (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

Schon mal
 http://www.mikrocontroller.net/articles/Drehgeber
gelesen (und verstanden)?

von Jochen (Gast)


Lesenswert?

Gelesen ja, verstanden nicht so ganz. Weiß nicht, wie man auf die 
Dekodiertabelle kommt.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Jochen (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.