Überleg dir mal mit welchem Takt der Uno läuft. Dann hast du ein Gefühl für die Zeiten bzw. Taktraten
Werbung
Überleg dir mal mit welchem Takt der Uno läuft. Dann hast du ein Gefühl für die Zeiten bzw. Taktraten
Wie lang sind die Impulse? Ohne 3 Hardware-Interrupts wirds evtl. schwierig, die Impulse sicher zu detektieren (der UNO hat 2 Hardware-Interrupts). Ohne Hardware-Interrupts müssen die 3 Digital-Inputs schneller abgetastet werden, als die Impulse lang sind.
Was soll der Arduino mit den Drehzahl-Daten machen?
Hei,
2 Sensoren reichen mir eigendlich. Ich brauch die Drehrichtung und die ungefähre Geschwindigkeit.
Gruß
Hab noch mal nachgedacht: Ein Hardware-Interrupt reicht aus. Und 2 Sensoren.
Wenn Flanke an Sensor1 (per Hardware-Interrupt detektiert), wird Zustand an Sensor2 gemessen: Wenn High: Drehrichtung A, wenn Low: Drehrichtung -A.
Anzahl Impulse / Zeiteinheit ist Drehgeschwindigkeit.
So schafft der UNO das locker. Das Programmieren ist auch nicht schwer.
Vorausgesetzt das Signal der Sensoren sieht so aus.
Geändert von Sisor (04.09.2017 um 22:05 Uhr)
Moin Moin,
ich habe mal folgende Lib probiert: RotaryEncoder.h
Damit kann ich schon mal zuverlässig Vor und Zurück erkennen. Der Uno ist also schnell genug hab es nur scheiße programmiert....Code:#include <RotaryEncoder.h> // Setup a RoraryEncoder for pins A2 and A3: RotaryEncoder encoder(A2, A3); void setup() { Serial.begin(9600); Serial.println("SimplePollRotator example for the RotaryEncoder library."); // You may have to modify the next 2 lines if using other pins than A2 and A3 PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C. PCMSK1 |= (1 << PCINT10) | (1 << PCINT11); // This enables the interrupt for pin 2 and 3 of Port C. } // setup() // The Interrupt Service Routine for Pin Change Interrupt 1 // This routine will only be called on any signal change on A2 and A3: exactly where we need to check. ISR(PCINT1_vect) { encoder.tick(); // just call tick() to check the state. } long position = -999; void loop() { static int pos = 0; int newPos = encoder.getPosition(); if (pos != newPos) { if(newPos < position){ Serial.print("Vor"); }else{ Serial.print("Zurueck"); } position = newPos; Serial.println(); pos = newPos; if (newPos == 66) delay(6600); } // if } // loop () // The End
werde es weiter versuchen![]()
Hi, in dein Code hat noch Schwächen:
- Ein Motor kann auch stehen
- Überflüssige Variable: Position
- Die Zeilen 'if (newPos == 66) delay(6600);' sind sinnlos
- Test 'if(newPos < position) ...': Die Variable newPos läuft irgendwann über. Dann ist einmal newPos kleiner als pos -> Test liefert einmalig falsche Richtung.
Vorschlag:
Code:#include <RotaryEncoder.h> // Setup a RoraryEncoder for pins A2 and A3: RotaryEncoder encoder(A2, A3); enum {zurueck =-1, still, vor}; // Motorrichtung sign(int x) { return (x>0)-(x<0); } // Vorzeichen einer Zahl : -1, 0, +1 void setup() { Serial.begin(9600); Serial.println("SimplePollRotator example for the RotaryEncoder library."); // Interrupt für Encoder festlegen PCICR |= (1 << PCIE1); PCMSK1 |= (1 << PCINT10) | (1 << PCINT11); } // Interrupt Service Routine für Pin Change Interrupt 1 ISR(PCINT1_vect) { encoder.tick(); } void loop() { static int pos = 0; int newPos = encoder.getPosition(); int richtung = sign(newPos - pos); switch(richtung) { case zurueck: Serial.println("Zurueck!"); break; case still: Serial.println("Still!"); break; case vor: Serial.println("Vor!"); break; } Serial.println(); pos = newPos; } }
Lesezeichen