Hi,
Ich habe gerade versucht einen Drehimpulsgeber anzuschließen. Leider will das ganze noch nicht so richtig.
Ich benutze die rotaryencoder-library und den einfachsten testsketch dazu. Die Verkabelung habe ich aus dem
Datenblatt übernommen. Terminal A hängt an Pin2 und B an 3
Wenn ich jetzt an dem Schaft drehe wird die Richtung korrekt erkannt. Allerdings wird bei einer Rastung 3-5 Werte weitergezählt.
Jemand eine Idee, wie ich das hinbekomme, dass pro Rastung immer nur genau 1 Wert weitergezählt wird?
// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder myEnc(4, 5);
// avoid using pins with LEDs attached
Laut mitgelieferten Schaltbild sollte der Drehgeber mit einem RC-Glied entprellt werden. Hast Du die Schaltung so aufgebaut?
pylon will Dir sagen, daß Du das Objekt für die Bibliothek mit den Pins 4 und 5 initialisierst aber schreibst Du hättst den Encoder an pin 2 und 3 angeschlossen.
Du solltest die Seite Encoder Library, for Measuring Quadarature Encoded Position or Rotation Signals genauer durchlesen.
ich habe beides ausprobiert, 2 3 und 4 5, daran liegt es nicht, ich hatte nur vergessen wieder 2, 3 im sketch einzutragen.
Was hat es mit diesem Rc-Glied auf sich? In der Schaltung sehe ich 4 Widerstände und 2 Kondensatoren. Die sind auch alle mit den
Vorgesehenen Werten an ihrem Platz.
Beim Öffnen bzw Schließen eines Kontakts hüpfen die Kontakte mehrmals und schließen erst dann zuverlässig. Das nennt man prellen. Bei genügend schnellen Schaltungen (zB Interrupt) ergibt das ein mehrfaches Betätigen des Kontakts. Der Kontakt muß entprellt werden. Durch den Widerstand wird er Kondensator langsam aufgeladen und behält auch während es Prellens den Zustand bei, sodaß der Eingang nur eine Betätigung sieht.
ok Danke für die Info. Ich hab mal ein Bild von meiner Schaltung angehängt, vllt. sieht ja wer einen Fehler. Ich hab alle Kontakte durchgemessen
und keinen Fehler gefunden.
Ich sehe, daß die seitlichen Stromschienen nicht durchgängig über die ganze Länge sind. An der + Seite hast Du 3 Brücken hineingesteckt aber nicht auf der Masseseite. Könnte das das Problem sein, daß ein Kondensator nicht auf Masse ist?
ps: Die Schaltung müßte trotz gefälschten Arduino funktionieren (In der rechten oberen Ecke fehlt das "Made in Italy") .
Die Gnd-Schiene ist von unten verlötet, daher keine Drahtbrücken. Auf den Kondensatoren steht 103, das müssten die richtigen Werte sein oder?
Ich hab das Uno übrigens damals für 25€ über Amazon bestellt, ist natürlich blöde, wenn die mir ne Fälschung untergejubelt haben, aber bis jetzt
hat es tadellos funktioniert.
Ja, ich habe gesehen, daß Amazon auch solche Arduinos vertreibt. Normalerweise findet mann sie bei Ebay von Asiatischen Verkäufern um den halben Preis. Schau mal auf die Unterseite und vergleich mit diesem Bild. Bei Fälschungen fehlt das "Made in Italy" ganz oder ist durch "Designed in Italy" ersetzt. Die Landkarte Italiens fehlt oder ist stark verzerrt. Wenn beides zutrifft kannst Du ja mal bei Amazon reklamieren daß sie Dir eine Fälschung verkauft haben. (zur Sicherheit schick mir per PM ein Foto der Unterseite und ich bestätige Dir den Verdacht).
Fälschung heißt nicht umbedingt, daß er nicht funktioniert. Das heißt nur, daß ein Nachbau als Orginal-Arduino Verkauft wurde. Wenn er einen anderen Namen hätte, wäre er legitim.
Die Gnd-Schiene ist von unten verlötet, daher keine Drahtbrücken. Auf den Kondensatoren steht 103, das müssten die richtigen Werte sein oder?
Die Gnd-Schiene ist von unten verlötet, daher keine Drahtbrücken. Auf den Kondensatoren steht 103, das müssten die richtigen Werte sein oder?
Also müßte, soweit ich das aus der Ferne beurteilen kann, die Schaltung richtig sein. 103 ist der richtige Wert (10 * 10^3 pF).
Auf der Rückseite steht designed in italy. Ich werde mal gucken, ob ich die Rechnung noch habe und werde mich dann an Amazon wenden, ich hab ja schließlich ein originales Arduino bezahlt.
Ich habe grade nochmal alles neu verkabelt und einen anderen Impulsgeber ausprobiert mit dem gleichen Ergebnis. Wenn man die Kondensatoren rauszieht ändert sich nichts am Verhalten, mit 1uf Elektrolytkondensatoren wird mal richtig, mal garnicht und mal zu viel gezählt . Ich habe mehrere Quellen gefunden, wo genau die gleiche Schaltung verwendet wird nur bei mir will es ums Erbrechen nicht klappen.
Nach dem Datenblatt wird pro Umdrehung auf jedem Pin 24 Mal ein Puls ausgelöst. Mit Deiner Bibliothek solltest Du also pro Umdrehung 48 Einheiten hoch-/runtergezählt kriegen. Im Datenblatt steht aber auch, dass die Rasterung in 24 Schritten gemacht wird, somit werden pro Rastpunkt 2 Einheiten hochgezählt.
Hast Du die Möglichkeit, daran mal ein Oszilloskop anzuschliessen? Damit siehst Du, welche Pulse wann ankommen und kannst evtl. die externe Beschaltung entsprechend ändern.
ich bin immernoch keinen Schritt weiter mit den Verdammten Drehimpulsgebern, ich brauche aber zwingend einen für mein Projekt.
Als kleinen Versuch habe ich jetzt einfach mal an jeden Anschluss eine kleine Led gehängt. Und siehe da, bei einem Schritt leuchtet
jede Led einmal kurz auf. Je nachdem wierum ich drehe entweder die eine oder die andere zuerst. Manchmal bleibt die eine Led jedoch
nach einem Schritt an und geht dann erst nach dem nächsten wieder aus, jmd eine Idee, woran das liegen könnte?
Da ich inzwischen alle Libraries, die man im Internet so findet ausprobiert habe und keine richtig funktioniert, bleibt mir wohl nix anderes
übrig, als die Impulse per Hand auszulesen.
Ps: hat vllt. jemand eine Idee, wieso sich Ino-Dateien unter win7 weigern mit der arduinosoftware zu verlinken?
Nach dem Datenblatt darf ein Statuswechsel erst gezählt werden, wenn seit dem letzten mehr als 2ms vergangen sind. Der Encoder eignet sich somit nur für relativ langsame Drehbewegungen (< 1200 U/min), für eine Bedienung per Hand aber mehr als ausreichend.
Du solltest jetzt einfach im Code diesen Faktor noch einbauen, z.B.:
int val;
int encoder0PinA = 4;
int encoder0PinB = 5;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
uint32_t encoder0PinALastChange = 0;
int n = LOW;
void setup() {
pinMode (encoder0PinA,INPUT);
pinMode (encoder0PinB,INPUT);
Serial.begin (57600);
}
void loop() {
n = digitalRead(encoder0PinA);
if ((encoder0PinALast == LOW) && (n == HIGH) && (millis() - encoder0PinALastChange > 2)) {
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos--;
} else {
encoder0Pos++;
}
Serial.print (encoder0Pos);
Serial.print ("/");
encoder0PinALastChange = millis();
}
encoder0PinALast = n;
}
pylon du bist mein Held!! Der Impulsgeber zählt jetzt brav hoch und runter. Ich hätte meinen Code übrigens ganz ähnlich aufgebaut. Aber ob es
schlussendlich funktioniert hätte ist eine andere Sache. Daher ein riesen Danke von mir.
@ ernie-berni: Danke, dass du dich mit meinem Problem befasst hast, ich hatte nur den Vorschlag von Pylon als erstes gesehen und da er auf
Anhieb funktioniert, werde ich bei diesem bleiben.
Habe das Programm auch versucht auf meine bedürfnisse abzuändern.
brauche wenn der Encoder in + Richtung gedreht wird ein 50µs Impuls am Ausgang 11 und in - Richtung auch ein 50µs Impuls am Ausgang 12
UND
wenn der Encoder jetzt schneller dreht und 20 Einheiten macht soll der Pegel generell auf HIGH am Ausgang gehen und wenn er langsamer wird wieder einzelne Impulse machen
Habe die millis in micros getauscht und eine warteschleife rein gesetzt aber so richtig kommen die Impulse am Oszi nicht an. Ich vermute mal das delayMicroseconds passt da nicht so rein weil das stört bestimmt den Ablauf.
Habt ihr eine Idee wie man das lösen könnte. Wäre für jede Hilfe dankbar.
Gruss
Stefan
int val;
int encoder0PinA = 9;
int encoder0PinB = 10;
int encoderOUTA = 11;
int encoderOUTB = 12;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
uint32_t encoder0PinALastChange = 0;
int n = LOW;
void setup() {
pinMode (encoder0PinA,INPUT);
pinMode (encoder0PinB,INPUT);
pinMode (encoderOUTA,OUTPUT);
pinMode (encoderOUTB,OUTPUT);
Serial.begin (57600);
}
void loop() {
n = digitalRead(encoder0PinA);
if ((encoder0PinALast == LOW) && (n == HIGH) && (micros() - encoder0PinALastChange > 50)) {
if (digitalRead(encoder0PinB) == LOW) {
// encoder0Pos--;
digitalWrite(encoderOUTB, HIGH);
delayMicroseconds(50);
digitalWrite(encoderOUTB, LOW);
delayMicroseconds(50);
} else {
// encoder0Pos++;
digitalWrite(encoderOUTA, HIGH);
delayMicroseconds(50);
digitalWrite(encoderOUTA, LOW);
delayMicroseconds(50);
}
// Serial.print (encoder0Pos);
// Serial.println ("/");
encoder0PinALastChange = micros();
}
encoder0PinALast = n;
}