- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 26

Thema: Menüsteuerung mit Drehencoder ?

  1. #11
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    20.02.2007
    Beiträge
    341
    Anzeige

    Powerstation Test
    Hi,

    Danke für die Hilfe, dass hört sich ja schonmal gut an

    Ich habe gerade noch ein Codebeispiel gefunden in dem ich etwas nicht verstehe und somit nochmal auf meine Frage im Edit zurück komme.

    Code:
    _encoder = Encoder(pinc.7 , Pinc.6 , Links , Rechts , 1) 
    .
    .
    .
    Rechts:
    While Auswahl < 5 And _encoder = 2
       Incr Auswahl
       _encoder = 3
       Waitms 50
    Wend
    Return
    Wozu dort das "And _encoder = 2" in der Sub ?

    mfg Yannic

  2. #12
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.01.2007
    Ort
    westliches Pannonien
    Beiträge
    123
    Hallo!

    Wenn Du ein LCD am µC hängen hast, lass Dir die Variable
    _encoder oder B oder wie auch immer anzeigen.
    Wenn Du den Encoder ganz langsam drehst, zeigt Dir das Display
    3 2 1 0 (sehr wahrscheinlich nicht in dieser Reihenfolge).
    Ist ganz einfach nur der Zustand der beiden Pins an denen der Encoder
    hängt.
    Wenn ich mich jetzt nicht ganz irre macht dieser Encoder zwei Schritte,
    dann folgt eine Rastung, wieder zwei Schritte, eine Rastung usw.

    Das alles brauchst Du jetzt nur mehr auswerten.
    Der Encoder Befehl verträgt allerdings keine schnellen Drehungen.

    MfG
    Rone

  3. #13
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    09.05.2007
    Beiträge
    202
    Hallo,

    ich habe auch so einen ähnlichen Encoder. Ich löse das über eine Bit-Variable:

    Code:
    Dim X As Byte
    Dim Encbit As Bit
    
    links:
    Toggle Encbit
       If Encbit = 1 Then
          decr X
       End If
    Return
    rechts:
    Toggle Encbit
       If Encbit = 1 Then
          incr X 
       End If
    Return
    Gruß, Stefan

  4. #14
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    20.02.2007
    Beiträge
    341
    Hi,

    wie ich rausgefunden habe geht es mit einem

    If B = 1 Or B = 2 Then in den Subs für Links und Rechts. Wieso das so ist kann ich zwar noch nicht ganz nachvollziehen, aber hausptsache ist ja das es so geht.

    Würde mich aber natürlich über eine Erklärung zum verständnis freuen

    mfg Yannic

  5. #15
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Die Encoder-Routine hat bei mir noch nie zufriedenstellend funktioniert.

    Ich nutze sehr zuverlässig folgendes:
    Code:
    Dim Drehung As Integer
    
    Dim Linksrechts As Byte
    Links Alias Pind.3
    Rechts Alias Pind.4
    
    
    do
       Gosub Rad  
    .
    .
    .
    .
    
    loop
    end
    
    Rad:
          If Linksrechts = 0 Then
             If Links = 0 And Rechts = 1 Then
                Linksrechts = 1
             End If
             If Rechts = 0 And Links = 1 Then
                Linksrechts = 11
             End If
          End If
          If Linksrechts = 1 And Links = 0 And Rechts = 0 Then  
             Linksrechts = 0
             Drehung = 0 - 1
          End If
    
    
    
          If Linksrechts = 11 And Links = 0 And Rechts = 0 Then 
             Linksrechts = 0
             Drehung = 1
          End If
    
          If Links = 1 And Rechts = 1 Then Linksrechts = 0
    
    
    
    Return
    Der Encoder zieht die PINS auf GND. bei links und rechts werden die pullups aktiviert.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  6. #16
    Benutzer Stammmitglied
    Registriert seit
    12.12.2004
    Ort
    Trier
    Beiträge
    38
    Ich habe auch bei einem Bastelprojekt mal einen (Billig-)Encoder von Pollin eingesetzt. Mittlerweile benutze ich wieder Tasten.

    Zur Erklärung:
    Die Encoder haben zwei Signalausgänge, namentlich A und B. Durch drehen ergibt sich folgender Signalwechsel (siehe auch Datenblatt zu deinem Encoder)

    Rechtsrum: (A,B)= (1,1)-(0,1)-(0,0)-(1,0) usw.
    Linksrum: (A,B)= (1,1)-(1,0)-(0,0)-(0,1) usw.

    Dein Modell durchläuft auch alle diese Signalzustände, rastet jedoch nur in den Zuständen A=B, also (0,0) und (1,1) ein.
    Es gibt aber auch Encodermodelle, die bei allen vier möglichen Zuständen einrasten, und dafür wurde die Encoder-Funktion von Bascom auch geschrieben.

    Ich habe auch mit der Encoderfunktion ein bischen rumgespielt bin aber dann bei einer selbstgeschriebenen Funktion gelandet. Obwohl die auf der Benutzung von externen Interrupts basiert (was zwar von den Profis zu Recht verpöhnt wird) fahre ich damit eigentlich ganz gut. Ich mußte jedoch die Kontakte durch RC-Glieder entprellen.

    Das ganze sieht dann etwa so aus:


    Code:
    Config Int2 = Falling 'Ph_a an ext. Int2
    On Int2 Isr_int2
    Enable Int2
    Enable interrupts
    
    Dim Rotary as byte  'Bit0= Ph_a, Bit1= Ph_b
    Dim Enc_down as bit 'Flag Runterzählen
    Dim Enc_up as bit  'Flag Hochzählen
    Dim Encoderstand as byte
    
    'Hauptprogramm
    Do
    If Enc_down=1 then
       reset Enc_down
       if Encoderstand>0 then decr Encoderstand
    Elseif Enc_up=1 then
       reset Enc_up
       if Encoderstand<255 then incr Encoderstand
    Endif
    Loop
    End.
    
    Isr_int2:   'Externer Interrupt von Ph_a
    Rotary.0 = Ph_a   'Signal A lesen
    Rotary.1 = Ph_b   'Signal B lesen
    Rotary = Rotary And &B00000011
    If Rotary = 0 Or Rotary = 3 Then                            'Ph_a = Ph_b
       Set Enc_down
    Else
       Set Enc_up
    End If
    Toggle Mcucsr.isc2   'Umschaltung steigende/fallende Flanke Int2
    Return

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    12.12.2004
    Ort
    Trier
    Beiträge
    38
    Das Thema Drehgeber ließ mir nun doch keine Ruhe mehr. Also habe ich einen von diesen (Billig-)Drehgeber von Pollin (Best.Nr. 240 313) ausgekramt und an mein AVR-Bastelboard nach angehängtem Plan angeschlossen.

    R1 ist lediglich ein Schutzwiderstand, falls einer der Eingänge PD4..PD6 versehentlich doch mal als Ausgang konfiguriert ist. Es befinden sich bis auf die aktivierten internen PullUp-Widerstände des AVR keine weiteren Bauteile (zwecks Entprellung) im Signalweg des Dreh-Encoders.

    Wie ich schon im vorigen Post schrieb, setze ich diesen Drehgebertyp in einem Projekt in der von dort beschriebenen Weise mittels externem Interrupt ein. Das Prinzip und auch der Nachteil dieser Lösung ist, dass jeder Signalwechsel am Interrupteingang die zugehörige Interrupt-Service-Routine (ISR) ausführen lässt. Was heute noch scheinbar einwandfrei funktioniert, kann bei einem ausgelutschtem Drehgeber mit ggf. starkem Kontaktprellen zu einer unkontrollierbaren Prozessorlast führen. Aus diesem Grund werden in Expertenkreisen generell Kontakte mittels einer Timer-Interrupt gesteuerten Routine entprellt.

    Die Bascom-eigene Lösung mit dem Encoder-Befehl arbeitete bei mir noch nie zufriedenstellend - egal ob in der Hauptprogrammschleife oder per Timerinterrupt ausgeführt - traten immer Sprünge oder Impulsverluste am Drehgeber auf. Daraufhin habe ich die untenstehende Lösung ausgearbeitet. Beim Testen konnte ich bisher absolut keine Fehler erkennen. Kritik und Verbesserungsvorschläge sind gerne willkommen.

    Lösungsweg:
    Zur Entprellung werden die beiden Drehgebersignalpaar (A,B) alle 0.5ms in der Timer0-ISR abgefragt und im Schieberegister-Byte ROTARY im Format AAAABBBB abgelegt. Nur wenn alle A's und alle B's gleich sind, also (0000_0000), (0000_1111), (1111_1111) oder (1111_0000) gilt das Encodersignalpaar als stabil.

    Außer dem Kontaktprellen besitzt dieser Drehgebertyp aber noch ein weiteres zu beseitigendes Übel:
    Grundsätzlich stehen in den Rastungen des Drehknopfes die Signalpaarungen (A,B)=(0,0) bzw. (A,B)=(1,1) stabil an. Einige der 16 Rastungen sind aber so unpräzise, das schon durch bloßes Anfassen des Drehknopfes ein Signalwechsel zu (A,B)=(1,0) bzw. (A,B)=(0,1) und beim Loslassen wieder zurück nach (A,B)=(0,0) bzw. (A,B)=(1,1) erfolgt. Dies wird in vielen Routinen (so auch in meiner vom Externen Interrupt gesteuerten Routine) fälschlicherweise als Drehbewegung des Knopfes interpretiert.

    Um diesen Fehler zu beheben muß eine Encoderauswertung drei aufeinanderfolgende Signalpaarungen berücksichtigen. Bei mir geschieht das mittels den Variablen
    ROTARY: Signalpaarung (A,B) in der aktuellen Rastung
    ROTARY1: (A,B) im Übergang zwischen zwei Rastungen (Drehrichtungserkennung)
    ROTARY2: Signalpaarung (A,B) in der vorherigen Rastung

    Befindet sich der Drehknopf in der Rastung mit (A,B)=(0,0) bzw. (A,B)=(1,1) so muß bei einer Drehung um eine Rastung anschliessend genau die entgegengesetzte Signalpaarung vorliegen, nämlich (A,B)=(1,1) bzw. (A,B)=(0,0). D.h. eine Drehbewegung kann nur stattgefunden haben wenn ROTARY ungleich ROTARY2 ist. Abhängig von der Signalpaarung ROTARY1 beim Übergang zwischen den Rastungen (A,B)=(0,1) bzw. (A,B)=(1,0) wird die Drehrichtung erkannt.
    Zur Auswertung des Encoders werden nach vollzogener Rastung entsprechend der Drehrichtung die Flags R_Flag bei Rechtsdrehung und L_Flag bei Linksdrehung gesetzt und der Encoderwert ROTARY_VALUE bei Rechtsdrehung inkrementiert bzw. bei Linksdrehung dekrementiert und können in der Hauptprogrammschleife abgefragt und zurückgesetzt werden.

    Code:
    '*******************************************************************************
    '***   Testprogramm für POLLIN Dreh-Encoder PANASONIC EVEQDBRL416B           ***
    '***   Best.Nr. 240 313                                                      ***
    '*******************************************************************************
    '***   Author: Screwdriver                                                   ***
    '***   Datum:  28.06.2009                                                    ***
    '*******************************************************************************
    
    '*******************************************************************************
    '***   Konfiguration                                                         ***
    '*******************************************************************************
    'AVR
    $regfile = "m644def.dat"
    $crystal = 20e6
    
    'System-Timer für periodische Encoder-Abfrage
    Config Timer0 = Timer , Prescale = 256
    On Timer0 Isr_timer0
    Enable Timer0
    Const Timer0_reload = 217                                   'Wert für 0.5ms
    
    'Drehencoder
    Config Portd.4 = Input : Set Portd.4 : Rotary_button Alias Pind.4       'Taste
    Config Portd.5 = Input : Set Portd.5 : Ph_a Alias Pind.5    'Encoder Signal A
    Config Portd.6 = Input : Set Portd.6 : Ph_b Alias Pind.6    'Encoder Signal B
    
    '*******************************************************************************
    '***   Variablen                                                             ***
    '*******************************************************************************
    'Variablen
    Dim Rotary As Byte                                          'Aktuelles Rasterwert (A,B)
    Dim Rotary1 As Byte                                         'Übergangswert (A,B) zwischen Rastungen
    Dim Rotary2 As Byte                                         'Letzter Rasterwert (A,B)
    Dim R_flag As Bit , L_flag As Bit                           'Flags für Links- / Rechtsdrehung
    Dim Rotary_value As Byte                                    'Zahlenwert des Encoders
    
    Dim Rotary_key As Byte : Rotary_key = &HFF                  'Schieberegister Taste, &HFF: nicht gedrückt
    Dim Press_flag As Bit                                       'Flag Taste wurde gedrückt
    Dim Release_flag As Bit                                     'Flag Taste wurde losgelassen
    
    '*******************************************************************************
    '***   HAUPTPROGRAMM                                                         ***
    '*******************************************************************************
    
    Enable Interrupts
    
    Do
    'Beispiel zur Auswertung der Flags und des Encoder-Werts im Hauptprogramm
       If R_flag = 1 Then                                       'Drehung nach Rechts
          Reset R_flag
          Print "Rechts"
          Print Rotary_value
       End If
       If L_flag = 1 Then                                       'Drehung nach Links
          Reset L_flag
          Print "Links"
          Print Rotary_value
       End If
       If Press_flag = 1 Then                                   'Taste wurde gedrückt
          Reset Press_flag
          Print "gedrueckt"
       End If
       If Release_flag = 1 Then                                 'Taste wurde losgelassen
          Reset Release_flag
          Print "losgelassen"
       End If
    Loop
    End
    
    '*******************************************************************************
    '***   ISR_TIMER0                                                            ***
    '***   Periodische Auswertung des Dreh-Encoders                              ***
    '*******************************************************************************
    Isr_timer0:
    Timer0 = Timer0_reload
    
    Shift Rotary , Left , 1                                     'Schieberegister für Entprellung (A,B)
    Rotary.4 = Ph_a                                             'Phase A lesen -> Bit 4
    Rotary.0 = Ph_b                                             'Phase B lesen -> Bit 0
    
    If Rotary <> Rotary2 Then                                   'Neues Signalpaar (A,B) ?
       Select Case Rotary
          Case &B0000_0000                                      'Aktuell (A,B)= (0,0)
             If Rotary1 = &B1111_0000 Then                      'Übergang war (A,B)= (1,0), also
                Set R_flag                                      'Rechtsdrehung
                Incr Rotary_value                               'Encoder-Wert erhöhen
             Elseif Rotary1 = &B0000_1111 Then                  'Übergang (A,B)= (0,1), also
                Set L_flag                                      'Linksdrehung
                Decr Rotary_value                               'Encoder-Wert verringern
             End If
             Rotary2 = &B0000_0000                               'Aktuelles (A,B) in vorheriges (A,B)
          Case &B0000_1111                                      'Übergang (A,B)= (0,1) zwischen Rastungen
             Rotary1 = &B0000_1111                              'erkennen und in abspeichern
          Case &B1111_0000                                      'Übergang (A,B)= (1,0) zwischen Rastungen
             Rotary1 = &B1111_0000                              'erkennen und abspeichern
          Case &B1111_1111                                      'Aktuell (A,B)= (1,1)
             If Rotary1 = &B0000_1111 Then                      'Übergang war (A,B)= (0,1), also
                Set R_flag                                      'Rechtsdrehung
                Incr Rotary_value                               'Encoder-Wert erhöhen
             Elseif Rotary1 = &B1111_0000 Then                  'Übergang war (A,B)= (1,0), also
                Set L_flag                                      'Linksdrehung
                Decr Rotary_value                               'Encoder-Wert verringern
             End If
             Rotary2 = &B1111_1111                              'Aktuelles (A,B) in vorheriges (A,B)
       End Select
    End If
    
    Shift Rotary_key , Left , 1                                 'Schieberegister für Entprellung Taste Encoder
    Rotary_key.0 = Rotary_button                                'Taste lesen -> Bit 0
    
    If Rotary_key = &B1000_0000 Then                            'Taste wurde gedrückt
       Set Press_flag
    Elseif Rotary_key = &B0111_1111 Then                        'Taste wurde losgelassen
       Set Release_flag
    End If
    Return
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken encoder.png  

  8. #18
    @screwdiver

    Hab Deinen Code gerade mal an meinen Atmega8 angepasst und muß sagen "das läuft super!".
    Keinerlei Aussetzer, einfach geschmeidig.
    Wenn mir jetzt noch jemand erklären könnte wie ich das für andere Encoder zB. http://www.watterott.com/download/PEC12-1.pdf
    anpassen kann dann wäre ich echt happy!?

    Grüße,
    kesi

  9. #19
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2007
    Beiträge
    594
    Andere Encoder brauchen das ja nicht, weil sie weniger schrottig sind - bzw. man weiß ja nicht genau, was der Encoder von Pollin im früheren Leben mal war - ggfs. was spezielles.

    Hat schonmal jemand den anderen Encoder von Pollin getestet?
    http://www.pollin.de/shop/shop.php?c...a=MDY2OTU3OTk=
    Sieht gut aus....

  10. #20
    Benutzer Stammmitglied
    Registriert seit
    12.12.2004
    Ort
    Trier
    Beiträge
    38
    @kesi
    Danke, für Deine Rückmeldung. Hast Du da jetzt den gleichen Drehgeber wie ich angeschlossen oder einen anderen?

    Wenn mir jetzt noch jemand erklären könnte wie ich das für andere Encoder zB. http://www.watterott.com/download/PEC12-1.pdf
    anpassen kann dann wäre ich echt happy!?
    Das Datenblatt ist nicht ganz eindeutig. Meine Timer-Interrupt-gesteuerte Lösung ist für alle Drehgeber, die nur bei jedem zweitem Signalwechsel einrasten passend, und meiner Meinung nach auch notwendig. Ob Dein genannter Drehgeber so einer ist, geht nicht klar aus dem Datenblatt hervor.

    @stefan_Z
    Andere Encoder brauchen das ja nicht, weil sie weniger schrottig sind - bzw. man weiß ja nicht genau, was der Encoder von Pollin im früheren Leben mal war - ggfs. was spezielles.
    Leider doch.
    Auch der von Dir alternativ genannte Drehgeber rastet nur in den Stellungen 00 und 11 ein. Eine sichere Auswertung verlangt dann - auch bei einem noch so hochwertigem Drehgeber - die Berücksichtigung der letzen drei Signalpaare. Die üblichen Routinen machen das nicht. Sieht aber wirklich edler aus, das Teil.

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen