mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mausrad Drehgeber


Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
/*
  Note:
   _      _____
  | |    |     |  > rechts
  | |=   |  O  |
  |_|    |_____|  > links
  |      |  |  |
  |      |  |  |
         0  G  1


  (rechts rum: 11 -> 10   ->   00 -> 11)
  (links  rum: 11 -> 00   ->   10 -> 11)

       turn right  turn right     turn left   turn left
           |  |     |  |            |  |        |  | 
    _______           _______________              _______
  0        |_________|               |____________|
    _________         _______________            __________
  1          |_______|               |__________|


-->

   \n| 0  0  1  1
   o\| 0  1  1  0
  ---+------------
  00 | x  l  r  
  01 |           
  11 | l  r  x   
  10 |
 */
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:
typedef enum Wheel
{
  Wheel_none,
  Wheel_left,
  Wheel_right
}Wheel;

static volatile Wheel s_wheel;

ISR(TIMER0_OVF_vect)
{
  static uint8 old=3;
  if( s_wheel == Wheel_none ){
    uint8 newVal = (PIND>>2)&3;
    if(    ((old == 0)  && (newVal == 2))
        || ((old == 3)  && (newVal == 0))
       ){
       s_wheel = Wheel_left;
    }else if(     ((old == 0)  && (newVal == 3))
               || ((old == 3)  && (newVal == 2)) 
             ){
       s_wheel = Wheel_right;
    }
    old = newVal;
  }


}



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

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus irgendeinem grund evrstehe ich deine durchaus sehr ausführliche 
Beschreibung nicht, vielleicht liegt's daran.

       turn right  turn right     turn left   turn left
           |  |     |  |            |  |        |  |
    ______         ___________________            ______
  0        |_______|                   |__________|
    _________         _____________            _________
  1           |_______|             |__________|

   \n| 0  0  1  1
   o\| 0  1  1  0
  ---+------------
  00 | 0  l  X  r
  01 | r  0  l  X
  11 | X  r  0  l
  10 | l  X  r  0


 ISR(TIMER0_OVF_vect)
{
    static uint8 old=3;
    uint8 newVal = (PIND>>2)&3;
    if(((old == 0)  && (newVal == 1))
    || ((old == 1)  && (newVal == 3))
    || ((old == 3)  && (newVal == 2))
    || ((old == 2)  && (newVal == 0)))
    {
       pos++;
    }
    else if(((old == 0)  && (newVal == 2))
         || ((old == 1)  && (newVal == 0))
         || ((old == 3)  && (newVal == 1))
         || ((old == 2)  && (newVal == 3)))
    {
       pos--;
    }
    else if(newVal != old) ; // Fehlerkondition

    old = newVal;
  }

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das Diagramm war richtig:
/*
       turn right  turn right     turn left   turn left
           |  |     |  |            |  |        |  | 
    _______           _______________              _______
  0        |_________|               |____________|
    _________         _______________            __________
  1          |_______|               |__________|

*/
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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)...

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die mechanischen sind soweit ich weiß alle meist nach dem greycode  in 
ihrer funktion
also so wie jeder belibige andere drehencoder auch

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"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.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>nenn mir mal ein paar quellen

reichelt, Conrad, Pollin

Suche mal 'Drehimpulsgeber', 'Encoder', 'inkremental Drehgeber'.

MfG Spess

Autor: Guido Körber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann nimm doch mal Elektronikhändler statt Resteverwerter: Segor, 
Farnell, RS...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
z.B. Reichelt:
http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=B29...
Knopf dafür: 
http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=B29...


oder "STEC12E08" mit Knopf "KNOPF 10-150E" oder "KNOPF 13-164E"

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  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

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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...

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:
ISR(TIMER0_OVF_vect)
{
  static uint8 old=3;
  uint8 newVal = (PIND>>2)&3;
  if( s_wheel == Wheel_none ){
    if(    ((old == 0)  && (newVal == 1))
        || ((old == 3)  && (newVal == 2))
       ){
       s_wheel = Wheel_right;
    }else if(     ((old == 0)  && (newVal == 2))
               || ((old == 3)  && (newVal == 1)) 
             ){
       s_wheel = Wheel_left;
    }
    old = newVal;
  }
}


Ü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).

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
    if(s_wheel != Wheel_none)
    {
      // s_wheel = Wheel_none; <- hab ich dämlicherweise hier gemacht
      if( s_wheel==Wheel_left ){
        --number;
      }else{
        ++number;             // und damit immer hochgezählt
      }
      s_wheel = Wheel_none;   // anstatt  hier
      lcd_init(LCD_DISP_ON);
      utoa(number, (char*)s_logBuf, 10); 
      lcd_puts((char*)s_logBuf);        
    }

Edit:

Noch mal danke an Alle!

Vor allem für die Hilfe bei der Suche nach kaufbaren encodern - Ich wär 
nie darauf gekommen, die dinger bei "Potis und Trimmer" zu suchen


Danke!
Vlad

Edit:
http://www.pollin.de/shop/shop.php?cf=detail.php&p...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

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.