Hi,
Ich habe hier einen mechanischen Drehgeber aus einem Mausrad, den ich
gerne recyclen möchte.
das Ding hat 3 Füße.
Ich habs jetzt einfach so angeschlossen, dass ich an den Mittleren masse
lege und mit die anderen jeweils an einen Pin meines mega8 mit
aktiviertem internenen Pullup.
dann habe ich das Muster geloggt, was sich ergibt, wenn man den
Drehgeber in die eine oder die andere Richtung dreht.
Folgendes kommt dabei raus:
1
/*
2
Note:
3
_ _____
4
| | | | > rechts
5
| |= | O |
6
|_| |_____| > links
7
| | | |
8
| | | |
9
0 G 1
10
11
12
(rechts rum: 11 -> 10 -> 00 -> 11)
13
(links rum: 11 -> 00 -> 10 -> 11)
14
15
turn right turn right turn left turn left
16
| | | | | | | |
17
_______ _______________ _______
18
0 |_________| |____________|
19
_________ _______________ __________
20
1 |_______| |__________|
21
22
23
-->
24
25
\n| 0 0 1 1
26
o\| 0 1 1 0
27
---+------------
28
00 | x l r
29
01 |
30
11 | l r x
31
10 |
32
*/
Anstatt des loggings hab ich in der ISR (selbe Frequenz) nun die
Auswertung versucht um im Programm rechts/links auswerten zu können und
dazu obige Tabelle umgesetzt:
1
typedefenumWheel
2
{
3
Wheel_none,
4
Wheel_left,
5
Wheel_right
6
}Wheel;
7
8
staticvolatileWheels_wheel;
9
10
ISR(TIMER0_OVF_vect)
11
{
12
staticuint8old=3;
13
if(s_wheel==Wheel_none){
14
uint8newVal=(PIND>>2)&3;
15
if(((old==0)&&(newVal==2))
16
||((old==3)&&(newVal==0))
17
){
18
s_wheel=Wheel_left;
19
}elseif(((old==0)&&(newVal==3))
20
||((old==3)&&(newVal==2))
21
){
22
s_wheel=Wheel_right;
23
}
24
old=newVal;
25
}
26
27
28
}
Mein Problem ist nun, dass ich immer nur Wheel_right bekomme.
Ich bin langsam ratlos
Wär nett, wenn von euch mal jemand drüber schaut.
Ist wahscheinlich ein total sinnloser Fehler, aber ich kriegs nicht.
Danke im Voraus!
Vlad
Der bereich zwischen zwei den | | kennzeichnet den Vorgang wärend de
Drehens um eine Stufe.
wenn ich eine Einrastung (hört sich doof an, wie nennt man das?) nach
rechts drehe, gibts diese stufe, dannch bleiben beide low.
wenn ich dann eine weitere Einrastung drehe, gehen beide sofort auf high
Bei links rum ist es logischer weise genau umgedreht.
Die Tabelle habe ich nicht komplett ausgefüllt, da von den Stufen nur
die erste Flanke erkennen wollte, was ja eindeutig sein sollte.
rechts rum:
von 11 -> 10 oder von 00 -> 11
links rum:
von 11 -> 00 oder von 00 -> 10
Nach deinem Code würde er an einer Sufe immer 2 Positionen zählen
Da vermute ich doch, daß deine mechanische "Einrastung" zu grob ist.
Ich gehe davon aus, daß bei einmal Rasten gelegentlich auch gleich
zwei optische Positionssprünge erfolgen.
Du hast in deinem Diagramm zwar gelegentlich beide Pegelwechsel
direkt übereinander gezeichnet, aber in Wirklichkeit sind die leicht
versetzt. Bei den Encodern gibt es zu einem Zeitpunkt nur einen
Pegelwechsel.
Wenn du (zeitlich) genauer hinschaust, wirst du das sehen (so
wie MaWin das gezeichnet hat)...
>Ich habe hier einen mechanischen Drehgeber aus einem Mausrad, den ich>gerne recyclen möchte.
nix optik, das ding ist rein mechanisch.
also dieses Signal bekomme ich recht eindeutig.
wenn es daran liegen würde müsste ich bei mehreren Versuchen
unterschiedliche Werte bekommen. Dem ist nicht so.
ich hab 12Mhz quarz und nen timerprescaler von 64. macht eine Samplerate
von 732, das ist nicht so viel, allerdings sind die Stufen so 5-7
Samples breit, also bin ich davon ausgegangen, das da auf der anderen
Seite wirklich nix ist.
Und da die Auswertung in der Selben ISR mit gleicher Frequenz wie vorher
das Logging gemacht wird, sollte es doch gehen, oder nicht?
Werd dann aber noch mal den anderen Timer frei machen und es mit nem
prescaler von 16 Probieren. Bei 8 läuft der Puffer über, da kommt das
SD-logging nicht hinterher
Aber danke erstmal
MfG,
Vlad
Du musst unbedingt jeden Pegelwechsel mitbekommen.
Mit einer festen Frequenz abfragen ist vielleicht suboptimal, weil
du viel Rechenzeit verbrätst und dann doch mal einen Wechsel
übersiehst.
Geschickter ist es, auf die beiden Pegel einen Interrupt anzusetzen
und das Zählen in der/n Interruptroutine(n) zu machen.
Klaus Wachtler schrieb:
> Du musst unbedingt jeden Pegelwechsel mitbekommen.> Mit einer festen Frequenz abfragen ist vielleicht suboptimal, weil> du viel Rechenzeit verbrätst und dann doch mal einen Wechsel> übersiehst.> Geschickter ist es, auf die beiden Pegel einen Interrupt anzusetzen> und das Zählen in der/n Interruptroutine(n) zu machen.
Ich wollts erst mal überhaupt hinbekommen.
Hab auch schon darüber nachgedacht, das an einen ext. INT zu hängen,
aber da gibt es dann das Problem der Synchronisation der routinen.
Außerdem wollt ich mir zumindest einen der Int-Pins möglichst frei
halten.
Mit der derzeitigen Abtastfrequenz könnt ich noch leben, wenn ich das
ding polle. würd dann die ISR noch optimieren und eventuell in asm
schreiben.
ich hab vor, das ding als eingabegerät zu benutze (menu-avigation,
eisntellung von werten). Ich will das so montiernen, dass man einen
drehknopf hat, den man dann noch drücken kann.
konnt solche Knöpfe nirgends finden (zumindest nicht zu vertretbaren
Preisen)
>die mechanischen sind soweit ich weiß alle meist nach dem greycode in>ihrer funktion>also so wie jeder belibige andere drehencoder auch
Hab sowas noch nie benutzt, bin mir auch nicht sicher, ob ich den
richtig angeschlossen habe. Hab leider das PCB nicht mehr um
rachzuschauen.
aussehen tut er in etwas so:
http://www.fdm-ware.de/powermate/pm3.jpg
Man kann auch mit einem externen Int. auskommen und dementsprechend
nur eine ISR nehmen, wenn man die beiden Signalketten an beliebige
Pins hängt, und an Int0 oder Int1 einfach das XOR der beiden
Signale.
Den Interrupt aktiviert man nun für sowohl steigende als auch fallende
Flanke (geht bei neueren AVR wie Mega8, nicht bei den alten wie
At90S2313). Die ISR wird dann bei jedem Wechsel eines der beiden
Signale aktiviert, liest die beiden eigentlichen Signale und zählt
entsprechend.
Encoder zur Eingabe mit Drehknöpfen gibt es abgesehen davon auch
fertig zu kaufen, inkl. Drucktaster...
>Encoder zur Eingabe mit Drehknöpfen gibt es abgesehen davon auch>fertig zu kaufen, inkl. Drucktaster...
nenn mir mal ein paar quellen
Ich hab keine gefunden (reichelt, Conrad, Pollin, westfalia).
Ich hätt halt schon gern was mechanisches, da die optischen ja selbst
auch wieder strom verbrauchen.
"Drehimpulsgeber" bei Reichelt, 15 Treffer. Grob die Haelfte davon sind
welche, der Rest Knoepfe und Zubehoer.
Btw: Versuch bei deinem Drehgeber mal andere Beschaltungsvarianten zu
messen und zeig mal die Impulsdiagramme davon. Vieleicht ist er doch nur
falsch angeschlossen.
@ Klaus Wachtler (mfgkw)
>Man kann auch mit einem externen Int. auskommen und dementsprechend>nur eine ISR nehmen, wenn man die beiden Signalketten an beliebige>Pins hängt, und an Int0 oder Int1 einfach das XOR der beiden>Signale.>Den Interrupt aktiviert man nun für sowohl steigende als auch fallende>Flanke (geht bei neueren AVR wie Mega8, nicht bei den alten wie>At90S2313). Die ISR wird dann bei jedem Wechsel eines der beiden>Signale aktiviert, liest die beiden eigentlichen Signale und zählt>entsprechend.
Genau DAS macht man NICHT! Warum? Siehe Drehgeber
MFG
Falk
> Suche mal 'Drehimpulsgeber', 'Encoder', 'inkremental Drehgeber'.
ja die Begriffe haben mir gefehlt, weswegen ich direkt über die
Kategorien gesucht hatte
ich hab natürlich nicht unter "Potis und Trimmer" gesucht. sondern
"drehschalter"
http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=B29;GROUPID=3714;ARTICLE=73923;START=0;SORT=user;OFFSET=100;SID=153g2D5qwQAQ8AABqIRkM18664388e8b35288c4e28f4574133fe0
sieht ganz gut aus.
Danke!
>Btw: Versuch bei deinem Drehgeber mal andere Beschaltungsvarianten zu>messen und zeig mal die Impulsdiagramme davon. Vieleicht ist er doch nur>falsch angeschlossen.
Ich hab jetzt mal alle drei Kombinationen durchprobiert. und Tatsächlihc
in einer (natürlich der letzt gewählten) gibt er folgendes aus
(Drehrichtung rechts)
11 -> 10 -> 00
oder
00 -> 01 -> 11
für links halt jeweils umgedreht.
mein Code gibt trotzdem nur rechts aus:
1
ISR(TIMER0_OVF_vect)
2
{
3
staticuint8old=3;
4
uint8newVal=(PIND>>2)&3;
5
if(s_wheel==Wheel_none){
6
if(((old==0)&&(newVal==1))
7
||((old==3)&&(newVal==2))
8
){
9
s_wheel=Wheel_right;
10
}elseif(((old==0)&&(newVal==2))
11
||((old==3)&&(newVal==1))
12
){
13
s_wheel=Wheel_left;
14
}
15
old=newVal;
16
}
17
}
Überlegung im Code war halt, das jede der Flanken eindeutig ist und ich
nur die erste auswerten muss.
Würd ich beide auswerten, würde ich mit drehen um reine Rastung ja immer
zwei impulse kriegen (falls das Hauptprogramm schnell genug die Variable
zurücksetzt).
> Also das Diagramm war richtig:
In dem Sinne, daß sich an einer Stelle beide Signale gleichzeitig (na
gut, gleichzeitig gibt es nie, nur mal der eine kurz vor dem anderen,
und mal der andere kurz vor dem einen) ändern ?
Dann ist dein Drehgeber kaputt.
> Überlegung im Code war halt,> das jede der Flanken eindeutig ist> und ich nur die erste auswerten muss.
Und was lernst du jetzt daraus,
daß dein Programm nicht richtig zählt?
Genau, deine Überlegung war halt einfach falsch.
Ahhhhh
kopf gegen Wand schlag
meine ISR ist richig und funktioniert super!
ich hab im hauptprogramm die Variable vor der Auswertung auf Wheel_none
gesetzt.
1
if(s_wheel!=Wheel_none)
2
{
3
// s_wheel = Wheel_none; <- hab ich dämlicherweise hier gemacht
Falk Brunner schrieb:
> @ Klaus Wachtler (mfgkw)>>>Man kann auch mit einem externen Int. auskommen und dementsprechend>>nur eine ISR nehmen, wenn man die beiden Signalketten an beliebige>>Pins hängt, und an Int0 oder Int1 einfach das XOR der beiden>>Signale.>>Den Interrupt aktiviert man nun für sowohl steigende als auch fallende>>Flanke (geht bei neueren AVR wie Mega8, nicht bei den alten wie>>At90S2313). Die ISR wird dann bei jedem Wechsel eines der beiden>>Signale aktiviert, liest die beiden eigentlichen Signale und zählt>>entsprechend.>> Genau DAS macht man NICHT! Warum? Siehe Drehgeber>> MFG> Falk
Wenn man entprellen will/muß, darf man das nicht machen; eingesehen.
Bisher hatte ich einmal einen einfachen Drehgeber zur Menüsteuerung
in der Hand, da ging es gut ohne (vielleicht weil man nicht viel
dreht?). Bei den "echten" teuren Drehgebern mit optischer Abtastung
und eigener Logik war dagegen das Signal bisher immer so sauber,
daß es kein Gezappel gab.
Insofern würde ich es nicht so pauschal sagen, wie man es IMMER
oder NIE macht.
Daß es im Einzelfall falsch sein kann, glaube ich dir dagegen
durchaus.