ich bin neu auf dem Gebiet Microcontroller, habe jedoch eine abgeschlossene Berufsausbildung als Elektroniker für Automatisierungstechnik und bin Momentan auf einer Technikerschule um mich weiter zu bilden.
Ich bastle momentan ein wenig mit einem UNO Board und versuche seit gestern einen Drehgeber auszuwerten.
Zu den Fakten:
Drehgeber --> 500 Pulse/Umdrehung
Motor --> 1300 1/min
Problem:
Drehe ich den Drehgeber von Hand genau um 360° bekomme ich exakt 500 Pulse. Sobald ich meinen Motor anhänge verschluckt er sich.
Daraus ergeben sich auch die Fragen:
Wie hoch ist die mögliche Eingangsrequenz der Eingänge des Arduino Uno Boards?
Ich zähle die Impulse und gebe sie per Serial auf den Rechner weiter. (115200)
Ist nun die Frequenz am Eingang zu hoch oder verschluckt er sich erst bei der Übertragung.
Die serielle Schnittstelle bremst den Controller aus.
Ca 11kHz müßten kein Problem für den Arduino sein. Das Problem liegt in Deinem Code.
Poste mal den Kode.
Da die Interruptroutine nur bei der fallenden Flanke von pin1 angesprungen wird hat diese Kontrolle wenig Sinn
Ich nehme mal an, daß der Motor in beide Richtungen drehen kann.
anstatt:
if (digitalRead(pin1) == digitalRead(pin2))
genügt:
if (digitalRead(pin2))
Außerdem würde ich nicht 2 Variablen für die Drehrichtung verwenden sondern nur eine; zB: 1 rechtsdrehend, 0 linksdrehend
dann vereinfacht sich alles auf:
habe es gerade ausprobiert.
Sieht gut aus.
Ich übergebe jetzt nur noch jeden 500sten Puls an den Rechner. Also pro Umdrehung einen. Dann komme ich relativ genau hin!
Davon abgesehen gehört vor die Variablen die in der ISR gesetzt werden bei der Deklaration ein "volatile". Ansonsten kann es unerwartet passieren, daß der Compiler Zugriffe auf die Variablen wegoptimiert. Das führt dann in der Regel zu langen verwirrenden Fehlersuchen.
Auch wenn ich noch weitere Eingänge auslesen und zum Beispiel einen Analogausgang (um den Moto selbst an zu steuern) verwende?
Ja er muss in beide RIchtigen drehen können.
Gleichstrommotor wird mittels PWM und H Brücke geregelt
Drehgeber gibt 500 Impule/Umdrehung
Gleichstrommotor bringt bei 24V 3000 1/min
Gebe ich der Regelung einen possitiven Sollwert funktioniert alles einwand frei.
Gebe ich der Regelung einen negativen Sollwert (Motor dreht in die andere Richtung) rasst der Motor leider los ohne die Pulse auszuwerten.
Mein bisheriges vorgehen:
Umdrehen der Drehgebereingänge
Hat zur Folge dass das ganze nun gerade umgekeht funktioniert. Also mit nagativen Sollwert ist alles ok, mit possitiven rasst der Motor
Flanken mittels Osszi beobachtet
Die Pulse kommen beide sauber, auch bei hoher Drehzahl
Verminderung der Spannung
Fällt die Versorgungsspannung des DC-Motors unter 20V funktioniert es.
Nun woran kann es liegen, meine erste Vermutung, die Frequenz an den Eingängen, die wird jedoch mit dem Versuch des Umdrehen der Drehgebereingänge wiederlegt. Momentan stehe ich ein wenig auf dem Schlauch.
Anbei noch mal den Code zu Auswertung der Impulse vom Drehgeber:
Das ist die Interruptroutine durch eine Flanke an Phase 1 des Drehgebers aufgerufen wird. Es könnte sein daß die Anweisung "counter --;" zuviel Zeit in Anspruch nimmt und die 2. Phase bereits wieder Status geändert hat bevor Du deren Zusatand in "counter += 2*digitalRead(pin2);" ausliest.
Bei 20V läuft der Motor dann langsam genug, daß es nicht passiert.
Einen Integer runterzuzählen kostet maximal 2-3 Takte. Bei 16 Mhz sollte man davon so gut wie nichts merken. digitalRead hingegen ist laaaaannnnngggsssaaaaaammmm. Wenn das wirklich unter Verdacht steht würde ich vorschlagen die Ports direkt auszulesen. Im Playground steht wie: Arduino Reference - Arduino Reference.
Und nur zur Sicherheit: ist der counter jetzt "VOLATILE" deklariert oder fehlt das noch? Zeig uns doch bitte mal das komplette Programm.
Ich denke wenn man auszüge aus dem Sketch hier verwendet:
Und die Funktion read_encoder anpasst an die Pins die man verwendet und die Funktion über einen Interrupt ausführt könnte das alles um einiges schneller werden http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino