Hallo,
Ich glaube, ich habe da ein Problem und stehe auf dem Schlauch.....
Alsoooo...
ich beschäftige mich gerade mit Drehgebern und deren Auswertung mit
einem µC. Ich bin allerdings gerade etwas verwirrt denn in
verschiedenen Quellen
Beitrag "Drehgeber auslesen"http://www.mikrocontroller.net/articles/Drehgeber
und den Tutoriell über Drehgeber von Peter, verstehe ich nur Bahnhof vom
Code.
Ich habe sogar auf Papier versuch die Logik zu verstehe, leider nichts.
Mit meinem Code kann der Drehgeber nur dekrementieren B Chanel wird nie
auf 1 gesetzt, Natürlich habe ich beide Ausgänge ausgeführt und auf dem
Oszilloskop geschlossen, dort ist die Pegel und Flanke Wechselung
richtig angezeigt.
Ich komme einfach nicht weiter.
kann mir jemand weiter helfen?
Hier unter meine Drehgeber Auswertung Überlegung und dann die Code, die
ich mir ausgedacht habe.
Rechst (Vorwärts)
Gray-Code - Binär-Code
11 - - - 10 = 01 (1)
01 - - - 00 = 01 (1)
00 - - - 11 = 01 (1)
10 - - - 01 = 01 (1)
Links (Rückwärts)
Gray-Code - Binär-Code
01 - - - 10 = 11 (3)
11 - - - 00 = 11 (3)
10 - - - 11 = 11 (3)
00 - - - 01 = 11 (3)
(PINB&(1<<PB1)) ist entweder 0 oder 2, aber niemals 1.
Entweder du schreibst !=0, oder lass den Vergleich einfach ganz weg.
PS: Erwarte aber nicht, dass der Code als Ganzes dann geht. Da sind noch
andere Probleme in der grundsätzlichen Logik.
Stefan Ernst schrieb:
> PS: Erwarte aber nicht, dass der Code als Ganzes dann geht. Da sind noch> andere Probleme in der grundsätzlichen Logik.
zb hier:
1
if((PINB&(1<<PB0))==0)//Wenn A auf 0 geht (R oder L drehen)
das testet nicht, ob A von 1 auf 0 gewechselt hat.
Das testet, ob A gleich 0 ist. Das ist aber etwas völlig anderes. A
kann eine halbe Stunde auf 0 stehen, wenn zb niemand am Encoder dreht.
danke erst mal
>PS: Erwarte aber nicht, dass der Code als Ganzes dann geht. Da sind noch>andere Probleme in der grundsätzlichen Logik.
Genau diese Logik versuch ich seit ewig zu verstehen.
Mit deinem Vorschlag, kann ich jetzt inkrementieren, aber nicht mehr
dekrementieren. Und sogar beim Abbruch Drehgeber zu drehen, zähl er
weiter.
Das verstehe ich schon, weil wenn beim Abbruch die Phase immer auf 0
dann zähl er weiter.
Wie kann ich dann diese Logik vom Drehgeber am besten programmieren!?!?
Rechst (Vorwärts)
Gray-Code - Binär-Code
11 - - - 10 = 01 (1)
01 - - - 00 = 01 (1)
00 - - - 11 = 01 (1)
10 - - - 01 = 01 (1)
Links (Rückwärts)
Gray-Code - Binär-Code
01 - - - 10 = 11 (3)
11 - - - 00 = 11 (3)
10 - - - 11 = 11 (3)
00 - - - 01 = 11 (3)
Danke
Wie waere es erst einmal mit einer einfachen, aber uebersichtlichen
Variante?
if ((PINB&(1<<PB0))==0) //Wenn A auf 0 geht (R oder L drehen)
{
if ((PINB&(1<<PB1))==1) enc_delta++; //Wenn A=0 und B=1 inc
else if ((PINB&(1<<PB1))==0) enc_delta--; //Wenn A=0 und B=0 dec
Wenn ich sowas schon sehe - hat man es als Anfaenger nicht schon schwer
genug, als dass man sich noch mit Unuebersichtlichkeit quaelen muesste?
Ein Drehgeber funktioniert doch ganz einfach, du hast zwei Pins, die
geben zusammen einen Wert. Wenn sich der Wert aendert, ist der Gegeber
bewegt worden. Die Richtung haengt davon ab, wie der Wert vorher war und
wie er jetzt ist. Das steht in den Tabellen oben. Also machst du erst
mal primitiv einen dicke if-else-Baum. Wenn du das hast und es
funktioniert, baust du es auf eine Tabelle um. Und wenn das geht, kannst
du dich ja an die xor-Variante machen.
Peter Stegemann schrieb:
> Wenn sich der Wert aendert, ist der Gegeber> bewegt worden.
Ich denke, hier liegt der erste Knackpunkt:
Wenn sich der Wert ändert.
Also muss als erstes eine Auswertung her, die feststellt ob sich der
Wert überhaupt verändert hat.
Das geht aber nicht, indem man nur den momentanen Zustand der Pins
betrachtet. Eine Veränderung kann man nur feststellen, wenn man einen
Zustand von vorher mit dem jetzigen Zustand vergleicht.
1
ISR(TIMER2_COMP_vect)// for manual movement
2
{
3
...
4
5
now=PINB&((1<<PB0)|(1<<PB1));// es interessieren nur
6
// die Bits PB0 und PB1
7
8
if(now!=old)// nur wenn eine Veränderung fetsstellbar ist
9
{
10
...
11
12
13
old=now;// jetziger Zustand ist für die nächste Abfrage der
14
// vorhergehende Zustand
15
}
16
}
Durch geeignete Umformungen landet man dann irgendwann bei Peters Code.
nach vielen Überlegungen bin ich auf dieselbe Variante wie peter
gekommen.
für mich wäre es die Optimal Lösung für meinen Fall.
Leider kriege ich manchmal den Wert inkrementiert oder dekrementiert
unabhängig vom Drehrichtung.
soll meine Frequenz bestimmt sein.
ich habe 1000 Impulse pro Umdrehungen und dreh Manuel mit dem Hand.
Kann jemand mir mein Fehler zeigen?!.
MFG
Danke
> ISR( TIMER2_COMP_vect ) // 1ms for manual movement
Diese eine ms ist OK für Geber mit 16 oder 32 Rastungen pro Umdrehung.
Bei 1000 Impulsen pro Umdrehung bist du hier viel zu langsam.
wie berechnet man das !?!?!
wie komme ich drauf dass für 1000 Impulsen pro Umdrehung ich eine andere
frequenz brauche.
Habe gerade mit 16 Hz probiert jetzt habe ich probleme mit meinem
UART!!!!!!
gast schrieb:
> wie berechnet man das !?!?!
gar nicht. Sondern man denkt ein wenig nach.
> wie komme ich drauf dass für 1000 Impulsen pro Umdrehung ich eine andere> frequenz brauche.
Du schätzt wie lange es wohl dauert mit der Hand den Encoder einmal zu
drehen.
Bei einer Umdrehung verändert der Encoder 1000 mal seine Stellung. Aus
deiner Schätzung weißt du daher auch wie lange es dauert, bis der
Encoder einmal seine Stellung wechselt. Und dann denkst du daran, dass
du mindestens 2-mal in dieser Zeit nachsehen solltest, ob sich der
Encoder verändert hat.
Und dann nimmst du das alte Motto der Technik her: Grau lieber Freund
ist alle Theorie, schlag lieber noch einen Faktor 3 zur Sicherheit
drauf.
> Habe gerade mit 16 Hz probiert
Welche 16 Hz denn?
Ich kann mich dem Eindruck nicht verwehren, dass du im Dunkeln
stocherst...
> Leider kriege ich manchmal den Wert inkrementiert oder dekrementiert> unabhängig vom Drehrichtung.
Was passiert, wenn du gaaaaaanz laaaangsaaam drehst?
>> Was passiert, wenn du gaaaaaanz laaaangsaaam drehst?> es geht> aber wenn bei schneller Drehung nicht
Also, dann siehst du jetzt mal zu, dass der 1 ms Timer-Interrupt
wesentlich öfter kommt. Als Gedankengrundlage nimmst du das, was Karl
heinz Buchegger schon schön beschrieben hat.
Z.B. 1 U/s per Hand macht 1000 Impulse/sec, bei 4-fach Auswertung und
mindestens doppelter Abtastrate sind das dann 8000 Hz. Dazu die 3-fache
Sicherheit gibt ca. 25kHz.
Fazit: stell den Timer auf eine Wiederholzeit von ca. 40 us ein...
Ob dir die übrige Rechenleistung dann noch ausreicht, das steht auf
einem anderen Blatt :-/
Karl heinz Buchegger schrieb:
> Und dann nimmst du das alte Motto der Technik her: Grau lieber Freund> ist alle Theorie, schlag lieber noch einen Faktor 3 zur Sicherheit> drauf.
Und wenn ein boshafter Benutzer den Knopf "anschnippt", hast du immer
noch zu wenig :-/