Problem mit Drehencoderbefehl in bascom

fofi1

Mitglied
09. Jan. 2010
116
1
18
Sprachen
Hallo,

ich versuche seit ner knappen Stunde rauszufinden warum der encoderbefehl in Bascom nicht funktioniert.

Also zum Problem:
Der Encoder hängt am Atmega8 mit A und B an Portd.2 und Portd.3 , also die Interruptpins. Alle Portc werden als Ausgänge verwendet (7 Segment) .

So jetzt schreibe ich in Bascom den Encoderbefehl und bekomme einen Haufen Fehlermeldungen. Also hab ich mal einfach alles systematisch rausgestrichen bis ich rausfand dass er die Deklarierung des Portc nicht mag. Kann ich das nicht umgehen? Ich hab schon alles fertig gelötet und will jetzt nicht den kompletten portc freiräumen:(:eek: . Ausserdem scheint er mir die Variable A und das B übel zu nehmen:mad:

Hier mal das Stück des Codes das ich meine:
Code:
$regfile = "m8def.dat"
$crystal = 8000000


'##############################################################################
'Einstellen der Segmentausgänge
'##############################################################################

A Alias Portc.5                                   'Hier sitzt der Wurm (Portc.x mag er nicht)
B Alias Portc.4
C Alias Portc.3
D Alias Portc.2
E Alias Portc.1
F Alias Portb.1
G Alias Portb.0

T1 Alias Portb.0
T2 Alias Portd.7



Config A = Output                                                'Hier ist Problem No.2
Config B = Output
Config C = Output
Config D = Output
Config E = Output
Config F = Output
Config G = Output
Config T1 = Output
Config T2 = Output

'##############################################################################
'Einstellen der Eingänge
'##############################################################################
Config Pind.2 = Input                                       'Encodereingänge
Config Pind.3 = Input
Config Pind.4 = Input                                       'Encodertaster

Portd.2 = 1
Portd.3 = 1

'###############################################################################
'Variabeln
'###############################################################################
Dim L_sekunden As Byte                                      'Ausgabewerte
Dim H_sekunden As Byte
Dim L_minuten As Byte
Dim H_minuten As Byte
Dim L_stunden As Byte
Dim H_stunden As Byte
Dim Temp_ziffer As Byte
Dim Ausgabe As Byte

Dim Stunden As Byte                                         'Eingestellte Werte
Dim Minuten As Byte
Dim Sekunden As Byte
Dim E As Byte

'##############################################################################
'Timer (wurden entfernt)
'##############################################################################


Do


E = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1)

Wait 1
Loop



Ps: Das ganze sollte ein Ostergeschenk werden, aber langsam sehe ich schwarz:p

Mfg,
Flo
 
Hallo Flo,
E ist als Alias auf PortC.1 und als Byte dimensioniert. Nenne die Variablen besser um.
Dann musst du noch die Label Links und Rechts angeben.

HBA
 
Hallo HBA,

(danke für die schnelle Rückmeldung. Ich hab es jetzt umgeändert. Jetzt funkioniert eigentlich alles, nur mag er A und B in der Portdeklaration noch nicht annehmen.

Zitat: Unknown Config Parameter [A]

Benutzt der Encoder Befehl vllt nebenbei die Variablen A und B?)


Schnell Vergessen :D . Hab versehentlich die falsche Variable geändert. Jetzt geht alles . TOP

Mfg,
Flo
 
Morgen,

Ich muss das Thema nochmal aufwärmen, da ich nen tollen encoder gekauft habe der einfach nur Schmarrn macht. Testcode ist dieser:
Code:
$regfile = "attiny2313.dat"
$crystal = 8000000
$baud = 19200

'I/Os
Config Pind.4 = Input                                       'A
Config Pind.5 = Input                                       'B
Portd.4 = 1
Portd.5 = 1
Config Pind.3 = Input                                       'Taster
Portd.3 = 1


'Variablen
Dim E As Byte
Dim Enc As Word

'Startbedingungen
Enc = 0



Do

E = Encoder(pind.4 , Pind.5 , Rauf , Runter , 1)            'Wartend!

Print "enc" ; Enc

Waitms 100
Loop


Rauf:
Enc = Enc + 5
Print "Rauf"
Return

Runter:
Enc = Enc - 5
Print "Runter"
Return

End

Jetzt passiert das:
Code:
Rauf<CR><LF>
enc0<CR><LF>
Runter<CR><LF>
enc65531<CR><LF>
Rauf<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>
Rauf<CR><LF>
enc5<CR><LF>
Runter<CR><LF>
enc0<CR><LF>

Ich frage mich echt: Warum nur springt der Encoder wild hin und her wenn ich ihn nur nach rechts drehe:rolleyes:. Egal was ich mache es wird nur schlimmer. Hat jemand von euch den Encoder schon mal zum laufen gebracht?

Mfg,
Flo
 
Hallo Flo,

Ich muss das Thema nochmal aufwärmen, da ich nen tollen encoder gekauft habe der einfach nur Schmarrn macht.
...
...
Ich frage mich echt: Warum nur springt der Encoder wild hin und her wenn ich ihn nur nach rechts drehe:rolleyes:. Egal was ich mache es wird nur schlimmer. Hat jemand von euch den Encoder schon mal zum laufen gebracht?
das Ding läuft bei mir unter .... Assembler ;) mit ner selbst gebauten Routine :cool:

Also funktionieren tut das Teil. Ich hab mir damals vor den Bascom-Versuchen in Assembler ne eigene Routine gebaut die auch recht gut funktioniert. Wenn du die ansehen willst dann brauchst du nur im Projekt-Bereich nach nem "Daddelboard mit ATmega32" suchen.Ist schon etwas her.

Aber ich tippe mal das du es lieber in Bascom zum laufen bekommen willst. Da hab ich aber leider noch nichts mit gemacht.

Ich hab gemerkt das die Drehgeber mit mechanischen Kontakten nach einiger Zeit von den Kontakteigenschaften schlecher werden. Die prellen dann anscheined stärker oder was weiß ich. Es kommt mir so vor. Ob was dran ist weiß ich nicht. Aus dem Grund hab ich mir mal 2 optische besorgt (bei Reichelt unter Drehschalter zu finden). Außerdem gibt es auch Schaltungen um Schrittmotoren als Drehgeber zu mißbrauchen. Da hätte man dann 100-200 Schritte pro Umdrehung und keinen Verschleiß :cool:

Gruß
Dino
 
ENDLICH! Dino du hattest recht, das Ding läuft. Nur dass es genau das gleiche Problem verursacht wie die Panasonic Encoder. Im Roboternetz wiki findet sich eine nette Sammlung von Codeschnipseln aus verschiedensten Foren wo das Problem umgangen wurde.

Optische Drehencoder sind natürlich Top, aber sie kosten auch ein bisschen Kleingeld :) . Das mit den Schrittmotoren ist ne gute Idee. Da hätte ich noch eine ganze Schachtel von.

Mfg,
FLo
 
Hi Flo,

Optische Drehencoder sind natürlich Top, aber sie kosten auch ein bisschen Kleingeld :) . Das mit den Schrittmotoren ist ne gute Idee. Da hätte ich noch eine ganze Schachtel von.
optische Drehencoder liegen bei Reichelt glaube ich bei etwa 10,-eur. Die Schrittmotoren müsen glaube ich bipolare Typen sein. Such mal etwas im Internet. Da sollte was zu finden sein. Notfalls durchstöber ich mal meine Platten.

Bei Mikrocontroller.net (glaube ich) steht auch drin das die Routine für Drehencoder bei Bascom recht "einfach" umgesetzt ist und darum wohl teilweise mal Probleme machen könnte.

Gruß
Dino
 
Da die Bascom Encoder Funktion weder einen Timer noch einen ext. Int-Eingang erfordert, ist das eigentlich reine Glücksache, ob in dem Moment der Abfrage gerade der Pegelwechsel kommt oder nicht.
Ich hatte mir daher auch eine eigene Routine gemacht. Bei jedem Pegelwechsel an Int0 in die ISR springen und dort nur eine Variable rauf oder runterzählen, je nachdem welchen Pegel der andere Eingang hat. Da geht einem kein Klick verloren.

Grüße

Sebastian
 
Hallo Flo!

Wenn du mit BASCOM einen Drehencoder auswerten möchtest, dann solltest du auch die Variable "E" (in deinem Programmcode) mit auswerten.
Danach funtioniert der Encoder auch zuverlässiger! :wink:


Beispiel:
Code:
'Encoder-Sub----------------------------------------
Rauf:
If E = 0 Then Incr Enc
Return

'Encoder-Sub----------------------------------------
Runter:
If E = 0 Then Decr Enc
Return


Auf diese Weise sollte das "Gezappel" ein Ende haben und die Variable "Enc" vernünftig hoch bzw. runter gezählt werden.

Grüße,
Cassio
 
Ich hohl das mal aus der Versenkung. Eigentlich ist die Frage ganz leicht, da aber meine Assemblerkenntnisse schon lange weg sind muss ich nachfragen.

Mit dem schönen Code hier (eigentlich für Panasonic Drehencoder) habe ich damals die Encoder ausgewertet. Ich frage mich nur im nachhinein warum ichs nicht bemerkt habe, dass er gleich um 2 Werte springt ;) .

Code:
'*******************************************************************************
'***   Testprogramm für POLLIN Dreh-Encoder PANASONIC EVEQDBRL416B           ***
'***   Best.Nr. 240 313                                                      ***
'*******************************************************************************
'***   Algorithmus: BASCOM ENCODER-Befehl mit Anpassungsroutine              ***
'*******************************************************************************
'***   Author: Screwdriver                                                   ***
'***   Datum:  29.08.2009                                                    ***
'*******************************************************************************

'*******************************************************************************
'***   Konfiguration                                                         ***
'*******************************************************************************
'AVR
$regfile = "m16def.dat"
$crystal = 8e6
$baud = 9600

'System-Timer für periodische Encoder-Abfrage
Config Timer0 = Timer , Prescale = 256
On Timer0 Isr_timer0
Enable Timer0
Const Timer0_reload = 224                                   'Wert für 1ms

'*******************************************************************************
'***   Variablen                                                             ***
'*******************************************************************************
Dim Rotary0 As Byte                                         'Phasenzustand des Drehencoders
Dim Rotary1 As Byte                                         'Zähler der Phasenwechsel
Dim Rotary2 As Byte                                         'Hilfsvariable
Dim Rotary As Byte                                          'Encoder-Wert

Dim Rotary_last As Byte                                     'Letzter Encoder-Wert (nur für Demo)

'*******************************************************************************
'***   Deklaration Unterprogramme                                            ***
'*******************************************************************************
Declare Sub Encoder2()                                      'Routine zur Anpassung des ENCODER-Befehls

'*******************************************************************************
'***   HAUPTPROGRAMM                                                         ***
'*******************************************************************************
Enable Interrupts

Do
   Call Encoder2()                                          'Wird zyklisch im Hauptprogramm aufgerufen
   If Rotary_last <> Rotary Then                            'Encoder gedreht?
      Rotary_last = Rotary                                  'Neue Stellung merken
      Print Rotary                                          'und Encoder-Wert ausgeben
   End If
Loop
End

'*******************************************************************************
'***   ISR_TIMER0                                                            ***
'***   Periodische Auswertung des Dreh-Encoders                              ***
'*******************************************************************************
Isr_timer0:
   Timer0 = Timer0_reload
   Rotary0 = Encoder(pinc.0 , Pinc.1 , Links , Rechts , 0)
Return

'*******************************************************************************
'***   Unterprogramme                                                        ***
'*******************************************************************************
Rechts:                                                     'Bei Rechtsdrehung
   Rotary1 = Rotary1 + 1                                    'Zählvariable Phasenwechsel erhöhen
Return

Links:                                                      'Bei Linksdrehung
   Rotary1 = Rotary1 - 1                                    'Zählvariable Phasenwechsel vermindern
Return

'*******************************************************************************
'***   Routine zur Anpassung des ENCODER-Befehls an POLLIN Drehencoder       ***
'*******************************************************************************
Sub Encoder2()
   Disable Interrupts
   Rotary2 = Rotary1                                'Zählvariable Phasenwechsel kopieren
   Rotary1 = Rotary1 And 1                          'Ggf.Phasenwechsel zwischen Rastungen stehenlassen
   push r0                                          'BASCOM kann kein arithmetisches Rechtsschieben
   lds r0,{rotary2}                                 'Aber der AVR kanns!
   asr r0                                           'ASR= Rechtsschieben mit Berücksichtigen
   sts {rotary2},r0                                 'des Vorzeichens, also teilen durch 2
   pop r0                                           'eines signed byte
   Rotary = Rotary + Rotary2                        'Encoder-Wert um Anzahl Rastungen erhöhen/vermindern
   Enable Interrupts
End Sub

Wie schaffe ich es dass er nicht mehr um 2 Werte springt sondern um 1? Die Lösung ist wohl im Sub Encoder2 drinnen, aber dank Null-Assembler komm ich nciht weiter. Ich fand den Code recht effizient also würde ich ihn ungern missen wollen.
 
Ich hohl das mal aus der Versenkung. Eigentlich ist die Frage ganz leicht, da aber meine Assemblerkenntnisse schon lange weg sind muss ich nachfragen.

Mit dem schönen Code hier (eigentlich für Panasonic Drehencoder) habe ich damals die Encoder ausgewertet. Ich frage mich nur im nachhinein warum ichs nicht bemerkt habe, dass er gleich um 2 Werte springt ;) .

Code:
'*******************************************************************************
'***   Testprogramm für POLLIN Dreh-Encoder PANASONIC EVEQDBRL416B           ***
'***   Best.Nr. 240 313                                                      ***
'*******************************************************************************
'***   Algorithmus: BASCOM ENCODER-Befehl mit Anpassungsroutine              ***
'*******************************************************************************
'***   Author: Screwdriver                                                   ***
'***   Datum:  29.08.2009                                                    ***
'*******************************************************************************

'*******************************************************************************
'***   Konfiguration                                                         ***
'*******************************************************************************
'AVR
$regfile = "m16def.dat"
$crystal = 8e6
$baud = 9600

'System-Timer für periodische Encoder-Abfrage
Config Timer0 = Timer , Prescale = 256
On Timer0 Isr_timer0
Enable Timer0
Const Timer0_reload = 224                                   'Wert für 1ms

'*******************************************************************************
'***   Variablen                                                             ***
'*******************************************************************************
Dim Rotary0 As Byte                                         'Phasenzustand des Drehencoders
Dim Rotary1 As Byte                                         'Zähler der Phasenwechsel
Dim Rotary2 As Byte                                         'Hilfsvariable
Dim Rotary As Byte                                          'Encoder-Wert

Dim Rotary_last As Byte                                     'Letzter Encoder-Wert (nur für Demo)

'*******************************************************************************
'***   Deklaration Unterprogramme                                            ***
'*******************************************************************************
Declare Sub Encoder2()                                      'Routine zur Anpassung des ENCODER-Befehls

'*******************************************************************************
'***   HAUPTPROGRAMM                                                         ***
'*******************************************************************************
Enable Interrupts

Do
   Call Encoder2()                                          'Wird zyklisch im Hauptprogramm aufgerufen
   If Rotary_last <> Rotary Then                            'Encoder gedreht?
      Rotary_last = Rotary                                  'Neue Stellung merken
      Print Rotary                                          'und Encoder-Wert ausgeben
   End If
Loop
End

'*******************************************************************************
'***   ISR_TIMER0                                                            ***
'***   Periodische Auswertung des Dreh-Encoders                              ***
'*******************************************************************************
Isr_timer0:
   Timer0 = Timer0_reload
   Rotary0 = Encoder(pinc.0 , Pinc.1 , Links , Rechts , 0)
Return

'*******************************************************************************
'***   Unterprogramme                                                        ***
'*******************************************************************************
Rechts:                                                     'Bei Rechtsdrehung
   Rotary1 = Rotary1 + 1                                    'Zählvariable Phasenwechsel erhöhen
Return

Links:                                                      'Bei Linksdrehung
   Rotary1 = Rotary1 - 1                                    'Zählvariable Phasenwechsel vermindern
Return

'*******************************************************************************
'***   Routine zur Anpassung des ENCODER-Befehls an POLLIN Drehencoder       ***
'*******************************************************************************
Sub Encoder2()
   Disable Interrupts
   Rotary2 = Rotary1                                'Zählvariable Phasenwechsel kopieren
   Rotary1 = Rotary1 And 1                          'Ggf.Phasenwechsel zwischen Rastungen stehenlassen
   push r0                                          'BASCOM kann kein arithmetisches Rechtsschieben
   lds r0,{rotary2}                                 'Aber der AVR kanns!
   asr r0                                           'ASR= Rechtsschieben mit Berücksichtigen
   sts {rotary2},r0                                 'des Vorzeichens, also teilen durch 2
   pop r0                                           'eines signed byte
   Rotary = Rotary + Rotary2                        'Encoder-Wert um Anzahl Rastungen erhöhen/vermindern
   Enable Interrupts
End Sub

Wie schaffe ich es dass er nicht mehr um 2 Werte springt sondern um 1? Die Lösung ist wohl im Sub Encoder2 drinnen, aber dank Null-Assembler komm ich nciht weiter. Ich fand den Code recht effizient also würde ich ihn ungern missen wollen.

Keiner? Ich les mich grade schon ne Stunde durch meine früheren Assembler-Aufzeichnungen aber werd noch ned schlau draus
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)