Forum: Mikrocontroller und Digitale Elektronik Drehencoder mit AVR will nicht so wie ich gern will


von Michael D. (etzen_michi)


Lesenswert?

Guten Tag.

Ich habe das Problem das ich mir ein Programm geschrieben habe, welches 
je nachdem ob ein Drehencoder Rechts oder Links herum gedreht wird 
entweder LED1 oder LED2 aufleuchten läßt (einen kurzen Impuls ausgibt).
1
.include "tn2313def.inc"
2
3
    ldi r16, 0b00000011
4
    out DDRD, r16      ; PD0+1 Sind Ausgänge
5
    ldi r16, 0x00
6
    out PORTD, r16
7
    out DDRB, r16      ; PB 0+1 Sind Eingänge
8
    ldi r16, 0b00000011
9
    out PORTB, r16      ; Eingänge haben einen Pull-Up Widerstand geschaltet
10
11
Loop:
12
13
    sbis PINB, 0
14
    rcall PINBR        ; Wenn Eingang PB0 auf Low zu Unterprogramm springen
15
    sbis PINB, 1
16
    rcall PINBL        ; Wenn Eingang PB1 auf Low zu Unterprogramm springen
17
    rjmp Loop
18
19
PINBR:
20
21
    ldi r16, 0x01
22
    out PORTD, r16      ; LED an PD0 einschalten
23
    ldi r16, 0xFF
24
    rcall Warte        ; Warteschleife
25
    ldi r16, 0x00
26
    out PORTD, r16      ; LED an PD0 abschalten
27
    rjmp PINB0_        ; In Unterprogramm springen
28
29
PINB0_:
30
31
    sbis PINB, 0
32
    rjmp PINB0_
33
    sbis PINB, 1
34
    rjmp PINB0_
35
    ret            ; Soblad beide Eingänge wieder Low zurück ins Programm
36
37
PINBL:
38
39
    ldi r16, 0x02
40
    out PORTD, r16
41
    ldi r16, 0xFF
42
    rcall Warte
43
    ldi r16, 0x00
44
    out PORTD, r16
45
    rjmp PINB1_
46
47
PINB1_:
48
49
    sbis PINB, 1
50
    rjmp PINB1_
51
    sbis PINB, 0
52
    rjmp PINB1_
53
    ret
54
55
Warte:
56
57
    dec r16
58
    brne warte
59
    ret

Irgendwie ist das Problem das teilweise die falsche LED angesteuert 
wird, desto schneller ich drehe desto öfter, aber teilweise auch bei 
gaanz langsamen drehen. Wenn ich die Tacktfrequenz erhöhe kommt dieser 
Fehler seltener vor.
An Aussenbeschaltung habe ich nur die LED`s mit vorwiderstand sowie den 
Drehencoder welcher auf Masse zieht.

von Thomas G. (mrmp3)


Lesenswert?

Hier erstmal nen Link, ist eigentlich ganz cool erklärt.
http://www.mikrocontroller.net/articles/Drehgeber

Leider hab ich von Assembler nicht so viel Ahnung. Aber Ich sehe das du 
nicht mit Timern arbeitest, ist aber bei Drehimpulsgebern von Vorteil.

Ich kenne 2 Möglichkeiten:

1. Einen der Beiden Pins (A oder B) an einen Interrupt Eingang und bei 
steigender oder fallender Flanke in die Rountine rein und testen ob sich 
der andere Pin auch geändert hat oder noch bleibt. So kannst du 
ermitteln welche Richtung gedreht wurde, das hat aber den nachteil das 
du nur die halbe Auflösung hast.

2. Per Timer in festen Abständen die Zustände von A und B auslesen und 
so entscheiden ob gedreht wurde, und wenn ja in welche Richtung.




Ein Drehimpulsgeber prellt genau so wie ein normaler Taster ich vermute 
das dein Programm das nicht berücksichtigt und aufgrund des Prellens 
irgendwelche entscheidungen trifft. wie lange wartest du bist zum 
nächsten abfragen ?

von Michael D. (etzen_michi)


Lesenswert?

Eigentlich haut er die Befehle mit 8MHz durch.

Entprellen habe ich mit n kleinen Kerko .. habe aber die Widerstände 
vergessen ^^

Edit:

Widerstände haben keine Besserung gebracht.

Zum Link:
Ich kann kein C :(

von Hannes L. (hannes)


Lesenswert?


von Thomas G. (mrmp3)


Lesenswert?

Hast du dein Problem gelöst ?

Also rein aus nem Gefühl herraus würd ich sagen das der Tiefpass nicht 
ausreicht um den Geber zu entprellen.

Die Lösung deines Problems liegt wahrscheinlich darin das du nicht mit 
8Mhz abtasten solltest weil du dann jedes Prellen mit analysierst 
sondern z.B. aller 1ms und dann solltest du schnelle Pegelwechsel in 
deiner Software ausschließen.

Hab den Link von Hannes nicht eingesehen, vllt. steht da ja das selbe 
^^.

von Hannes L. (hannes)


Lesenswert?

Thomas G. schrieb:
> Hast du dein Problem gelöst ?
>
> Also rein aus nem Gefühl herraus würd ich sagen das der Tiefpass nicht
> ausreicht um den Geber zu entprellen.

Der Tiefpass ist gar nicht nötig, wenn der Drehgeber per MC ausgewertet 
wird.

>
> Die Lösung deines Problems liegt wahrscheinlich darin das du nicht mit
> 8Mhz abtasten solltest weil du dann jedes Prellen mit analysierst
> sondern z.B. aller 1ms und dann solltest du schnelle Pegelwechsel in
> deiner Software ausschließen.

Richtig, alle etwa 1 ms den aktuellen Zustand beider Pins mit dem 
vorherigen (gemerkten) Zustand vergleichen.

>
> Hab den Link von Hannes nicht eingesehen, vllt. steht da ja das selbe
> ^^.

Schade eigentlich. Aber der Frager hat den Link vermutlich auch nicht 
verfolgt, sonst hätte er ja weitere Fragen dazu gestellt. Vermutlich 
fehlt die Zeit, denn jetzt ist ja erstmal Tastenentprellung dran:
Beitrag "Taster Softwaretechnisch entprellen"

...

von Thomas G. (mrmp3)


Lesenswert?

Da hast du recht wenn die Entprellen per µC erfolgt ist der Tiefpass 
sinnlos aber selbst wenn er die Entprellung mit dem Tiefpass machen 
wöllt würde das nicht funktionieren denk ich weil die Zeiten einfach zu 
kurz sind. Oder irre ich mich da ???

Ich hab mich mit dem Link den ich gepostet hab beschäftigt der ist in C 
das versteh ich besser ^^.

Entprellen eines Tasters steht im Tutorial sogar in Assembler !
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

von Michael D. (etzen_michi)


Lesenswert?

Info: Ich lese hier noch ^^.

von Hannes L. (hannes)


Lesenswert?

Thomas G. schrieb:
> Da hast du recht wenn die Entprellen per µC erfolgt ist der Tiefpass
> sinnlos aber selbst wenn er die Entprellung mit dem Tiefpass machen
> wöllt würde das nicht funktionieren denk ich weil die Zeiten einfach zu
> kurz sind. Oder irre ich mich da ???

Ich habe die Zeiten nicht überprüft, weil ich diesen Ansatz für eine 
Sackgasse halte. Denn ein MC, der Drehgeber auslesen soll, soll gewiss 
noch etwas Anderes tun als nur Drehgeber auszulesen. Daher hat er keine 
Zeit, Wartezeiten durch Vertrödeln von CPU-Takten zu generieren. Es muss 
also ein Timer her, der Drehgeber-Auslesen, Tastenentprellung und ggf. 
auch noch den Sekundentakt generiert, ohne der CPU Rechenzeit durch 
Zählen von Takten zu stehlen.

>
> Ich hab mich mit dem Link den ich gepostet hab beschäftigt der ist in C
> das versteh ich besser ^^.

Ist bei mir umgedreht, ich verstehe ASM besser als C. Der AVR übrigens 
auch (in Form von MC)... ;-)
Und weil der Frager kein C kann, habe ich (m)eine ASM-Routine verlinkt, 
die von anderen Leuten auf C und Bascom umgeschrieben wurde.

>
> Entprellen eines Tasters steht im Tutorial sogar in Assembler !
> http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

Ja sicher, ich benutze (und verstehe) Peter Danneggers Entprellroutine 
aber schon etwas länger als sie im Tutorial steht. Und ich passe sie 
auch an wechselnde Aufgaben an. Ich kann aber auch verstehen, wenn ein 
Anfänger diese Routine meidet, weil er sie nicht versteht. Die Routine 
ist hochoptimiert und für den Laien nicht leicht zu verstehen. Dafür 
braucht sie extrem wenig Ressourcen (Code, Rechenzeit) und kommt auch 
mit den labrigsten Tasten zurecht.

...

von Hannes L. (hannes)


Lesenswert?

Michael Dierken schrieb:
> Info: Ich lese hier noch ^^.

Prima...
Nachdem Deine Tasten ja nun sauber entprellt werden, kannst Du Dich ja 
wieder dem Drehgeber widmen.

Ein Beispiel, das Drehgeber und Tasten einliest findest Du z.B. hier:
http://www.mikrocontroller.net/attachment/43903/sinus.zip

Viel Erfolg...

...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.