Drehimpulsgeber / BIN Ausbabe - Fehler beim Abwärtz Zählen

ich komme hier nicht weiter.

Ich Möchte mit einen Drehimpulsgeber eine 8 bit Binär Ausgabe erzeugen und je nach dem in welcher Richtung ich Drehe soll der Zähler auf oder Ab Zählen.

leider funktioniert es nur bedingt. Das BIN Aufzählen funktioniert. Allerdings nicht das BIN Abwärtz zählen
was wurde hier falsch gemacht?

int l[]={0,0,0,0,0,0,0,0},T=8,a,p;
int val; 
const int encoder0PinA = A0;
 const int encoder0PinB = A1;
 int encoder0Pos = 0;
 int encoder0PinALast = LOW;
 uint32_t encoder0PinALastChange = 0;
 int n = LOW;

 void setup() { 
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);

 } 

 void loop() { 
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH) && (millis() - encoder0PinALastChange > 2)) {
    if (digitalRead(encoder0PinB) == LOW)  {
 
  
 
      
    p=0;
p=digitalRead(encoder0PinA) ;
while(digitalRead(encoder0PinA)!=0)
{
  
}
delay(1);
a=T-1;
while(a>=0&&p==1)
{
  if(l[a]==1)
  {
    l[a]=0;
    a--;
  }
  else
  {
    l[a]=1;
    p=0;
  }
}
p=digitalRead(encoder0PinB) ;
while(digitalRead(encoder0PinB)!=0)
{
  
}
delay(1);
a=T-1;
while(a>=0&&p==1)
{
  if(l[a]==0)
  {
    l[a]=1;
    a--;
  }
  else
  {
    l[a]=0;
    p=0;
  }
}
a=T-1;
for(int c=0;c<T;c++)
{
    if(l[c]==1)
    digitalWrite(T-c+1,HIGH);
  else
    digitalWrite(T-c+1,LOW);
  a--;
}
}
}
}


Gruß Markus

Etwas mehr Information wäre nötig. Lies mal das hier:
How to get the best out of this forum - Using Arduino / Installation & Troubleshooting - Arduino Forum
Und kommentiere bitte Deinen Code. Das macht es für die Leute, die Dir helfen wollen, leichter zu verstehen, wie es Deiner Meinung nach funktionieren soll.

Probiere mal diese Variante, die bei mir gut funktioniert:

// Quelle: https://github.com/pinae/Knob-Louder
// Beschreibung: c't 18/2020
// Hardware grüne und schwarze Platine nach GND schaltend
// https://forum.arduino.cc/index.php?topic=701098.0
const byte ENCODER_A_PIN = A0;
const byte ENCODER_B_PIN = A1;

void setup() {
  Serial.begin(115200);
  Serial.println("\nStart");
  pinMode(ENCODER_A_PIN, INPUT);
  pinMode(ENCODER_B_PIN, INPUT);
}

void loop() {
  static uint8_t wert = 127;
  int8_t state = 0;
  rotaryEncoder(state);
  if (state == -1) {
    if (wert > 0) wert--;
    Serial.print("<-- \t");
    ausgabe (wert);
    Serial.print('\t');
    Serial.print(wert);
    Serial.println();
  }
  if (state == 1) {
    if (wert < 255) wert++;
    Serial.print(" --> \t");
    ausgabe (wert);
    Serial.print('\t');
    Serial.print(wert);
    Serial.println();
  }
}

void ausgabe(uint8_t w) {
  for (int8_t p = 7; p >= 0; p--) {
    if (w & (1 << p)) {
      Serial.print('1');
    } else {
      Serial.print('0');
    }
  }
}

void rotaryEncoder(int8_t &delta) {
  delta = 0;
  enum {STATE_LOCKED, STATE_TURN_RIGHT_START, STATE_TURN_RIGHT_MIDDLE, STATE_TURN_RIGHT_END, STATE_TURN_LEFT_START, STATE_TURN_LEFT_MIDDLE, STATE_TURN_LEFT_END, STATE_UNDECIDED};
  static uint8_t encoderState = STATE_LOCKED;
  bool a = !digitalRead(ENCODER_A_PIN);
  bool b = !digitalRead(ENCODER_B_PIN);
  switch (encoderState) {
    case STATE_LOCKED:
      if (a && b) {
        encoderState = STATE_UNDECIDED;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_RIGHT_START:
      if (a && b) {
        encoderState = STATE_TURN_RIGHT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_RIGHT_MIDDLE:
    case STATE_TURN_RIGHT_END:
      if (a && b) {
        encoderState = STATE_TURN_RIGHT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
        delta = -1;
      };
      break;
    case STATE_TURN_LEFT_START:
      if (a && b) {
        encoderState = STATE_TURN_LEFT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_LEFT_MIDDLE:
    case STATE_TURN_LEFT_END:
      if (a && b) {
        encoderState = STATE_TURN_LEFT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
        delta = 1;
      };
      break;
    case STATE_UNDECIDED:
      if (a && b) {
        encoderState = STATE_UNDECIDED;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
  }
}

EDIT: Binäre Ausgabe mit führenden Nullen.

ich möchte nicht andere varianten Durch Probieren, sondern meine variante am laufen bekommen

Habs mal Ausprobiert
Als Ausgabe bekomme ich das Hier:
#⸮⸮⸮⸮2⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮2⸮⸮⸮⸮⸮2⸮2⸮⸮2⸮2⸮2⸮⸮⸮⸮⸮⸮⸮⸮⸮

das ist aber kein BIN Code und eine Serielle Ausgabe.

Ich habe vermutlich eine andere Baudrate verwendet: Serial.begin(115200);

Ausgabe:

Start
--> 10000000 128
<-- 01111111 127

Ah jetzt funktioniert die Ausgabe soweit.
Nur wie Bekomme ich das jetzt auf die Pins 2 - 9 gelegt?

Versuch mal sowas:

const byte LED_PIN[] = {2, 3, 4, 5, 6, 7, 8, 9};
...
digitalWrite(LED_PIN[p], w & (1 << p));

Danke
Funktioniert soweit.
drei dinge sind mir Aufgefallen:
die LED´s leuchten nicht gerade hell. warum auch immer die Spannung bei belastung zusammen sackt
der Bin Zähler zickt rum und zählt an bestimmten Stellen nicht Korekt weiter.
z.b. wert 16 Müsste ja 00010000 sein, wird aber in 00011000 angezeigt.
bei wert 32 bekomme ich 00100100 zu sehen
64 ist 01000010 und 128 sieht so aus 10000001

Am ende von 255 zählt er intern weiter .

da Stimmt was nicht.

Zeige Dein Programm, dann können wir gemeinsam schauen.

ich habe das Problem Lösen können. die Sache sieht jetzt so aus:

// Quelle: https://github.com/pinae/Knob-Louder
// Beschreibung: c't 18/2020
// Hardware grüne und schwarze Platine nach GND schaltend
// https://forum.arduino.cc/index.php?topic=701098.0
const byte LED_PIN[] = {2, 3, 4, 5, 6, 7, 8, 9};
const byte ENCODER_A_PIN = A0;
const byte ENCODER_B_PIN = A1;

void setup() {
  Serial.begin(115200);
  Serial.println("\nStart");
  pinMode(ENCODER_A_PIN, INPUT);
  pinMode(ENCODER_B_PIN, INPUT);
  pinMode(LED_PIN,OUTPUT);

}

void loop() {
  static uint8_t wert = 0;
  int8_t state = 0;
  rotaryEncoder(state);
  if (state == -1) {
    if (wert > 0) wert--;
    Serial.print("<-- \t");
    ausgabe (wert);
    Serial.print('\t');
    Serial.print(wert);
    Serial.println();
 
  }
  if (state == 1) {
    if (wert < 255) wert++;  // Schritte
    Serial.print(" --> \t");
    ausgabe (wert);
    Serial.print('\t');
    Serial.print(wert);
    Serial.println();
  }
}

void ausgabe(uint8_t w) {
  for (uint8_t p = 0; p < 8; p++) { // Bit tiefe
    if (w & (0 << (0 - p))) {
      Serial.print('1');
    } else {
      Serial.print('0');
        digitalWrite(LED_PIN[p], w & 1 << (p));
    }
  }
}

void rotaryEncoder(int8_t &delta) {
  delta = 0;
  enum {STATE_LOCKED, STATE_TURN_RIGHT_START, STATE_TURN_RIGHT_MIDDLE, STATE_TURN_RIGHT_END, STATE_TURN_LEFT_START, STATE_TURN_LEFT_MIDDLE, STATE_TURN_LEFT_END, STATE_UNDECIDED};
  static uint8_t encoderState = STATE_LOCKED;
  bool a = !digitalRead(ENCODER_A_PIN);
  bool b = !digitalRead(ENCODER_B_PIN);
  switch (encoderState) {
    case STATE_LOCKED:
      if (a && b) {
        encoderState = STATE_UNDECIDED;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_RIGHT_START:
      if (a && b) {
        encoderState = STATE_TURN_RIGHT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_RIGHT_MIDDLE:
    case STATE_TURN_RIGHT_END:
      if (a && b) {
        encoderState = STATE_TURN_RIGHT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
        delta = -1;
      };
      break;
    case STATE_TURN_LEFT_START:
      if (a && b) {
        encoderState = STATE_TURN_LEFT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_LEFT_MIDDLE:
    case STATE_TURN_LEFT_END:
      if (a && b) {
        encoderState = STATE_TURN_LEFT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
        delta = 1;
      };
      break;
    case STATE_UNDECIDED:
      if (a && b) {
        encoderState = STATE_UNDECIDED;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
  }
}

Die Aussage wundert mich, da Dein Programm bei mir nicht funktioniert.

Bei mir auch nicht - da hab ich aber noch seine Pins drin ;(

Ich hab hier auch rumgespielt und bin hier auch über irgendwas gestolpert. Das mit dem schieben geht bei mir auch nicht, aber das liegt wohl eher an mir ;(

Allerdings bekomme ich auch nur 8bit 0 raus...

Na denn.

Hmm...
Verstehe ich nicht.

bei mir Läuft der Bin Code und stimmt mit der Serial Ausgabe überein.
das ganze habe ich auf dem UNO R3 am laufen

Anzeige:

Start
--> 00000000 1
--> 00000000 2
--> 00000000 3
--> 00000000 4
<-- 00000000 3
<-- 00000000 2
<-- 00000000 1
<-- 00000000 0

Auch bekomme ich zwei, wie ich finde, relevante Warnungen:

14:26: warning: invalid conversion from 'const byte* {aka const unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive]
   pinMode(LED_PIN, OUTPUT);
                          ^

134:6: note:   initializing argument 1 of 'void pinMode(uint8_t, uint8_t)'
 void pinMode(uint8_t pin, uint8_t mode);
      ^~~~~~~

Hier auf'm Mega nicht.
Da kommt nur 00000000 raus.
das hier ist schon Mist:

/tmp/arduino_modified_sketch_433925/sketch_aug29d.ino: In function 'void setup()':
/tmp/arduino_modified_sketch_433925/sketch_aug29d.ino:16:26: warning: invalid conversion from 'const byte* {aka const unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive]
   pinMode(LED_PIN, OUTPUT);
                          ^

Und das hier auch irgendwie.

  static uint8_t wert = 0;

Du merkst am Anfang nicht, das sich der Encoder in die andere Richtung gedreht hat.

Die Ausgabe für beider ersetzt mit diesem:

void ausgabe(uint8_t w)
{
  // Ausgabe 1 - tubeland
  for (uint8_t p = 0; p < 8; p++)   // Bit tiefe
  {
    if (w & (0 << (0 - p)))
    {
      Serial.print('1');
    }
    else
    {
      Serial.print('0');
      digitalWrite(LED_PIN[p], w & 1 << (p));
    }
  }
  Serial.println();
  // Ausgabe 2 - agmue
  for (int8_t p = 7; p >= 0; p--)
  {
    if (w & (1 << p))
    {
      Serial.print('1');
    }
    else
    {
      Serial.print('0');
    }
  }
}

ergibt:

|18:43:02.633 -> 00101101|45|
|---|---|
|18:43:02.674 ->  --> |00000000|
|18:43:02.674 -> 00101110|46|
|18:43:02.931 ->  --> |00000000|
|18:43:02.931 -> 00101111|47|
|18:43:02.975 ->  --> |00000000|
|18:43:02.975 -> 00110000|48|

Da ist also irgendwas falsch mit deinem schieben.

OK habe das Jetzt verstanden .
ihr habt recht die BIN Ausgabe ist immer 000000 allerdings stimmen die Zahlen mit den Ausgangs Port überein . sorry habe ich übersehen.

ich war damit beschäftigt die Port Ausgabe richtig da zu stellen

Ich wollte noch eine Abfrage einbauen!
Wenn LED_PIN Low ist ( 00000000)
dann soll led_Abfrage High werden.
ist eines der LED_PIN bits High soll led_Abfrage Low sein.

Ich habe wie folgt eingebaut.

const byte led_Abfrage = 10;

void setup() {
  Serial.begin(115200);
  Serial.println("\nStart");
  pinMode(ENCODER_A_PIN, INPUT);
  pinMode(ENCODER_B_PIN, INPUT);
pinMode(LED_PIN,OUTPUT);
pinMode(led_Abfrage,OUTPUT);

}

void loop() {
   if (LED_PIN < led_Abfrage)
   digitalWrite(led_Abfrage HIGH);  
  static uint8_t wert = 0;
  int8_t state = 0;
  rotaryEncoder(state);

unabhängig von der Fehlermeldung weiß ich nicht welcher der Operatoren hier richtig ist

... die niemand kennt und auch nicht nachvollziehen kann, weil Dein Code nicht da ist.

hier der Komplette code

// Quelle: https://github.com/pinae/Knob-Louder
// Beschreibung: c't 18/2020
// Hardware grüne und schwarze Platine nach GND schaltend
// https://forum.arduino.cc/index.php?topic=701098.0
const byte LED_PIN[] = {2, 3, 4, 5, 6, 7, 8, 9};
const byte ENCODER_A_PIN = A0;
const byte ENCODER_B_PIN = A1;
const byte led_Abfrage = 10;

void setup() {
  Serial.begin(115200);
  Serial.println("\nStart");
  pinMode(ENCODER_A_PIN, INPUT);
  pinMode(ENCODER_B_PIN, INPUT);
pinMode(LED_PIN,OUTPUT);
pinMode(led_Abfrage,OUTPUT);

}

void loop() {
   if (LED_PIN < led_Abfrage)
   digitalWrite(led_Abfrage HIGH);  
  static uint8_t wert = 0;
  int8_t state = 0;
  rotaryEncoder(state);
  if (state == -1) {
    if (wert > 0) wert--;
    Serial.print("<-- \t");
    ausgabe (wert);
    Serial.print('\t');
    Serial.print(wert);
    Serial.println();
 
  }
  if (state == 1) {
    if (wert < 255) wert++;  // Schritte
    Serial.print(" --> \t");
    ausgabe (wert);
    Serial.print('\t');
    Serial.print(wert);
    Serial.println();
     
  }
}

 void ausgabe(uint8_t w)
{
  // Ausgabe 1 - tubeland
  for (uint8_t p = 0; p < 8; p++)   // Bit tiefe
  {
    if (w & (0 << (0 - p)))
    {
//      Serial.print('1');
    }
    else
    {
  //    Serial.print('0');
      digitalWrite(LED_PIN[p], w & 1 << (p));
    }
  }
  // Serial.println();
  // Ausgabe 2 - agmue
  for (int8_t p = 7; p >= 0; p--)
  {
    if (w & (1 << p))
    {
      Serial.print('1');
    }
    else
    {
      Serial.print('0');
      
    }
  }
}

void rotaryEncoder(int8_t &delta) {
  delta = 0;
  enum {STATE_LOCKED, STATE_TURN_RIGHT_START, STATE_TURN_RIGHT_MIDDLE, STATE_TURN_RIGHT_END, STATE_TURN_LEFT_START, STATE_TURN_LEFT_MIDDLE, STATE_TURN_LEFT_END, STATE_UNDECIDED};
  static uint8_t encoderState = STATE_LOCKED;
  bool a = !digitalRead(ENCODER_A_PIN);
  bool b = !digitalRead(ENCODER_B_PIN);
  switch (encoderState) {
    case STATE_LOCKED:
      if (a && b) {
        encoderState = STATE_UNDECIDED;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_RIGHT_START:
      if (a && b) {
        encoderState = STATE_TURN_RIGHT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_RIGHT_MIDDLE:
    case STATE_TURN_RIGHT_END:
      if (a && b) {
        encoderState = STATE_TURN_RIGHT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_RIGHT_START;
      }
      else {
        encoderState = STATE_LOCKED;
        delta = -1;
      };
      break;
    case STATE_TURN_LEFT_START:
      if (a && b) {
        encoderState = STATE_TURN_LEFT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
    case STATE_TURN_LEFT_MIDDLE:
    case STATE_TURN_LEFT_END:
      if (a && b) {
        encoderState = STATE_TURN_LEFT_MIDDLE;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_LEFT_START;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
        delta = 1;
      };
      break;
    case STATE_UNDECIDED:
      if (a && b) {
        encoderState = STATE_UNDECIDED;
      }
      else if (!a && b) {
        encoderState = STATE_TURN_RIGHT_END;
      }
      else if (a && !b) {
        encoderState = STATE_TURN_LEFT_END;
      }
      else {
        encoderState = STATE_LOCKED;
      };
      break;
  }
}