Hi,
in einem meiner Projekte verwende ich einen Drehencoder.
Der Encoder hat ne Rastung, pro Rasteinheit liefert er zwei Inkremente
ab.
Prinzipell funktioniert die Auswertung. Angeschlossen ist der Drehgeber
an zwei externe INTs (PinChange an AVR ATmega88).
Im Programm gibt es nun Probleme, weil das Ding prellt. Ne "normale"
Entprellung kommt nicht in Frage, weil man ja keine Pulse verpassen
will.
Das Problem ist, daß Linksdrehen (-) nicht die Umkehrung von
Rechtsdrehen (+) ist, d.h. im Programm wird die Folge +-+ anders
interpretiert als ++- anders als + etc.
Hat jemand ne Idee wie man das lösen könnte? Hier mal die
C-Implementierung:
1
#ifndef _DREHGEBER_H_
2
#define _DREHGEBER_H_
3
4
#define DREH_INVALID -128
5
6
staticinlinechardrehgeber_step(void);
7
staticinlinechardrehgeber_job(void);
8
9
#if defined (__GNUC__) && defined (__AVR__)
10
# include <avr/pgmspace.h>
11
#else
12
# define PROGMEM
13
# define pgm_read_byte(x) (*(x))
14
#endif // avr-gcc
15
16
// Aufrufen, wenn eine Flanke an einem der Ports festgestellt wurde,
>Im Programm gibt es nun Probleme, weil das Ding prellt. Ne "normale">Entprellung kommt nicht in Frage, weil man ja keine Pulse verpassen>will.
Macht man im TImerinterrupt alle 1 bzw. 10ms.
Drehgeber: Beispielcode in C
#ARGL#
Hätt ich auch seber mal draufkommen können, das auszuprobieren...
Reagiert im 10ms-Job zwar merklich langsamer als vorher, aber wenigstens
zählt er nicht mehr falsch...
EDIT
und @ 2.5kHz ist's so wie ich's mir vorstelle :-)
So einfach ist die Welt...
Codevorschlag ohne Klimbim (für Encoder mit 2 Werten pro Rasterung im
polling):
neu= PORTB&0b.0000.0011; // einlesen der beiden Pins
if (alt!=neu)
{
// Auswertung der Richtung
// jede Richtung hat separaten Zähler
if(alt==0 && neu==1)zahler_down++;
if(alt==1 && neu==3)zahler_down++;
if(alt==3 && neu==2)zahler_down++;
if(alt==2 && neu==0)zahler_down++;
if(alt==0 && neu==2)zahler_up++;
if(alt==2 && neu==3)zahler_up++;
if(alt==3 && neu==1)zahler_up++;
if(alt==1 && neu==0)zahler_up++;
//wenn einer der Richtungszähler den Wert 2 hat
//wird er auf Null zurückgesetzt und der Hauptzähler bewegt
if(zahler_up == 2) {Hauptzahler++; zahler_up=0;}
if(zahler_down == 2) {Hauptzahler--; zahler_down=0;}
//zum Entprellen:wenn ein Zähler den Wert 1 erreicht
//wird die Gegenrichtung zurückgesetzt
if(zahler_up == 1) {zahler_down=0; }
if(zahler_down == 1) {zahler_up=0; }
alt=neu;
}
ich weiss der thread ist alt , ist bei google aber noch weit vorne wenn
man nach --Drehencoder entprellen-- sucht
fantozzi schrieb:> Codevorschlag ohne Klimbim
Also 13 IFs, das ist ne riesen Menge Klimbim.
Der Code im obigen Link braucht kein einziges IF, der ist kurz und
knackig (wenig Zyklen, wenig Flash).
Peter
Dietmar Steiner schrieb:> auf alle Fälle mit 0,1 uf keramik c von den pulskontaten nach masse.>> das ist oft mehr als die halbe miete !!!
Da der Thread offenbar bei der Suche noch so weit vorne ist:
Oben genannten Tipp bitte unter keinsten Umständen machen. Das ist
allergröbster Pfusch und zerstört nicht nur die Kontakte, sondern
erzeugt auch noch extreme Störungen.