mikrocontroller.net

Forum: Compiler & IDEs Drehgeber aus Artikelübersicht


Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, die Funktion "Incrementalgeber_auslesen" rufe ich alle 50ms auf.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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%.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welches beschriebene Fehlerbild? :-)

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank, funktioniert nun mit der schnelleren Abtastung!

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: Jochen (Gast)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.