if ((encoder0PinALast == LOW) && (current == HIGH))
23
{
24
if (digitalRead(encoder0PinB) == HIGH)
25
{
26
encoder0Pos++;
27
if(encoder0Pos == 100) { encoder0Pos = 0; }
28
}
29
else
30
{
31
encoder0Pos--;
32
if(encoder0Pos == -1) { encoder0Pos = 99; }
33
}
34
Serial.println (encoder0Pos);
35
}
36
encoder0PinALast = current;
37
}
Den Wert encoder0Pos zu erhöhen klappt auch, er wird erhöht, nachdem der
Encoder eingerastet ist.
Den Wert encoder0Pos zu erniedrigen klapp nicht sauber, da der Arduino
schon vor dem Einrasten zählt.
So kommt es durch schnelleres Drehen zu anderen Werten, wie beim
langsamen Drehen.
Der Encoder hat neben A und B auch noch neg. A und neg. B Ausgänge.
Wie kann ich (mit diesen) das Problem umgehen?
Oder gibt es eine andere Lösung?
Danke für eure Hilfe
Peter schrieb:> if ((encoder0PinALast == LOW) && (current == HIGH))
Und wo wird der umgekehrte Fall behandelt?
Die Auswertung von Inkrementalgebern wurde hier im Forum doch schon oft
genug und leidenschaftlich diskutiert.
Peter schrieb:
>Den Wert encoder0Pos zu erniedrigen klapp nicht sauber, da der Arduino>schon vor dem Einrasten zählt.
Das Einrasten hat nichts mit dem Zählen oder den Kontakten
zu tun, daß ist eine föllig unabhängige mechanische Sache.
Der Fehler liegt woanders, vielleicht in deinem Programm.
>Der Encoder hat neben A und B auch noch neg. A und neg. B Ausgänge.
Was hat er überhaupt für Kontakte? Sind das Mechanische Kontakte,
oder ist da Elektronik drinn?
Wenn das zwei mechanische Umschaltekontakte sind, kann
man damit mit RS-Flipflops prima Kontaktentprellschaltungen
aufbauen, die 100% funktionieren.
Dein Algorithmus für den Encoder funktioniert nicht. Kannst ja mal
folgendes ausprobieren:
int drehencodertask(int A,int B)
{
static int enc_last=0,enc_delta=0;
char i = 0;
if (A) i = 1;
if (B) i ^= 3;
i -= enc_last;
if (i & 1)
{
enc_last += i;
enc_delta += (i & 2) - 1;
}
return enc_delta;
}
Bei meinem Drehencoder (mechanisch) ändert sich enc_delta von Rast zu
Rast Stellung jeweils um 4. Das kann bei Dir anders sein. Ergebnis würde
mich interessieren.
Bei Dir einfach in loop() folgende Zeile:
Serial.println
(drehencodertask(digitalRead(encoder0PinA),digitalRead(encoder0PinB));
Martin B. schrieb:> Bei meinem Drehencoder (mechanisch) ändert sich enc_delta von Rast zu> Rast Stellung jeweils um 4. Das kann bei Dir anders sein. Ergebnis würde> mich interessieren.
Ist bei mir genauso.
Peter schrieb:> Ist bei mir genauso.
Das ging ja schnell. Danke für den Test.
Solltest Du verwenden können, wenn Du enc_delta um 2 shiftest. Ich
initialisiere Enc_deta mit 2, weil der Encoder bei manchen
Raststellungen die Kontakte nicht sauber stehen. Dann gibts beim shiften
weniger Fehler.
P.S.
Der Code ist schwer verständlich, weil optimiert. Nur eine if Abfrage!
Peter schrieb:> Martin B. schrieb:>> Solltest Du verwenden können, wenn Du enc_delta um 2 shiftest.>> Wie genau mache ich das? :D
Ups, ganz am Anfang? Mit dem Shiftoperator.
encoder0Pos = enc_delta >> 2;
static int enc_last=0,enc_delta=2; //vorher enc_delta=0
20
char i = 0;
21
encoder0Pos = enc_delta >> 2;
22
23
if (A) i = 1;
24
if (B) i ^= 3;
25
i -= enc_last;
26
if (i & 1)
27
{
28
enc_last += i;
29
enc_delta += (i & 2) - 1;
30
}
31
return enc_delta;
32
}
Wo ist "ganz am Anfang", außerhalb von int drehencodertask(int A,int B)
geht es ja nicht oder doch?
"Ich initialisiere Enc_deta mit 2", also static int
enc_last=0,enc_delta=2;?
So, neue Erkenntnis, ich habe den folgenden Code und die Libary dazu
verwendet.
1
/* Encoder Library - TwoKnobs Example
2
* http://www.pjrc.com/teensy/td_libs_Encoder.html
3
*
4
* This example code is in the public domain.
5
*/
6
7
#include <Encoder.h>
8
9
// Change these pin numbers to the pins connected to your encoder.
10
// Best Performance: both pins have interrupt capability
11
// Good Performance: only the first pin has interrupt capability
12
// Low Performance: neither pin has interrupt capability
13
Encoder knobLeft(2,3);
14
15
void setup()
16
{
17
Serial.begin(9600);
18
Serial.println("Encoder Test:");
19
}
20
21
long positionLeft = -999;
22
23
void loop() {
24
long newLeft;
25
newLeft = knobLeft.read();
26
if (newLeft != positionLeft)
27
{
28
Serial.print("Left = ");
29
Serial.print(newLeft);
30
Serial.println();
31
positionLeft = newLeft;
32
}
33
// if a character is sent from the serial monitor,
34
// reset both back to zero.
35
if (Serial.available())
36
{
37
Serial.read();
38
Serial.println("Reset knobs to zero");
39
knobLeft.write(0);
40
}
41
}
Wenn ich mal schneller und mal langsamer drehe, habe ich wieder eine
Differenz von 4, mal von 20, mal von 60. Je nachdem wie oft ich drehe.
Verwende ich nun aber die neg. Kontakte also A Strich und B Strich, kann
ich 3x, 10x oder auch 20x in unterschiedlichen Geschwindigkeiten drehen,
stelle ich den Encoder dann wieder auf Null (Skala), steht im
SerialMonitor auch wirklich 0...
Ist also ein Hardwaredefekt/-problem.
Dennoch würde mich das mit dem Shiftoperator interessieren.
Peter schrieb:> Wenn ich mal schneller und mal langsamer drehe, habe ich wieder eine> Differenz von 4, mal von 20, mal von 60. Je nachdem wie oft ich drehe.>> Verwende ich nun aber die neg. Kontakte also A Strich und B Strich, kann> ich 3x, 10x oder auch 20x in unterschiedlichen Geschwindigkeiten drehen,> stelle ich den Encoder dann wieder auf Null (Skala), steht im> SerialMonitor auch wirklich 0...>> Ist also ein Hardwaredefekt/-problem.>> Dennoch würde mich das mit dem Shiftoperator interessieren.
Irgendwie hast Du doch jetzt eine Lösung. Verwende A' und B'
Die Ausgänge des Encoders müssen halt zum Decoderalgorithmus passen. Da
muss man manchmal einfach spielen oder probieren.
Du bekommst jetzt immer Vielfache von 4, weil der Encoder das halt so
macht. Von Rast zu Raststellung ändern A,B halt viermal ihren Zustand.
Damit Du 1,2,3,4.... rausbekommst, musst Du halt einfach durch 4 teilen
oder eben um 2 (nach rechts) shiften.
Um 2 (nach rechts) shiften teilt für positive Zahlen durch 4. Das musst
Du Dir mal in einem Grundlagenbuch "C lernen" mal angucken. Es gibt
einen kleinen Unterschied zwischen shiften und Teilen für negative
Zahlen.
Dreh mal den Encoder von der Nullstellung nach links. Dann müsstest Du
negative Zahlen bekommen. (-4,-8,-12 . . .)