www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Rotary Encoder entprellen


Autor: MyCo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe ein Problem beim Entprellen von Drehgebern (Bourns Rotary
Encoder mit graycode). Ich bastel gerade an 2 Projekten damit. Bei dem
einen will ich das eine Taktsignal an den Interrupt1 und das andere
Taktsignal an PD4  eines Atmega8 hängen. Der Bascom-Quelltext, den ich
bisher habe ist im Anhang.

Das ist bisher nur zum Testen. Leider zählt die Variable c völlig
wahllos. Wenn ich in eine Richtung drehe, zählt er mal rauf und mal
runter, ausserdem sind die Sprünge zwischen den Werten auch bei einem
einzelnen Klick unterschiedlich gross. Die Drehgeschwindigkeit ist da
auch völlig egal. Ich brauche allerdings die Abfrage per Interrupt, da
das Hauptprogramm sehr zeitintensiv wird. Es wird daher auch per
Assembler geschrieben sein.
Ich habe auch schon versucht, den Interrupt einfach abzuschalten, damit
er nicht mehrfach aufgerufen wird. Nur irgendwie scheint der AVR die
zwischenzeitlichen Interrupt-Aufrufe zu speichern, um sie später
nachzuholen.

Ich hoffe ihr könnt mir helfen, da ich mich jetzt schon ein paar
Stunden damit herumgequält habe und nun nicht mehr weiter weiss.

Danke!
Maik

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du mußt den Zustand eines Drehgeber-Pins in einer Variablen "merken"
und vor der Auswertung auf Veränderung prüfen, z. B. Kanal A.
Erst wenn sich Kanal A verändert hat hat der Nutzer den Drehgeber
betätigt und darauf hin dann die Auswertung "IF PinD.3=0 then" etc.

Noch mal der Ablauf:
 If Gemerkt <> PinD.3 dann
   If PinD.3 = PinD.4 dann
     .....
   else
     .....
   EndIf
   Gemerkt = PinD.3
 EndIf

MfG
Andi

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für eine zuverlässige Auswertung muss sich das Programm die Zustände
beider Ausgänge merken, dann kann man sich das Entprellen auch i.d.R.
sparen.

http://www.mikrocontroller.net/forum/read-4-37992.html#87902

Autor: MyCo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja... wenn ich das so machen würde, könnte ich mein Projekt gleich
abhaken. Bei der ersten Lösung würde ich 10-20 Zyklen alleine im
Hauptprogramm mehr haben, und bei der 2. wären diese 10-20 Zyklen
regelmässig beim Timeraufruf.
Bei mechanischen Drehgebern muss man nicht alle 4 Stadien der Ausgänge
auswerten. Da der Regler ja selbst rastet, würde man so eh pro Klick um
2 werte nach oben zählen.

@Andi: Die Lösung funktioniert wenn überhaupt, nur mit einem bereits
hardwaremässig-entprellten Drehgeber.

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir ging es ganz einfach:
Pullups des uC aktivieren, 10nF nach Masse zur Entprellung und ein
Ausgang des Inkrementgebers an einen Interrupt. In der Interruptroutine
wird der Zustand des zweiten Pins abgefragt: Ist der High wurde vorwärts
gedreht, ist es Low wurde rückwärts gedreht.
Fragt micht nicht wiso das so ist, ich weiß nur dass es einwandfrei bei
mir läuft.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@MyCo

"Naja... wenn ich das so machen würde, könnte ich mein Projekt gleich
abhaken. Bei der ersten Lösung würde ich 10-20 Zyklen alleine im
Hauptprogramm mehr haben, und bei der 2. wären diese 10-20 Zyklen
regelmässig beim Timeraufruf."


Das must Du aber schon näher erläutern !

20 Zyklen in einem Timer z.B. alle 200µs (5kHz) sind bei 8MHz
20/1600=1,25% CPU-Last.

Du must also die Quarzfrequenz nur um 1,25% erhöhen und Du hast genau
die gleiche Leistung wie ohne Drehgeber auslesen.

Ich kenne jedenfalls keine Anwendung, die bei 1,25% CPU-Last schon in
die Knie geht.


Peter

Autor: MyCo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will den Atmega als "stellbaren" Taktgeber einsetzen, mit
Frequenzen zwischen 2MHz und 50Hz, wobei Low- und High-Zeit getrennt
geregellt werden kann. Das wichtige dabei ist, dass wenn die Frequenz
einmal gestellt ist, der Taktgeber 100% genau laufen soll. Ein
Timer-Interrupt der immer mal das Hauptprogramm unterbricht würde so
zB. das ganze Prinzip kaputt machen.

Der µC läuft schon mit einem 16MHz Quarz, ein Erhöhung der Taktrate
bringt dann nur noch mehr Fehler.

Autor: ...HanneS... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2MHz??

Hut ab, das ist ein hohes Ziel!
Und denn noch 100% genau...
Da wird ein AVR arg zu knabbern haben, selbst bei Verwendung der
Hardware-PWM.

...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Ich will den Atmega als "stellbaren" Taktgeber einsetzen, mit
Frequenzen zwischen 2MHz und 50Hz, wobei Low- und High-Zeit getrennt
geregellt werden kann."


Und warum nimmst Du nicht die PWM (Mode 14 oder 15) ?

Die macht das doch voll in Hardware, da stört ein Interrupt überhaupt
nicht.

Und unter 245Hz nimmst Du eben die Pin-Set und Clear-Funktion des
Timers.


Peter

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es zwingt dich doch niemand dazu die Auswertung im Timerinterrupt zu
machen, das geht genau so gut in der Hauptschleife.

Autor: MyCo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe bisher pwm noch nicht dazu bekommen, das zu tun was ich will...
die Dokumentation in Bascom bringt einem nicht weiter, und mit ASM bin
ich auch noch nicht so weit...

Software-mässig bekomme ich mit meinem ASM-Code bisher etwa 1,5MHz
konstant

Aber es geht mir auch darum, einen Drehgeber abzufragen, ohne dafür die
Pins abzufragen. Es soll also nur der Drehgeber abgefragt werden, wenn
bereits feststeht, dass er bewegt wurde.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Ich habe bisher pwm noch nicht dazu bekommen, das zu tun was ich
will... die Dokumentation in Bascom bringt einem nicht weiter"

Die Doku im Datenblatt aber schon.

Es schad nix, wenn man sich mal mit den internen Registern und
Funktionen der CPU beschäftigt und sich nicht blindlings auf die
vorgefertigten Black-Boxes in Bascom verläßt.
Ich finds sogar interessanter, wenn man weiß, wie etwas funktioniert.



"Software-mässig bekomme ich mit meinem ASM-Code bisher etwa 1,5MHz
konstant"

Wie machst Du denn da die Einstellung des Tastverhältnisses ?



"Es soll also nur der Drehgeber abgefragt werden, wenn
bereits feststeht, dass er bewegt wurde."

Ginge im Prinzip auch (beide Pins auf beide Interrupts und dann bei
beiden Flanken auslösen). Beide Interrupthandler rufen dann die Routine
auf.

Trotzdem wirst Du dann aber ohne die PWM Signalstörungen haben, auch
wenns nur beim Drehen ist.


Peter

Autor: MyCo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Hauptteil des Taktgebers ist:

   mainloop:
     cbi $15,0
     movw Temp,LTimeH
      dlya:
         sbiw Temp,1
         brne  dlya

      sbi $15,0
      movw Temp,HTimeH


      dlyb:
         sbiw Temp,1
         brne  dlyb

   rjmp mainloop


Im Interrupt soll dann per Drehgeber LTimeH, LTimeL, HTimeH und HTimeL
gesetzt, und der Hauptteil macht dann automatisch den Rest.

Wie gesagt, die PWM-Beschreibung ist mir im Moment zu schwer zu
verstehen, da ich ASM noch nicht so gut kann. Den Hauptteil habe ich
gerade so zusammenbekommen. Vielleicht kann mir jemand eine PWM-Version
geben, die ähnliches erzielt, wie mein Hauptteil. Aus Quelltext kann ich
besser lernen, als aus trockenen Dokumentationen.

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
Also sowas sollten unbedingt der/die Timer selber machen.
Beschäftige dich mal mit Output Compare A+B. Du wirst sehen dein
Zeitproblem löst sich in Luft auf. Mal so als Tip OC1A macht Low-Teil,
OC1B macht High-Teil deiner Freq. Aber um's Datenblatt kommst du nicht
herum.

MFG Uwe

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.