Forum: Mikrocontroller und Digitale Elektronik Drehgeber Problem


von kime (Gast)


Lesenswert?

Servus


Ich habe diese Timerschaltung nachgebaut !
Das LCD die ANzeige und das Schalten funktionbiert alles bestens nur 
zählt der Drehgeber nur in eine Richtung egal wie rum ich drehe also 
egal ob gegen oder im Uhrzeigersinn das Programm zählt immer hoch
Hat jemand eine Idee an was es liegen könnte

http://img31.imageshack.us/i/schaltplani.gif/


'----------------------------------------------------------------------- 
---'
'
'  STEUERUNG für UV - Platinenbelichtungsgerät
'
'  von Matthias Franz, HB9EFY im Dezember 2007
'
'  Benutzung auf eigene Gefahr, keine Garantie
'  keine Gewährleistung
'
'  Berechnung des Timer1 Startwertes:
'  65535 - (Quarzfrequenz / Vorteiler)
'  65535 - (16000000 Hz / 256)
'  = 3035
'
'
'  Drehgeber     Port A, Pin 0 und 1
'  Starttaster   Port A, Pin 2
'
'  LC-Display    Port D, Db4 = Pin 0
'                        Db5 = Pin 1
'                        Db6 = Pin 2
'                        Db7 = Pin 3
'                        E = Pin 5
'                        Rs = Pin 4
'
'  Relais        Port A, Pin 7
'
'
'  VIEL SPASS
'             Matthias
'
'----------------------------------------------------------------------- 
---'

$regfile = "m32def.dat"                                     ' BASCOM AVR 
Steuerdatei für ATmega32
$crystal = 16000000                                         ' 16 Mhz 
Quarz

'----------------------------------------------------------------------- 
-------
' Initialisierung des LCD Displays (unveränderte Standardbelegung)
'
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , 
Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
Config Lcdbus = 4
Cls
Cursor Off Noblink
'
'----------------------------------------------------------------------- 
-------
'
' Dimensionierung der verwendeten Variablen
'
Dim B As Byte                                               ' Variable 
für Drehkoderlesefunktion
Dim Spalte As Byte                                          ' Position 
auf dem LC-Display
Dim C As Integer
Dim Ce As Eram Integer                                      'Variable im 
EEprom (Belichtungszeit)

Config Pina.0 = Input                                       'Drehgeber 
und Starttaste
Config Pina.1 = Input                                       'Drehgeber 
und Starttaste
Config Pina.2 = Input                                       'Drehgeber 
und Starttaste

Config Pina.6 = Output                                      'Ausgang für 
den Alarmton (derzeit NICHT BENUTZ)
Config Pina.7 = Output                                      'Ausgang für 
Relais

Porta = &B0000111                                           'Port A: 
0,1,2 Pull-Up Widerstand EIN (muss so sein um den Geber zu lesen)
Porta.6 = 0                                                 'Alarmton 
AUS (DERZEIT NICHT BENUTZT)
Porta.7 = 0                                                 'Relais AUS

C = Ce                                                      'Wert für 
die Belichtungszeit aus Eeprom holen

If C < 0 Then                                               ' 
Entsprechend dem Wert im Eeprom (ein-, zwei- oder mehrstellig)
             C = 0                                          ' wird die 
Position auf dem LCD angepasst
             Spalte = 11
             End If
If C >= 0 Then Spalte = 11
If C >= 10 Then Spalte = 10
If C >= 100 Then Spalte = 9

'----------------------------------------------------------------------- 
-------
'  Drehimpulsgeber - Abfrage
'  bestimmt die Belichtungszeit
'
Geber_abfrage:

     B = Encoder(pina.0 , Pina.1 , Links , Rechts , 0)
     Locate 1 , 2 : Lcd "Time:" : Locate 1 , Spalte : Lcd C
     Locate 1 , 13 : Lcd "sec."
     Locate 2 , 2 : Lcd "START ?"

     If Pina.2 = 0 Then Goto Countdown

Goto Geber_abfrage
End


'----------------------------------------------------------------------- 
-------
' Rotations - sub - routine
'
Links:
C = C - 5                                                   ' Verändern 
des Belichtungswertes in - 5 Sek. Schritten
If C <= 1 Then C = 0
If C < 100 Then Spalte = 10
If C < 10 Then Spalte = 11
Cls
Return

Rechts:
C = C + 5                                                   ' Verändern 
des Belichtungswertes in + 5 Sek. Schritten
If C >= 10 Then Spalte = 10
If C >= 100 Then Spalte = 9
Cls
Return
'
'----------------------------------------------------------------------- 
-------
'
' Countdown - sub - routine
'
Countdown:

   Ce = C 
'Belichtungszeit in Eeprom schreiben

   Locate 2 , 1 : Lcd "                "                    ' LCD Zeile 
2 löschen
   On Timer1 Ontimer1
   Config Timer1 = Timer , Prescale = 256                   ' Vorteiler 
für Timer1
   Enable Timer1
   Enable Interrupts

   Porta.7 = 1                                              'Relais 
(Belichtung) EIN

'---------------------------------------------------------

   Timer1 = 3035


     Do

       If C = 0 Then Goto Countdown_stop

                 If C < 100 Then
                                Spalte = 10
                                Locate 1 , 9 : Lcd " "
                               End If

                 If C < 10 Then
                                Spalte = 11
                                Locate 1 , 10 : Lcd " "
                               End If

       Locate 1 , Spalte : Lcd C

     Loop


'---------------------------------------------------------
    Ontimer1:
      Timer1 = 3035
      C = C - 1
    Return
'---------------------------------------------------------
'
' Countdown STOP
'

Countdown_stop:

Porta.7 = 0                                                 'Relais AUS
Porta.6 = 1                                                 'Alarmton AN 
(DERZEIT NICHT BENUTZT)

Cls                                                         ' LCD: 
Endmeldung angeben
Locate 1 , 1
Lcd "Belichtung STOP"
Locate 2 , 1
Lcd "Press RESET"                                           ' RESET 
drücken für Anfangszustand
'---------------------------------------------------------
'
' Schluss mit Lustig....
'
Stop
End
'---------------------------------------------------------

von Schrotty (Gast)


Lesenswert?

Ich vermute mal, dass das Basic ist und damit kenn ich mich nicht aus, 
aber dennoch stellt sich mir die Frage, was diese Zeile hier macht:

B = Encoder(pina.0 , Pina.1 , Links , Rechts , 0)

Kann es sein, dass da irgendwas fehlt? z.B. die Funktion ENCODER?

Nicht schlagen, wie gesagt, ich hab von Basic keine Ahnung.

von kime (Gast)


Lesenswert?

Habe mal das ganze mit nem Atmega8 aufgebaut , selbset Problem.
Ich habe mal eben alles rausgelöscht was nichts mit dem Problem zu tun 
hat so ist der Code zumindest schlanker

Der Geber hängt an Portd.0 und Portd.1

$regfile = "m8def.dat"
$crystal = 8000000



Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
   Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2                                         '
Cls


Dim B As Byte
Dim Spalte As Byte
Dim C As Integer
Dim Ce As Eram Integer

Config Portd.0 = Input
Config Portd.1 = Input





Portd = &B0000011



C = Ce

If C < 0 Then
             C = 0
             Spalte = 11
             End If
If C >= 0 Then Spalte = 11
If C >= 10 Then Spalte = 10
If C >= 100 Then Spalte = 9

'----------------------------------------------------------------------- 
-------



Geber_abfrage:

     B = Encoder(pind.0 , Pind.1 , Links , Rechts , 0)
     Locate 1 , 2 : Lcd "Time:" : Locate 1 , Spalte : Lcd C
     Locate 1 , 13 : Lcd "sec."




Goto Geber_abfrage
End



' Rotations - sub - routine
'
Links:
C = C - 5
If C <= 1 Then C = 0
If C < 100 Then Spalte = 10
If C < 10 Then Spalte = 11
Cls
Return

Rechts:
C = C + 5                                                   '
If C >= 10 Then Spalte = 10
If C >= 100 Then Spalte = 9
Cls
Return






Stop
End
'---------------------------------------------------------

von Schrotty (Gast)


Lesenswert?

... und nochmal meine Frage: Was macht diese Zeile?
B = Encoder(pind.0 , Pind.1 , Links , Rechts , 0)

von kime (Gast)


Lesenswert?

Hallo

Das ist eine Bascom eigene Funktion für Drehgeber allg. so weit ich weis 
!"

von Schrotty (Gast)


Lesenswert?

>so weit ich weis
Aha! also wenn das so ist, dann schau doch mal genauer nach, was diese 
Finktion macht. Denn ich könnte wetten, dass die dir dann irgenwie die 
Drehrichtung und Anzahl der Inkremente zurückliefert.
Und dann würde ich an einem einfachen Beispiel prüfen, ob die Funktion 
das tut, was du von ihr erwartest.. wenn ja, dann im restlichen Code 
weitersuchen.

von kime (Gast)


Lesenswert?

Hallo


Hier mal ein Link für dich , habe mir das schon durchgelesen und keinen 
Fehler gefunden. Is eine Einfache Funktion und ist ganz gut erklärt

http://www.avrhelp.mcselec.com/index.html?encoder.htm

von kime (Gast)


Lesenswert?

Kann es an den Portd.0 und Portd.1 liegen , da dort auch RX und TX 
umgesetzt werden.Allerdings dachte ich dies nur der Fall ist wenn man 
den mc dazu veranlasst diese anzusprechen also zum bsp Baud im Programm 
stehen hat

von sbyxc (Gast)


Lesenswert?

B = Encoder(pind.0 , Pind.1 , Links , Rechts , 0)

Wieso ist der eine Pin gross- und der andere kleingeschrieben?

Gast

von kime (Gast)


Lesenswert?

Nur ein Übertragunsfehler , im Code ist alles ok also beides groß

Ich versteh nicht warum er nur in eine Richtung zählt

von sbyxc (Gast)


Lesenswert?

Falsch angeschlossen?

Gast

von kime (Gast)


Lesenswert?

Hallo

Er ist wie auf dem Bild angeschlossen nur eben an den Portd.0 und 
Portd.1 (A,B)

von Schrotty (Gast)


Lesenswert?

Ganz unabhängig, woran das Problem jetzt liegt, würde ich an deiner 
Stelle auch ne "Begrenzung" für C im "Rechtslauf" einbauen..

if C>= 101 then C = 100

von kime (Gast)


Lesenswert?


von kime (Gast)


Lesenswert?

@ Schrotty

Der ganze Code dient nur zum Testen sollte nur schnell zeigen ob alles 
funktioniert , danach wollte ich mein Programm drumherum bauen bzw es 
anpassen.Danke für deinen Tip werde es berücksichtigen

von Karl H. (kbuchegg)


Lesenswert?

kime schrieb:
> Habe mal das ganze mit nem Atmega8 aufgebaut , selbset Problem.
> Ich habe mal eben alles rausgelöscht was nichts mit dem Problem zu tun
> hat so ist der Code zumindest schlanker
>
> Der Geber hängt an Portd.0 und Portd.1

Lass mal das ganze 'Zahlen an bestimmter Spalte ausgeben' weg und 
schreib in 'Links' den Text "links" bzw in 'Rechts' den text "rechts" 
raus. Nicht, dass du dir ein Ei gelegt hast, weil du die Zahlen immer 
nur übereinander pinselst, aber den Bereich in dem die Zahlen ausgegeben 
werden nicht löscht.

von Karl H. (kbuchegg)


Lesenswert?

kime schrieb:
> Hallo
>
> Er ist wie auf dem Bild angeschlossen nur eben an den Portd.0 und
> Portd.1 (A,B)

Das Bild in der BASCOM Hilfe würde ich nicht zu ernst nehmen. Im Zweifel 
gilt immer das Datenblatt des Herstellers. GND ist oft auf dem mittleren 
Pin und nicht am Rand.

von kime (Gast)


Lesenswert?

Hallo

Danke für den Tip mit den Zahlen werde es gleich mal testen !


Angeschlossen ist er so wie es im Datenblatt steht Gnd ist in der Mitte
http://www.produktinfo.conrad.com/datenblaetter/700000-724999/705586-da-01-ml-Drehimpulsgeber_liegend_de_en.pdf

von kime (Gast)


Lesenswert?

So ich habe jetzt mal die ganzen Zahlen Weg gelassen und nur 
Rechts,Links zum LCD geschickt.

Egal welche Richtung ich drehe es kommt immer Rechts , ab und zu aber 
wirklich nur ganz ganz selten kommt ein Links durch

von kime (Gast)


Lesenswert?

Hallo Again

So habe nunmal 100% des Codes gekürz also auch die LCD Anzeige die 
dauerhaft in der Schleife läuft

------------------------------------------------

Geber_abfrage:

     B = Encoder(pind.0 , Pind.1 , Links , Rechts , 0)
     Locate 1 , 2 : Lcd "Time:" : Locate 1 , Spalte : Lcd C
     Locate 1 , 13 : Lcd "sec."




Goto Geber_abfrage


-----------------------------------------------------


Habe also den Bereich gelöscht
Locate 1 , 2 : Lcd "Time:" : Locate 1 , Spalte : Lcd C
Locate 1 , 13 : Lcd "sec."




Ich lasse mir jezt nur noch Rechts oder Links anzeigen

Links:
C = C - 5
Lcd "Links"
Waitms 20

Cls
Return

Rechts:
C = C + 5                                                   '
Lcd "Rechts"
Waitms 20
Cls

Return




Und siehe da auch einmal funktioniert alles besten ab und zu kommt zwar 
ein Fehler , also wird Rechts statt Links angezeigt aber das könnte man 
denke ich mit 2 Kondensatoren fixen bzw damnit kann ich leben

Was mich nur wundert das es anscheined an der LCD Anzeige bzw an dem 
Zähler C liegt hat da jemand eine Idee

von kime (Gast)


Lesenswert?

So neuer Tag neues Glück , hat jemand eine Idee an was es liegen könnte

von kime (Gast)


Lesenswert?

Kann es sein das der ATmega8 es nicht schafft , beides zu handeln also 
LCD Ausgabe und Drehgeber einlesen.
Ich würde mich sehr freuen wen jemand von euch einen Tip hat oder besser 
eine Idee an was es liegen könnte

von Karl H. (kbuchegg)


Lesenswert?

kime schrieb:
> Kann es sein das der ATmega8 es nicht schafft , beides zu handeln also
> LCD Ausgabe und Drehgeber einlesen.

Kann ich mir nicht vorstellen.

> Ich würde mich sehr freuen wen jemand von euch einen Tip hat oder besser
> eine Idee an was es liegen könnte

Das Problem ist, dass kein Mensch hier weiß, wie Encode arbeitet. Dieses 
Wissen wäre aber wichtig um zu entscheiden, ob sich da drinnen ein 
Fehler verbirgt oder nicht.

von Falk B. (falk)


Lesenswert?

@  kime (Gast)

>Kann es sein das der ATmega8 es nicht schafft , beides zu handeln also
>LCD Ausgabe und Drehgeber einlesen.

Das schafft der AVR schon. Die Frage ist, ob dein Programm dafür auch 
richtig geschrieben ist.

Poste VOLLSTÄNDIGEN Quelltext als ANHANG.

MFG
Falk

von kime (Gast)


Angehängte Dateien:

Lesenswert?

hallo


Hier der Code als Anhang .txt

von Falk B. (falk)


Lesenswert?

Sieht ok aus, ich tippe auf einen Verdrahtungsfehler roder defekten 
Drehgeber. Lies mal direkt die Eingaänge ein und gibt sie auf dem LCD 
aus. Ich wette, ein Pin wackelt nicht.

MFg
Falk

von kime (Gast)


Lesenswert?

Hallo Falk

Habe ich auch erst gedacht das Porblem ist aber wie ich weiter oben 
gesagt habe das es funktioniert wen ich die Lcd Ausgabe weglasse .
Also den Code so kürze !

Zitat:

Hallo Again

So habe nunmal 100% des Codes gekürz also auch die LCD Anzeige die
dauerhaft in der Schleife läuft

------------------------------------------------

Geber_abfrage:

     B = Encoder(pind.0 , Pind.1 , Links , Rechts , 0)
     Locate 1 , 2 : Lcd "Time:" : Locate 1 , Spalte : Lcd C
     Locate 1 , 13 : Lcd "sec."




Goto Geber_abfrage


-----------------------------------------------------


Habe also den Bereich gelöscht
Locate 1 , 2 : Lcd "Time:" : Locate 1 , Spalte : Lcd C
Locate 1 , 13 : Lcd "sec."




Ich lasse mir jezt nur noch Rechts oder Links anzeigen

Links:
C = C - 5
Lcd "Links"
Waitms 20

Cls
Return

Rechts:
C = C + 5                                                   '
Lcd "Rechts"
Waitms 20
Cls

Return

von kime (Gast)


Lesenswert?

keiner ne Idee

von kime (Gast)


Lesenswert?

Hallo

Zitat:
Lies mal direkt die Eingaänge ein und gibt sie auf dem LCD
aus. Ich wette, ein Pin wackelt nicht.

Wie kann ich das am besten machen ??

von Karl H. (kbuchegg)


Lesenswert?

kime schrieb:
> Hallo
>
> Zitat:
> Lies mal direkt die Eingaänge ein und gibt sie auf dem LCD
> aus. Ich wette, ein Pin wackelt nicht.
>
> Wie kann ich das am besten machen ??

Jetzt ist es an mir, mich zu wundern.
Du programmierst und weißt nicht, wie man Eingänge abfrägt?

von kime (Gast)


Lesenswert?

Ich gebe gerne Kurse im Wundern , ne spass bei seite !
Ich habe ja gefragt wie ich das am besten mache , also in welchem 
Bereich des Codes , wie die LCD Anzeige in der Main Schleife? Bin kein 
Programmier Ass eher ein Anfänger ich würde die Eingänge spontan jetzt 
mit IF ... abfragen ?

von Karl H. (kbuchegg)


Lesenswert?

kime schrieb:
> Ich gebe gerne Kurse im Wundern , ne spass bei seite !
> Ich habe ja gefragt wie ich das am besten mache , also in welchem
> Bereich des Codes , wie die LCD Anzeige in der Main Schleife? Bin kein
> Programmier Ass eher ein Anfänger ich würde die Eingänge spontan jetzt
> mit IF ... abfragen ?

Leg deinen jetzigen Code beiseite und fang ein Testprogramm an

Port auf Eingang schalten

do

  if( pin 1 ist high )
    pinsle "1 high" hin

  if( pin 2 ist high )
    pinsle "2 high" hin

loop

so ungefähr. Denk dir was aus. Du willst wissen, ob die Pins toggeln. 
Wie kannst du dein Programm benutzen um das festzustellen.

von kime (Gast)


Lesenswert?

Hallo


Also mein Testporgramm liefer mir bei beiden Eingängen ein High

lg

von Falk B. (falk)


Lesenswert?

Geber_abfrage:

     Locate 1 , 1
     Lcd Pind.0
     Lcd Pind.1

Goto Geber_abfrage

BASCOM ist schon komplex . . .

von kime (Gast)


Lesenswert?

Hallo

Danke für den Tip so gehts natürlich noch einfacher !

Beides liefert aber das selbe zurück 0 und 1 sind auf High die Schritte 
vom Drehgeber werden auch erkannt bzw angezeigt , solange man langsam 
dreht !

von kime (Gast)


Lesenswert?

Kann es sein das die Funkltion Encoder von Bascom einfach nicht zu 
meinen Drehgeber passt bzw zu den Schritten die der Drehgeber macht

Hat jemand schonmal Erfahrungen mit dem Drehgeber von Conrad gemacht ?
Hier mal beide Links zum Drehgeber und zu der Funktion

http://www.avrhelp.mcselec.com/index.html?encoder.htm

http://www.produktinfo.conrad.com/datenblaetter/700000-724999/705586-da-01-ml-Drehimpulsgeber_liegend_de_en.pdf

von Falk B. (falk)


Lesenswert?

Versuchs mal mit

    B = Encoder(pina.0 , Pina.1 , Links , Rechts , 1)

Und noch besser, im BASCOM Handbuch (PFD) gibt es ein vollständiges 
Beispiel zu dem Befehl. Hmmmmm . . .

von kime (Gast)


Lesenswert?

Hallo


Zitat:

Versuchs mal mit

    B = Encoder(pina.0 , Pina.1 , Links , Rechts , 1)

Und noch besser, im BASCOM Handbuch (PFD) gibt es ein vollständiges
Beispiel zu dem Befehl. Hmmmmm . . .


Zitat:


In meinem Code arbeite ich ja genau mit diesem Bsp bzw mit der von dir 
genannten Funktion ?!
Das weiter unten war nur zum Testen der Eingänge.

von Karl H. (kbuchegg)


Lesenswert?

Kannst du ausser Bascom noch was anderes benutzen?
Sagen: wir AVR-Studio mit WinAvr?

von Karl H. (kbuchegg)


Lesenswert?

Da fällt mir noch etwas ein.
Wie hast du den Enocder angeschlossen? SO wie im Datenblatt mit den 
Widerstanden und Kondensatoren?

von kime (Gast)


Lesenswert?

Zitat:

Kannst du ausser Bascom noch was anderes benutzen?
Sagen: wir AVR-Studio mit WinAvr?


Leider nein !



Zitat:

Wie hast du den Enocder angeschlossen? SO wie im Datenblatt mit den
Widerstanden und Kondensatoren?

Schon beides ausprobiert mit und ohne Widerst. und Konds. immoment mit !

von Karl H. (kbuchegg)


Lesenswert?

kime schrieb:
> Zitat:
>
> Kannst du ausser Bascom noch was anderes benutzen?
> Sagen: wir AVR-Studio mit WinAvr?
>
>
> Leider nein !

Schade.
Das Problem.
Von uns hier weiß niemand, wie der Befehl "Encoder" intern arbeitet. Das 
ist auf der anderen Seite das gute an BASCOM, wird hier aber zum 
Boomerang, wenn es nicht so funktioniert, wie es funktionieren soll und 
keiner weiß warum.

Hardwaremässig kannst du nicht viel falsch machen.
Dein letztes Testprogramm sieht auch nicht schlecht aus. Ich würde mal 
sagen, das entspricht ziemlich genau dem, was ich auch aus der Hilfe 
herauslesen würde.

Entweder hat dein Encoder einen Schaden weg oder BASCOM hat hier einen 
Fehler.

Als ich meinen ersten Encoder ausprobiert habe, hab ich folgendes 
gemacht: Ich hab mein Multimeter auf Durchgangsprüfer gestellt (in dem 
Modus pfeift das Ding, wenn es einen Durchgang gibt). Eine Messleitung 
vom Multimeter an den A-Pin, den anderen auf Ground vom Encoder. Beim 
Durchdrehen des Encoders um nur 1 Rastposition ertönt ein ganz kurzes 
Pfeifen. Das für mich interessante war, das beim Drehen um 1 
Rastposition nur ein kurzer Impuls vom Encoder kam und nicht wie 
erwartet eine Ein/AUs Sequenz beim Drehen über 2 Rast-Positionen.
Dasselbe dann beim Pin-B

Vielleicht kannst du das auch mal probieren. Auch eine LED könnte gehen, 
die beim Drehen auf die nächste Rastposition kurz aufleuchtet.

Ich bin mir nicht ganz sicher, aber anscheinend gibt es da 2 Bauarten. 
Die wie oben beschrieben und die bei denen die beiden Pins die Zustände 
beim Drehen auf die nächste Rastposition wechseln. Ich hab mich da aber 
nie näher damit beschäftigt.

von screwdriver (Gast)


Angehängte Dateien:

Lesenswert?

Karl heinz Buchegger schrieb:
> Das Problem ist, dass kein Mensch hier weiß, wie Encode arbeitet.

Im Anhang der disassemblierte Maschinencode, den BASCOM aus diesem 
Programm generiert.
1
$regfile = "m16def.dat"
2
Dim B As Byte
3
4
Do
5
   B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1)
6
Loop
7
8
Links:
9
nop
10
Return
11
12
Rechts:
13
nop
14
Return

von kime (Gast)


Lesenswert?

Hallo

Durchgepibst habe ich das ganze auch schon habe hier einen Testboy 
(Durchgangsprüfer)


Also der Drehgeber macht folgendes:

Rechts(CW)
Wen man schnell durchschaltet also direkt auf die Rastposition geht dan 
sieht man nur:

11
00
11
00

Wenn man langsam dreht spürt man wen er in der Mitte von 2 
Rastpositionen steht wen , man dan langsam dreht sieht das ganze so 
aus(Von Rastposition zu Rastposition)

11<- Rastp.
10
00<- Rastp.
01
11<- Rastp.

Links(CCW)

11
00
11
00

oder langsam

11<- Rastp.
01
00<- Rastp.
10
11<- Rastp.

von Michael M. (Gast)


Lesenswert?

kime schrieb:
> Hat jemand schonmal Erfahrungen mit dem Drehgeber von Conrad gemacht ?
> Hier mal beide Links zum Drehgeber und zu der Funktion
ja. er macht genau 2 flankenwechsel pro raster auf jedem pin.

von Karl H. (kbuchegg)


Lesenswert?

screwdriver schrieb:
> Karl heinz Buchegger schrieb:
>> Das Problem ist, dass kein Mensch hier weiß, wie Encode arbeitet.
>
> Im Anhang der disassemblierte Maschinencode, den BASCOM aus diesem
> Programm generiert.

Hmm. In diesem Code kann ich keine Vorkehrungen gegen prellende Taster 
entdecken -> die Widerstände und Kondensatoren sind ein Muss!

von Karl H. (kbuchegg)


Lesenswert?

Wenn sich jemand beteiligen will.
Hier ist meine aufgearbeitete Version des BASCOM-Assembler Codes
1
+00000046:   E6A0        LDI     R26,0x60         ; X Pointer laden (Temporäre Speicher zur Aufnahme
2
+00000047:   E0B0        LDI     R27,0x00         ; des letzten Encoder Zustandes)
3
+00000048:   9468        SET                      ; Set T in SREG, Zeigt an ob Encode warten soll
4
5
+00000049:   914C        LD      R20,X            ; letzten Encoder Zustand holen
6
7
+0000004A:   B306        IN      R16,0x16         ; neuen Zustand holen
8
9
+0000004B:   2788        CLR     R24              ; Zustand in R24 neu codieren um beliebige Pins
10
+0000004C:   FD00        SBRC    R16,0            ; Pins benutzen zu können. Effektiv werden die
11
+0000004D:   6081        ORI     R24,0x01         ; angegebenen Pins in R24 in die Bits 0 und 1
12
+0000004E:   FD01        SBRC    R16,1            ; abgebildet
13
+0000004F:   6082        ORI     R24,0x02
14
         
15
+00000050:   1784        CP      R24,R20          ; hat sich am Eingang was getan?
16
+00000051:   F411        BRNE    PC+0x03          ; Ja: weiter bei 0x0054
17
18
+00000052:   F3B6        BRTS    PC-0x09          ; Wenn Encode warten soll -> 0x0049
19
+00000053:   C010        RJMP    PC+0x0011        ; AUsstieg: -> 0x005E
20
21
                                                  ; an den Tasten hat sich was getan
22
                                                  ; nur was
23
+00000054:   938C        ST      X,R24            ; aber erst mal den neuen Zustand wegspeichern
24
25
+00000055:   9542        SWAP    R20              ; alten und neuen Zustand gemeinsam in ein Register holen
26
+00000056:   0F84        ADD     R24,R20          ; High-Nibble: alter Zustand, Low Nibble: neuer
27
28
+00000057:   3082        CPI     R24,0x02         ; Kanal B: 0->1 (wobei A auf 0 ist)
29
+00000058:   F049        BREQ    PC+0x0A          ; -> 0x0062  (call rechts)
30
31
+00000059:   3180        CPI     R24,0x10         ; Kanal A: 1->0 (wobei B auf 0 ist)
32
+0000005A:   F039        BREQ    PC+0x08          ; -> 0x0062  (call rechts)
33
34
+0000005B:   3283        CPI     R24,0x23         ; Kanal A: 0->1 (wobei B auf 1 ist)
35
+0000005C:   F029        BREQ    PC+0x06          ; -> 0x0062   (call rechts)
36
37
+0000005D:   3381        CPI     R24,0x31         ; Kanal B: 1->0 (wobei A auf 1 ist)
38
+0000005E:   F019        BREQ    PC+0x04          ; ->0x0062    (call rechts)
39
40
+0000005F:   940E0068    CALL    0x00000068       ; keines von diesen, call links
41
+00000061:   C002        RJMP    PC+0x0003        ; und zum Ende vom Encode
42
43
+00000062:   940E0066    CALL    0x00000066       ; call rechts

OB ich jetzt die Funktion links mit der Funktion rechts vertauscht habe, 
soll nicht so die Rolle spielen.
Aber so ganz verstehe ich den Teil ab 0x0057 noch nicht, ob da 
tatsächlich richtig verzweigt wird.


Hmm. Ausgangsstellung 11

Drehen nach rechts

  A B
> 1 1<- Rastp.
> 1 0
> 0 0<- Rastp.
> 0 1
> 1 1<- Rastp.

d.h. Kanal B wechselt von 1 auf 0, wobei A auf 1 ist (erste Drehung)
das müsste in R24 die 0x31 ergebn und damit den richtigen Call
nächster Teilschritt: A wechselt von 1 auf 0 wobei B auf 0 ist
das ist in R24 die 0x10 und damit ein erneuter Call auf rechts

Nächste Drehung
B geht von 0 auf 1, A ist 0, d.h. R24 hat 0x02 -> call rechts
zweiter SChritt
A geht von 0 auf 1, B ist 1, d.h. R24 hat 0x23 -> call rechts

Jetzt anders rum
  A B
> 1 1<- Rastp.
> 0 1
> 0 0<- Rastp.
> 1 0
> 1 1<- Rastp.

A von 1 auf 0, B ist 1, kommt bei den Compare nicht vor -> call links
B von 1 auf 0, A ist 0, kommt Compare nicht vor -> call links
A von 0 auf 1, B ist 0, detto -> call links
B von 0 auf 1, A ist 1, detto -> call links

Hmm. der Code sieht soweit in Ordnung aus, mit der Ausnahme, dass die 
jeweilige Callback Funktion bei Drehen von einer Rastposition in die 
nächste 2-mal aufgerufen wird.

Das einzige was mich hier stört ist, dass der Code ganz am Anfang immer 
davon ausgeht, dass an *X die letzte Tasterkombination steht. Auch bei 
Eintritt in Encode. Wenn jetzt aber zuviel zu tun ist, dann muss das 
nicht stimmen! Und das dekct sich dann auch mit der Beobachtung von 
kime. Dreht man langsam, funktioniert alles.
Und natürlich, dass die ganze Problematik 'Tastenprellen' komplett 
ignoriert wird. Insbesondere letzteres stört mich dann schon.

Summa summarum.
Ich denke, das geschilderte Verhalten ist per Design so. Gibt es von 
einem Enocde AUfruf zum nächsten zuviel zu tun (zb Ausgaben aufs LCD), 
dann kann es sein, dass der Encoder Schritte macht, die die 
Auswertelogik nicht mitbekommt.
Nur beispielsweise
Nimmt man die Sequenz

> 1 1<- Rastp.
> 1 0
> 0 0<- Rastp.
> 0 1
> 1 1<- Rastp.

und streicht die 3.te und 4.te Zeile (die die Encode Funktion wegen 
Arbeitsüberlastung nicht mitbekommt), so kommt raus

> 1 1<- Rastp.
> 1 0
> 1 1<- Rastp.

und das ist dann: einmal rechts gefolgt von einmal links

von Karl H. (kbuchegg)


Lesenswert?

und ein bischen googlen zeigt, dass anscheinend auch Andere ihre liebe 
Not mit dem Encode haben.

von kime (Gast)


Lesenswert?

Hallo

Vielen Dank für die Infos.
Ich denke das ist genau das Problem !

Zitat:
Ich denke, das geschilderte Verhalten ist per Design so. Gibt es von
einem Enocde AUfruf zum nächsten zuviel zu tun (zb Ausgaben aufs LCD),
dann kann es sein, dass der Encoder Schritte macht, die die
Auswertelogik nicht mitbekommt.
Zitat:



Wen ich die LCD Anzeige "Geber_abfrage:" stehen lasse kann ich nur in 
eine Richtung hoch bzw runter zählen !
Wen ich die LCD Anzeige rausnehme und einfach mit C anzeigen lasse in 
Rechts bzw Links und nicht in der Schleife "Geber_abfrage:" dan kann ich 
zwar in beide Richtungen (Hoch/Runter)zählen allerdings springt der 
Zähler immer um 10 also 2 Schritte und nicht um 5


Die Frage die sich stellt ist wie man das vermeiden kann bzw welche 
Lösungsansetze gibt es ?

von Karl H. (kbuchegg)


Lesenswert?

kime schrieb:

> Die Frage die sich stellt ist wie man das vermeiden kann bzw welche
> Lösungsansetze gibt es ?

Musst du googeln. Bei meiner kurzen Googlerei habe ich 
alternativ-Auswertungen gesehen.
Aber so wie es aussieht, kannst du den Encode Befehl vergessen. Der ist 
fehldesigned. Vielleicht repariert der Hersteller den mal. Aber im 
Moment ist das nicht wirklich 100% brauchbar.

von Falk B. (falk)


Lesenswert?

@  Karl heinz Buchegger (kbuchegg) (Moderator)

>Hmm. In diesem Code kann ich keine Vorkehrungen gegen prellende Taster
>entdecken -> die Widerstände und Kondensatoren sind ein Muss!

Keineswegs! Siehe Artikel Drehgeber. Das ist ja der Clou daran!

MfG
Falk

P S Man kann ja einfach mal das BASCOM Demo runterladen und auf seiner 
heimischen AVR-Umgebung testen. Hab aber keinen Drehgeber hier.

von Jürgen W. (juergen_w) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Wenn sich jemand beteiligen will.
> Hier ist meine aufgearbeitete Version des BASCOM-Assembler Codes

Die erinnert mich stark an meine eigene Routine die ich mal hier in der 
Codesammlung gepostet habe.

Beitrag "Drehencoder auslesen ASM"

Diese ist auch nicht entprellt und funktioniert wunderbar, WENN die 
Abtastrate hoch genug ist.
Ich würde mal bei den Fuses nachschauen ob der M32 auch wirklich mit den 
besagten 16MHz läuft.

Ich kenne mich mit Basic zwar nicht so gut aus, aber ich nehme an, das 
der Cls Befehl das Display löscht.
Falls das so ist:
Um Zeit zu sparen und die Abtastrate zu erhöhen, würde ich den Cls mal 
versuchsweise rausnehmen da dieser (glaub) an die 5mS braucht und so 
eine Stellung verschlucken könnte.
Evtl. die nicht benötigten Zeichen mit Space überschreiben, das spart 
Zeit.

von screwdriver (Gast)


Lesenswert?

Falk Brunner schrieb:
> @  Karl heinz Buchegger (kbuchegg) (Moderator)
>
>>Hmm. In diesem Code kann ich keine Vorkehrungen gegen prellende Taster
>>entdecken -> die Widerstände und Kondensatoren sind ein Muss!
>
> Keineswegs! Siehe Artikel Drehgeber. Das ist ja der Clou daran!

@Falk:
Ok, Dank Peter Dannegger und anderen wissen wir, dass selbst der 
billigste mechanische Encoder mit einer guten Software auch gut 
funktioniert.

Aber dennoch, und damit möchte ich die professionellen 
Hardware-Entwickler in diesem Forum fragen:
Wer traut sich in einem Serienprodukt im Zeitalter von EMV einen 
Drehgeber ohne RC-Glied direkt an µC-Pins anzuschliessen?

mfg
screwdriver

von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner schrieb:
> @  Karl heinz Buchegger (kbuchegg) (Moderator)
>
>>Hmm. In diesem Code kann ich keine Vorkehrungen gegen prellende Taster
>>entdecken -> die Widerstände und Kondensatoren sind ein Muss!
>
> Keineswegs! Siehe Artikel Drehgeber. Das ist ja der Clou daran!

Hmm.
Dann müsste man aber alle Zustandswechsel auscodieren.
Solange da ein default 'wenns nichts anderes ist, dann ist es eine 
Drehung nach links' drinnen ist, müsste das IMHO Ärger beim Auswerten 
geben. Oder nicht?

von Falk B. (falk)


Lesenswert?

@  Karl heinz Buchegger (kbuchegg) (Moderator)

>> Keineswegs! Siehe Artikel Drehgeber. Das ist ja der Clou daran!

>Hmm.
>Dann müsste man aber alle Zustandswechsel auscodieren.

Sicher, davon gehe ich implizit aus. Alles andere sind Bastellösungen.

@screwdriver (Gast)

>Aber dennoch, und damit möchte ich die professionellen
>Hardware-Entwickler in diesem Forum fragen:
>Wer traut sich in einem Serienprodukt im Zeitalter von EMV einen
>Drehgeber ohne RC-Glied direkt an µC-Pins anzuschliessen?

;-)
Hehe, erwischt. In dem Fall schon mit RC-Filter, aber RICHTIG! Einfach 
einen Pull-Up und C-Gegen Masse ist IMO NICHT richtig, weil der 
Schalter/Taster dann immer den geladenen C kurzschliest, das brutzelt 
auf Dauer die Kontakte. Richtig ist es wie im Artikel Entprellung.

MFG
Falk

von Klaus B. (forrestjump)


Lesenswert?

schau mal hier, auch direkt angeschlossen


http://www.rfcandy.biz/communication/rotator.html

Davon abgesehen habe ich auch gerade ein Problem mit dem 
Lautstärkeregler meines Autoradios. Ein Drehgeber. Will sich einfach 
nicht lauter stellen lassen bzw. springt dauernd hin und her beim 
drehen.
Rotator ausgebaut auseinander genommen, wieder eingebaut...geht.
Ein halbes Jahr. Jetzt wieder derselbe Krams.
Ich mag mir so eine Qualität etwa im Flugzeug ungern vorstellen.

von Karl H. (kbuchegg)


Lesenswert?

Klaus B. schrieb:
> schau mal hier, auch direkt angeschlossen
>
>
> http://www.rfcandy.biz/communication/rotator.html
>
> Davon abgesehen habe ich auch gerade ein Problem mit dem
> Lautstärkeregler meines Autoradios. Ein Drehgeber. Will sich einfach
> nicht lauter stellen lassen bzw. springt dauernd hin und her beim
> drehen.

Ja, das hat meine Softwareroutine am Anfang auch gemacht. Wenn ich den 
Geber in der gerasteten Stellung ganz vorsichtig ein bischen hin und her 
bewegt habe, sind die wunderlichsten Dinge passiert :-)

Aber jetzt ist sie absolut stabil. Seitdem weiß ich, warum dieser 
'Interrupt bei A und Ansehen von B' Ansatz absoluter Murks ist :-)

von kime (Gast)


Lesenswert?

Gibt es in C eine ähnliche Funktion für Drehgeber ?

von Karl H. (kbuchegg)


Lesenswert?

Anders als in BASCOM ist die Philosophie in C die:
Vorgefertigt gibt es fast nichts.
Dafür kann aber jeder sich seine eigenen Funktionen so schreiben wie er 
sie braucht und ist nicht darauf angewiesen, dass irgendetwas 
Vorgefertigtes schon passen wird.

http://www.mikrocontroller.net/articles/Drehgeber

Auch in BASCOM kann man im Grunde das gleiche machen. Niemand zwingt 
einen dazu, die vorgefertigten Module zu verwenden. Aber aus irgendeinem 
Grund, scheint dieser Ausweg viele abzuschrecken :-)

(Per Google keinen Ersatz für Encode gefunden?)

von gast2345 (Gast)


Lesenswert?

Als Quick'n'dirty-Übergangslösung kannst Du den Aufruf von Encode auch 
in einen Timer-Interrupt auslagern, der alle paar Milisekunden 
aufgerufen wird.

Je nachdem, wie deine lange deine LCD-Routinen brauchen, kannst Du damit 
die Abtastrate deutlich erhöhen. Achte dann aber darauf, dass die 
unterfunktionen "RECHTS" und "LINKS" nicht allzu kompliziert werden, 
sonst blockiert dir die ständige Encoder-Abfrage das Hauptprogramm!

von kime (Gast)


Lesenswert?

Zitat:

Als Quick'n'dirty-Übergangslösung kannst Du den Aufruf von Encode auch
in einen Timer-Interrupt auslagern, der alle paar Milisekunden
aufgerufen wird.

Zitat:

Das hört sich doch ganz gut an. Bin Bascom Neuling und habe mir eben 
bischen was zu Interrupt Timern duchgelesen.

Welchen Timer würdest du mir beim Atmega8 empfehlen zBsp Timer1? und 
welchen Prescaler damit das ganze nicht zu schnell läuft ?

von screwdriver (Gast)


Lesenswert?

Falk Brunner schrieb:
> Hehe, erwischt. In dem Fall schon mit RC-Filter, aber RICHTIG! Einfach
> einen Pull-Up und C-Gegen Masse ist IMO NICHT richtig, weil der
> Schalter/Taster dann immer den geladenen C kurzschliest, das brutzelt
> auf Dauer die Kontakte. Richtig ist es wie im Artikel Entprellung.

Ich hatte da schon einen RC-Tiefpass im Sinn. Aber es ist schon lustig, 
das die Encoder-Hersteller Selbstmord-Schaltungen für ihre eigenen 
Bauteile veröffentlichen. Nun ja, sie leben ja davon.

gast2345 schrieb:
> Als Quick'n'dirty-Übergangslösung kannst Du den Aufruf von Encode auch
> in einen Timer-Interrupt auslagern, der alle paar Milisekunden
> aufgerufen wird.

Das ist dann aber auch nur die halbe Miete. Der Encoder zählt, wie oben 
bereits erwähnt wurde, zwei Signalwechsel pro Rastung, so dass der 
Zählwert des Encoders noch zu halbieren ist. Und hier lauert die nächste 
Falle. Wenn man da einfach rechts schiebt bzw. halbiert, kann schon mal 
ein Zwischenschritt unter den Tisch fallen. Zum Glück weiss hier das WWW 
auch Rat.

mfg
screwdriver

von Andy H. (vinculum) Benutzerseite


Lesenswert?

>Das ist dann aber auch nur die halbe Miete. Der Encoder zählt, wie oben
>bereits erwähnt wurde, zwei Signalwechsel pro Rastung, so dass der
>Zählwert des Encoders noch zu halbieren ist. Und hier lauert die nächste
>Falle. Wenn man da einfach rechts schiebt bzw. halbiert, kann schon mal
>ein Zwischenschritt unter den Tisch fallen. Zum Glück weiss hier das WWW
>auch Rat.

Ich habe vor einiger Zeit auch versucht eine allgemeingültige 
Hard-/Software für Drehgeber von Alps zu entwickeln. Dabei habe ich 
unterschiedliche Typen, aber auch mehrere Exemplare derselben Typen hier 
gehabt. Das Ende vom Lied war, dass sich ALLE sehr unterschiedlich 
verhalten haben.

So ist im Datenblatt mal eine Phase während der Rastung gar nicht 
definiert (so verhalten die sich dann auch), mal ist es eine definierte 
0/1. Dann gibt es welche, die haben zwei komplette Signalwechsel, andere 
einen Signalwechsel zwischen 2 Rastungen. Das auch bei derselben 
Partnummer!

Grausam, ich habe dann einfach aufgegeben.

von Falk B. (falk)


Lesenswert?

Scheint das die Chinesen doch nicht alles so superdoll und billig 
kopieren können, nicht mal popelige Drehgeber. ;-)

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.