Hi,
Ich würde gerne 2 Drehgeber diesen Typs
(http://www.reichelt.de/Drehimpulsgeber/STEC11B03/3/index.html?&ACTION=3&LA=2&ARTICLE=73913&GROUPID=3714&artnr=STEC11B03)
an einem Pi 2 betreiben. Da ich aber nicht den Pi mit der Entprellung
nerven möchte, würde ich das gerne vorher realisieren.
Ich finde diese Lösung ganz sympathisch:
https://www.mikrocontroller.net/articles/Drehgeber#Dekoder_mit_diskreten_Logik-ICs.
Weiß jemand, wie schnell ich sowas takten sollte, dass auf der einen
Seite der Pi mithält und auf der anderen Seite nix verloren geht? Und wo
kriege ich einen Takt her? NE555 ist bisschen übertrieben, oder?
Oszillatoren finde ich aber nur mit >=1MHz und weiß nicht, ob das nicht
schon zu schnell ist. Außerdem müsste ich die eingebauten Taster dann
anders entprellen.
Die andere Möglichkeit, die mir so in den Sinn kommt, wäre, einen
ATtiny84 zur Auswertung zu nutzen, das ist allerdings Neuland für mich.
Kann man den Code von hier
(https://www.mikrocontroller.net/articles/Drehgeber#Solide_L.C3.B6sung:_Beispielcode_in_C)
so anpassen, dass ich quasi 6x Input habe (2x A, 2x B, 2x Taster) und 6x
Output? Wäre es da auch möglich, den Output so zu schalten, dass bei
einer Linksdrehung ein Pin flankt, bei einer Rechtsdrehung der andere?
Dann könnte ich mir die Auswertung des Gray Signals im Pi komplett
sparen. Wie gesagt, das mit dem ATtiny ist Neuland für mich und ich muss
auch gestehen, dass ich den Code oben noch nicht vollständig
nachvollziehen kann. Bin gerade dabei, im AVR Tutorial querzulesen.
Welche Lösung würdet ihr mir empfehlen?
Viele Grüße
raspi-user schrieb:> Dann könnte ich mir die Auswertung des Gray Signals im Pi komplett> sparen
edit: Dann könnte ich mir die Auswertung von 2 Pins für ein Signal
sparen und hätte einen Pin für Links und einen für Rechts am Pi
raspi-user schrieb:> Da ich aber nicht den Pi mit der Entprellung nerven möchte, würde
Was hast du an den von dir ausgesuchten Verfahren zur Erfassung von
Drehgebern nicht verstanden ?
Die haben kein Problem mit prellenden Kontakten oder vibrierenden
Wellen, die kann auch der rPi direkt entsprechend dem Algorithmus per
Timer Interrupt.
Hand-gedreht reichen schon mehr als 100Hz.
Ja, aber dann muss ich immer diese Schleife mitlaufen lassen und wenn
die Drehgeber vielleicht alle paar Stunden mal ein Signal ausgeben finde
ich, ist das viel verschwendete Rechenzeit. Außerdem geht das doch in
die Hose, wenn die CPU mal von anderen Prozessen stark ausgelastet wird,
oder?
Danke, werde ich auf jeden Fall mal ausprobieren.
Ich schätze, du hast den Code im Einsatz? Einfach direkt die Pins ohne
debounce (abgesehen von den 10ms von RPi.GPIO) angeschlossen? Und das
läuft zuverlässig?
Vermutlich wäre der scaler bei meinem Encoder dann 2, richtig? (15
Impulse, 30 Rastungen)
> Und das läuft zuverlässig?
Mehr oder weniger. Ab und zu wird ein Schritt vergessen. Kannst noch was
an den Debounce-Zeiten rumspielen. Hatte ich mal für mein Raspi-Radio im
Einsatz.
Für meine neuere Version des Radios habe ich dann einen ATmega als I2C
Slave eingebaut. Das hatte den Vorteil, dass er die ganze Bitschubserei
machen kann (LCD, Drehencoder, Taster, PWM LCD-Beleuchtung). Das läuft
schon besser; obwohl man dann wieder das Problem hat, dass der RASPI
kein I2C Clock-Stretching kann :-(
Aber du kannst meine Python-Lösung gern ausprobieren, kostet ja nix :-)
Für den Encoder
https://www.reichelt.de/Drehimpulsgeber/STEC12E08/3/index.html?&ACTION=3&LA=5000&GROUP=B29&GROUPID=3714&ARTICLE=73923&START=0&SORT=-rank&OFFSET=500
hatte ich den Teiler 4 genommen.
Hmm, habe gerade nochmal über den scaler nachgedacht, verstehe es aber
nicht so ganz, was der tun soll, bzw was du damit vorhattest. So, wie
ich das sehe, nullt der einfach in jedem Durchgang val. Falls dem
nämlich nicht so wäre, würde das Programm in der letzten Zeile den
Syntaxfehler erkennen ;-)
Wie gesagt, ich werds mal ausprobieren die Tage. Aber nochmal zu meiner
Frage von oben: Denkst du, es wäre machbar, einen ATtiny24/44/84 zu
spendieren, der die Auswertung macht und dann bei "Links" kurz HIGH auf
den einen Pin gibt und bei "Rechts" kurz HIGH auf einen anderen und
diese beiden Pins dann an den Pi anschließen? Dann könnte ich nämlich im
Pi einfach auf Flanken an diesen beiden Pins warten.
Oder denkst du, das wird eher schlecht mit dem Timing oder so?
raspi-user schrieb:> Ja, aber dann muss ich immer diese Schleife mitlaufen lassen und> wenn> die Drehgeber vielleicht alle paar Stunden mal ein Signal ausgeben finde> ich, ist das viel verschwendete Rechenzeit. Außerdem geht das doch in> die Hose, wenn die CPU mal von anderen Prozessen stark ausgelastet wird,> oder?
Alles eine Frage der Timer-Interrupt-Priorität.
Die muss so oder so höher sein als die Priorität dieser anderen
Prozesse, denn sonst würde das System ja nicht auf den Drehgeber
reagieren wenn diese Prozesse ihn (über)lasten. Egal ob die Drehgeber
direkt ausgewertet werden oder per SPI oder anderer Schnittstelle ein
extra Auswertechip angeschlossen wird, blöd wäre eine zu geringe
Priorität also in jeden Fall.
Es ist auch vollkommen egal, ob der rPi 0.1% seiner Rechenzeit dauerhaft
auf die Abfrage sich nicht-bewegender Drehgeber investiert, denn auch im
Höchstauslastungsfall muss er diese 0.1% Rechenleistung übrig haben. Er
hat sie also sowieso übrig, und übriges kann man nutzen, immer,
jederzeit.
Jens G. schrieb:> Für sowas wurden Interrupts erfunden, damit man nicht permanet und> sinnlos pollen muß ...
Oh nö, noch ein total Ahnungsloser.
Andreas R. schrieb:> Wenn Python eine Option ist
Das iat natürlich die schlechteste Lösung von allen, eine Skriptsprache
die nicht am Timer-Interrupt hängt und deren Priorität nicht angepasst
werden kann. Aber erstaunlich, wenn es damit immer noch funktioniert.
Andreas R. schrieb:> Ab und zu wird ein Schritt vergessen
Ok, funktioniert nicht, wird hier aber trotzdem als Lösung angepriesen.
Die üblichen Mistkonstruktionen also, hätte man schon daran sehen können
daß jemand meint, Drehgebereingänge "debouncen" zu müssen.
> Ok, funktioniert nicht, wird hier aber trotzdem als Lösung angepriesen.> Die üblichen Mistkonstruktionen also, hätte man schon daran sehen können> daß jemand meint, Drehgebereingänge "debouncen" zu müssen.
Ja nimm unbedingt meine Lösung alles andere ist Mist. Und ich bin total
sauer wenn du sie nicht nimmst. Ich bin nämlich der einzige der Ahnung
hat.
@laberkopp: Denkst du so?
Andreas R. schrieb:> Denkst du so?
Ich denke, daß ein Lösungsvorschlag, der "ab und zu wird ein Schritt
vergessen" nicht als Lösungsvorschlag taugt.
Sollte so was auch China kommen, wir hier gleich laut geschrieen, das
wäre Chinapfusch.
An dir sieht man aber: Deutsche Lösungen sind noch schlimmer, aber
arrogant behaupten Leute wie du, die Lösung wäre schon gut.
Nein, sie ist Pfusch und bleibt Pfusch, auch wenn du sie erfunden hast.
Andreas R. schrieb:> Ja nimm unbedingt meine Lösung alles andere ist Mist.
Nun, Drehgeber werden extra so gebaut, das man sie mit Auswertung
der Zustände eindeutig dekodieren kann. Lösungen, die auf Flanken
reagieren, sind eindeutig "Mist", da sie bei älteren Drehgebern
eben eindeutig nicht mehr zuverlässig funktionieren. Wenn man
sowieso per Rechner auswertet, sollte es auch keinen Unterschied
machen, ob man ein "richtiges" oder ein "falsches" Programm
verwendet. Das Wissen über die richtige Auswertung von Drehgebern
ist übrigens Jahrzehnte alt und keine "neue" Erfindung.
Leute nun lasst mal die Kirche im Dorf. Der TE kann doch selbst
entscheiden ob er den PI mal kurz per Steckbrett mit dem Encoder testet
oder nicht. Vielleicht reicht es für manche Anwendung wenn alle 30
Schritte einer vergessen wird. Natürlich kann man auch eine hoch.-priore
Anfrage-Task schreiben oder den Linux-Kernel anpassen oder ein
Echtzeit-Linux installieren. Nach oben sind da sicher keine Grenzen.
Ich habe mich grad mal ein bisschen durch den Code von PeDa gearbeitet
und es jetzt soweit nachvollzogen, indem ich einfach mal gerechnet hab
^^ Scheint alles zu stimmen. Nur eins irritiert mich: Warum wird in
encode_read2 und encode_read4 die Variable encode_delta nicht auf 0
zurück gesetzt nach dem Lesen? Es macht zwar keinen Unterschied, weil
der Rückgabewert eh geschoben wird, aber so fürs Verständnis... Gibts da
n Grund für?
Außerdem: Warum wird immer cli() aufgerufen? Was, wenn die Schleife in
der main() schneller ist, als der Timer? Dann wird der Timer Interrupt
doch nie ausgeführt, oder?
raspi-user schrieb:> ^^ Scheint alles zu stimmen. Nur eins irritiert mich: Warum wird in> encode_read2 und encode_read4 die Variable encode_delta nicht auf 0> zurück gesetzt nach dem Lesen? Es macht zwar keinen Unterschied, weil> der Rückgabewert eh geschoben wird, aber so fürs Verständnis... Gibts da> n Grund für?
Ich weiß es auch nicht. Wenn ich es aber wissen wollen würde, würde ich
das einfach ausprobieren. Warum tust du das nicht? Setz sie doch auf
Null und schau was passiert.