Guten Tag,
ich habe folgenden Arduino Sketch für einen rotary encoder gefunden:
1
#define clkPin 2
2
#define dtPin 3
3
#define swPin 4 //the number of the button
4
5
intencoderVal=0;
6
7
voidsetup()
8
{
9
pinMode(clkPin,INPUT);
10
pinMode(dtPin,INPUT);
11
pinMode(swPin,INPUT);
12
digitalWrite(swPin,HIGH);
13
Serial.begin(9600);
14
}
15
16
voidloop()
17
{
18
intchange=getEncoderTurn();
19
encoderVal=encoderVal+change;
20
if(digitalRead(swPin)==LOW)
21
{
22
encoderVal=0;
23
}
24
Serial.println(encoderVal);
25
}
26
27
intgetEncoderTurn(void)
28
{
29
staticintoldA=HIGH;
30
staticintoldB=HIGH;
31
intresult=0;
32
intnewA=digitalRead(clkPin);
33
intnewB=digitalRead(dtPin);
34
if(newA!=oldA||newB!=oldB)
35
{
36
// something has changed
37
if(oldA==HIGH&&newA==LOW)
38
{
39
result=(oldB*2-1);
40
}
41
}
42
oldA=newA;
43
oldB=newB;
44
returnresult;
45
}
Ich kenne die Programme für einen Rotary Encoder eigentlich nur mit zwei
Kanälen eines Timers. Hier wurde dies allerdings sehr einfach gelöst.
Warum benötigt man beim Arduino keine Timer und lässt sich dieser Sketch
auf auf "normale" µC anwenden?
Wahrscheinlich weil das Programm nichts zu tun hat und somit eine
relativ hohe Abfragefrequenz zustande kommt.
Das Programm macht offensichtlich keinen Unterschied – ist ja auch
sinnvoll – zwischen einer "Änderung" pro Jahr oder bei jeder "Runde".
Würde mich aber nicht wundern, wenn es auf der seriellen Schnittstelle
eng zugeht.
habmalnefrage schrieb:> Warum benötigt man beim Arduino keine Timer und lässt sich dieser Sketch> auf auf "normale" µC anwenden?
Was unterscheidet, deiner Meinung nach, einen Arduino von einem
"normalen" uC?
habmalnefrage schrieb:> Ich kenne die Programme für einen Rotary Encoder eigentlich nur mit zwei> Kanälen eines Timers.
Das kenne ich nun wieder nicht. Wozu braucht man zwei Kanäle?
> Hier wurde dies allerdings sehr einfach gelöst.
Die vordergründige Einfachkeit ist nur eine Seite der Medaille.
> Warum benötigt man beim Arduino keine Timer und lässt sich dieser Sketch> auf auf "normale" µC anwenden?
Dieses Programm macht nicht anderes, als permanent den Encoder auf eine
Veränderung des Zustands zu prüfen. Es verbrennt so 100% CPU-Zeit und
kann überhaupt nichts anderes machen.
Wenn die Abfrage des Encoders also das einzige ist, was das Programm
jemals machen soll, dann kann man das natürlich so machen.
In 99.9% der Fälle wird das aber nicht so sein. Und wenn man sich nicht
in der Hauptschleife auf ein festes Zeitregiment festlegen will, dann
wird man den Encoder sinnvollerweise in einem Timerinterrupt abfragen.
Siehe Artikel Drehgeber
habmalnefrage schrieb:> Warum benötigt man beim Arduino keine Timer und lässt sich dieser Sketch> auf auf "normale" µC anwenden?
Auf deinem Arduino-Board werkelt ein "normaler" µC, wahrscheinlich ein
AVR von Atmel, genauer ein ATmega328 o.ä.
Auf deinem Arduino läuft während dessen sogar ein Timer, aber der wird
für den Encoder in der Tat nicht gebraucht.
Falls du einen Arduino mit ARM Prozessor hast, kannst du den Encoder
auch ganz ohne Programmaktion auswerten. Dann macht der das per Hardware
und im Programm kannst du, wenn dich die Position interessiert, einfach
den HW-Zähler auslesen.
habmalnefrage schrieb:> Hier wurde dies allerdings sehr einfach gelöst.
Allerdings. Es wird absolut keine Rücksicht auf prellende Kontakte
genommen. Das ist unterstes Bastelniveau und bestenfalls für ein
Funktionsmodell zu brauchen...
Lothar M. schrieb:> Allerdings. Es wird absolut keine Rücksicht auf prellende Kontakte> genommen.
Der Gray-Code wird sich nicht verzählen, solange jeder Kontakte nur beim
Umschalten prellt und die Prellphasen sich zeitlich nicht überlappen.
@Werner
>Der Gray-Code wird sich nicht verzählen, solange jeder Kontakte nur beim>Umschalten prellt und die Prellphasen sich zeitlich nicht überlappen.
Du redest von einem anderen Encoder.
Und von welchem Programm redest Du eigentlich?
Werner M. schrieb:> Der Gray-Code wird sich nicht verzählen,
Da wird kein Gray Code ausgewertet.sondern einfach eine Flanke an A und
daraus folgend der Pegel an B.
Wenn B sich nicht ändert, aber A prellt, dann zählt der Ausgang
trotzdem munter in die selbe Richtung.
Und diese Abfrage hier ist wirkungslos und unnötig wie ein Kropf:
> if (newA != oldA || newB != oldB)
habmalnefrage schrieb:> Wieso braucht man bei diesem Arduino Sketch für einen Rotary Encoder keinen
Timer?
Weil die main-Loop eine Zeitverzögerung durch diese aufwändige Routine
hat:
> Serial.println(encoderVal);
die ungefähr zur nötigen Zeitverzögerung passt.
Lothar M. schrieb:> Da wird kein Gray Code ausgewertet.sondern einfach eine Flanke an A und> daraus folgend der Pegel an B.> Wenn B sich nicht ändert, aber A prellt, dann zählt der Ausgang> trotzdem munter in die selbe Richtung.
Das ist leider wahr. Daher TROTZ der eigentlich ausreichenden
Abtastfrequenz den Code umgehend entsorgen.
Sebastian S. schrieb:> Du redest von einem anderen Encoder.
Ich meine den Rotary Encoder mit seinen phasenverschobenen A/B-Signalen,
nicht das Programm, das die Signale decodiert. Im Programm muss man nur
dafür sorgen, dass A/B in eine FSM reinlaufen. Für die
Positionsbestimmung ist ein Entprellen dann nicht notwendig. Falls einen
das Hoch-Runterzählen während des Prellens stört, muss man natürlich
Maßnahmen ergreifen.
Ich habe nochmal eine allgemeine Frage zum Drehgeber:
Die Drehrichtung wird ja bekanntlich folgendermaßen bestimmt: Man hat
zwei um 90 Grad verschobene periodische Rechtecksignale A und B. Man
schaut sich B nun immer bei fallender Flanke von A an.
B negativ -> Gegen Uhrzeigersinn
B positiv -> In Uhrzeigersinn
Wie sehen nun A und B aus, wenn ich den Drehgeber nicht drehe? Sind dann
beide Signale 0? Oder wie kann ich erkennen, dass nicht gedreht wird?
joop13 schrieb:> Wie sehen nun A und B aus, wenn ich den Drehgeber nicht drehe? Sind dann> beide Signale 0?
Woher soll der Drehgeber wissen, ob er gedreht wird?
Wenn er nicht gedreht werden, stehen die Signale von A und B auf dem
Wert, auf den sie zuletzt gesprungen sind - wenn du Glück hast.
Bei Drehgebern ohne Rastung kann der Geber auch genau auf beliebigen
Kante stehen, so dass ein Signal, je nach Flügelschlag eines
Schmetterlings in Neuseeland oder anderer Welteinflüsse, munter hin und
her zappelt. Bei Gebern mit Rastung gibt es welche, bei denen eines der
Signale auf der Rastposition, genauso auf der Raste oder - je nach
Fertigungstoleranzen - beliebig dicht daneben steht.
joop13 schrieb:> Die Drehrichtung wird ja bekanntlich folgendermaßen bestimmt:
Nein. Das ist zwar eine mögliche Art, die Drehrichtung zu bestimmen,
aber weder die einzige und schon gar nicht die beste.
Wie man es richtig macht, steht im Artikel Drehgeber> Wie sehen nun A und B aus, wenn ich den Drehgeber nicht drehe?
<seufz>
> Sind dann beide Signale 0?
Nein?
> Oder wie kann ich erkennen, dass nicht gedreht wird?
Vielleicht daran, daß sich die Signale nicht ändern?