Hallo,
ich hab mal versucht, einen Drehgeber (Handbetrieben) auszuwerten.
Und zwar sollte die Drehbewegung in je ein Impuls pro Rastung
ausgegegebn werden, getrennt für rechts und links.
Ich verwende einen ATtiny26 mit 1MHz interner Taktung.
Den Drehgeber habe ich an PB6 und PB5 angeschlossen.
2 LEDs sind an PA0 und PA1 angeschlossen.
PB6 ist als externer Interrupt eingestellt auf "Pin Change".
Hier der code:
1
;#################################
2
;# Project: Drehgeber auswerten mit Interrupt
3
;# Date: 20.3.07
4
;# Version: 0.1
5
;# Controller: ATtiny26
6
;# Frequency: 1Mhz intern
7
;#################################
8
.include "tn26def.inc"
9
10
rjmp main ;Power-on-reset
11
rjmp subroutine ;external interrupt
12
reti
13
reti
14
reti
15
reti
16
reti
17
reti
18
reti
19
reti
20
reti
21
reti
22
23
;#################################
24
;# main
25
;#################################
26
27
main: ldi r16,low(ramend)
28
out SP,r16
29
30
clr r16
31
out DDRB,r16
32
ser r16
33
out PORTB,r16
34
out DDRA,r16
35
36
ldi r16,0b01000000
37
out GIMSK,r16 ;external interrupt on
38
ldi r16,0b00000001
39
out MCUCR,r16 ;ext. int at "any change"
40
sei ;global interrupt enable
41
42
; Mainloop
43
loop: rjmp loop
44
45
; Interrupt program
46
subroutine:
47
in r16,PINB
48
mov r17,r16
49
ror r17
50
andi r16,0b01000000
51
andi r17,0b01000000
52
cp r16,r17
53
brne rechts
54
sbi PORTA,1
55
rcall wait
56
cbi PORTA,1
57
reti
58
rechts: sbi PORTA,0
59
rcall wait
60
cbi PORTA,0
61
reti
62
63
; Warteschleife
64
wait: ser r20
65
wait0: dec r20
66
brne wait0
67
ret
Das Ergebnis: Es werden abwechselnd PA0 und PA1 angesteuert, egal wie
rum ich den Drehgeber drehe. Mnachmal werden beide gleichzeitig
angesteuert.
Meine Frage ist nun: Findet jemand spontan einen Fehler?
Fehlt nur eine entprellung, oder kleine warteschleifen?
Ich bin ratlos.
Mfg
Sebastian Engel
s werden abwechselnd PA0 und PA1 angesteuert, egal wie
rum ich den Drehgeber drehe. Mnachmal werden beide gleichzeitig
angesteuert...
Aber du weißt wie ein Drehgeber funktioniert?
@Sebastian Engel
>ich hab mal versucht, einen Drehgeber (Handbetrieben) auszuwerten.
Alle Jahre wieder, komt nciht nur das Christuskind, sondern auch das
Thema Drehgeber.
Guggst du hier.
Beitrag "Drehgeber auslesen"http://www.mikrocontroller.net/articles/Drehimpulsgeber>PB6 ist als externer Interrupt eingestellt auf "Pin Change".
Was schonmal kein guter Ansatz ist. Auswertung per Flankeninterrupt ist
schlecht, periodische Abtastung per Timerinterrupt ist das Mittel der
Wahl.
MfG
Falk
@Dirk
>>Auswertung per Flankeninterrupt ist>>schlecht, periodische Abtastung per Timerinterrupt ist das Mittel der>>Wahl.>Warum nicht mit Interrupt ?
Das ist lang und breit und hundertmal im angegebenen Link erklärt.
MfG
Falk
Erstmal:
Ja, mir ist bekannt was ein Drehgeber ist. Das Datenblatt habe ich
ausführlich durchgeforstet
Zu den Links:
Ich habe hier schon fast alle Drehgeber Threads durchgestöbert,
aber ich dachte mir probierstes mal selber.
Zum interrupt:
So eine Lösung würde im Datenblatt vorgeschlagen.
Also ganz simpel:
positive Flanke triggert -> pin A & B vergleichen -> Wenn gleich
"rechts" / Wenn ungleich "links" -> trigger auf fallende flanke stellen
-> anfang ->
Ich dachte das hätte ich richtig in der Software umgesetzt.
Sonst muss ich halt nochmal die alten Threads durchstöbern.
Danke für die flotten antworten
Mfg
S. Engel
Hast du vielleicht richtig programmiert, doch das Prellen wird das
Genick brechen... Ohne "schlauere" Routinen geht es vielleicht bei
optischen Gebern, aber bei mechanischen wird es zum Glückspiel.
@Sebastian Engel
>Ich habe hier schon fast alle Drehgeber Threads durchgestöbert,>aber ich dachte mir probierstes mal selber.
Prinipiell OK, aber leider machen dabei die meisten Leute genau den
Fehler, den hunderttausende vor ihnen schon gemacht haben.
>Zum interrupt:>So eine Lösung würde im Datenblatt vorgeschlagen.>Also ganz simpel:>positive Flanke triggert -> pin A & B vergleichen -> Wenn gleich>"rechts" / Wenn ungleich "links" -> trigger auf fallende flanke stellen>-> anfang ->
Daran sieht man, dass auch Datenblätter manchmal Müll enthalten.
>Ich dachte das hätte ich richtig in der Software umgesetzt.
Kann sein, sit aber dennoch falsch, weil es nur zu 90% sauber läuft.
>Sonst muss ich halt nochmal die alten Threads durchstöbern.
Das musst du. Kleiner Tip. Stell dir mal vor, der Drehgeber kommt genau
auf einer Flanke zum Stehen und schwingt dann lustig vor und zurück (das
ist ein realer Fall!).
Was passiert mit deinem Controller, wenn er auf steigende/fallende
Flanke triggert?
Was passiert mit dem Controller, wenn er nur alle 10ms abtastet?
@Thomas
>Genick brechen... Ohne "schlauere" Routinen geht es vielleicht bei>optischen Gebern, aber bei mechanischen wird es zum Glückspiel.
Auch bei optischen ist es das gleiche Problem.
MFG
Falk
@Sebastian
Laß dir keinen Müll erzählen, auch im flankengesteurten Interrupt kann
man erfolgreich Drehgeber auswerten/abfragen. Hab bei mir zu Hause auch
zwei Teile im Einsatz, die seit zehn Jahren funktionieren. Damals war
mir Peters Timerroutine noch gar nicht bekannt, und ob es dieses Forum
hier schon gab, kann nicht sagen.
@Gugge 73
>Laß dir keinen Müll erzählen, auch im flankengesteurten Interrupt kann>man erfolgreich Drehgeber auswerten/abfragen. Hab bei mir zu Hause auch
Man kann auch 20 Jahre ohne Sturzhelm Moped fahren und es passiert nix.
>zwei Teile im Einsatz, die seit zehn Jahren funktionieren. Damals war>mir Peters Timerroutine noch gar nicht bekannt, und ob es dieses Forum>hier schon gab, kann nicht sagen.
Der Aufstieg und Fall der Elektronikbranche wird wohl kaum an dieser
Webseite hängen ;-)
Und auch wenn es Peters Routine noch nciht gab, so gab es schon Leute
die wussten wie man Drehgeber richtig auswertet. Aber bestimmte Mythen
sind eben sehr zäh.
MFG
Falk
P.S. Stell dir bitte auch mal die Fragen aus meinem vorherigen Posting.
Was passiert mit dem Controller? Die Antwort ist auch im verlinkten
Thread zu finden.
rol r17 ;<---- ror durch rol ersetzt, der eigendliche Fehler
51
andi r16,0b01000000
52
andi r17,0b01000000
53
cp r16,r17
54
brne rechts
55
sbi PORTA,1
56
rcall wait
57
cbi PORTA,1
58
reti
59
rechts: sbi PORTA,0
60
rcall wait
61
cbi PORTA,0
62
reti
63
64
; Warteschleife
65
wait: ser r20
66
wait0: dec r20
67
brne wait0
68
ret
Hab nur die beiden oben genannten dinge geändert, und schon läufts.
Funktioniert zu 98,7% :-)
Ab und zu kommt ein "Fehlimpuls".
Zum testen habe ich anstatt 2 pins zu toggeln, einfach an Port A durch
LEDs ein Register ausgegeben, welches man durch drehen +1 / -1
durchzählen kann.
>>Funktioniert zu 98,7% :-) Ab und zu kommt ein "Fehlimpuls".
Mach mal je 33nF Keramikkondensatoren von jedem der beiden Drehgeberpins
nach Masse. Das schluckt einen Großteil der Prellimpulse, flacht aber
die Flanken ab. Es könnte die Fehler aber auf nahezu 0 reduzieren. Trotz
aller Deiner Argumente würde ich aber nie einen Interrupt an einem
externen Schaltelement anbinden. Das sorgt im Zweifelsfalle (schnelle
Betätigungen) für Instabilität im Programm.