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

und an pin 10 soll die LED Leuchten wenn der BIN Wert 00000000 ist.
ist der BIN Wert Größer als 00000000 dann soll die LED an Pin 10 Nicht Leuchten.

sorry war ein schreibfehler

Ist schon klar , also noch mal wiso kannst Du dann nicht Vorschlag von #39 verwenden ?

if ( wert ==0 ) digitalWrite(10,HIGH);
else digitalWrite(10,LOW);

habe ich so eben eingebaut.
wenn ich runter Zähle von 00000111 auf 00000000 gegt die LED an pin 10 An so wie sie es soll
nur wenn ich wieder hoch zähle bleibt sie an

Hallo,
dann zeig das mal, das kann ich nicht glauben. Dazu ist doch das else da. ??

Heinz

// 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;
int  led_Mute = 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_Mute,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 (led_Mute >= 0 )digitalWrite(led_Mute, LOW); // LED LOW Wenn BIN Wert min 0000001 ist
 // if (led_Mute  <= 2 )digitalWrite(led_Mute, HIGH);  // LED HIGH Wenn BIN 00000000 ist
if ( wert ==0 ) digitalWrite(10,HIGH);
else digitalWrite(10,LOW);

 
  }
  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));


        
  // if (p < 1 )digitalWrite(led_Mute, HIGH);
  // if (p++  <= 10 )digitalWrite(led_Mute, HIGH);
 //  digitalWrite(led_Mute, LOW);
       
 
    }
  }
}

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;
  }
}

Hallo.
bau den Loop mal so um , du hast das innerhalb der IF Bedingung desshalb

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 (led_Mute >= 0 )digitalWrite(led_Mute, LOW); // LED LOW Wenn BIN Wert min 0000001 ist
    // if (led_Mute  <= 2 )digitalWrite(led_Mute, HIGH);  // LED HIGH Wenn BIN 00000000 ist


  }
  if (state == 1) {
    if (wert < 255) wert++;  // Schritte
    Serial.print(" --> \t");
    ausgabe (wert);
    Serial.print('\t');
    Serial.print(wert);
    Serial.println();

  }
  if ( wert == 0 ) digitalWrite(10, HIGH);
  else digitalWrite(10, LOW);

}

Wenn ich das sehe, dann frage ich mich wo Dein löschen des gesetzten LED PIN ist.

Versuchs doch mal so:

{
  bool PIN = false;
  for (uint8_t i = 0; i < 8; i++)
  {
    if (LED_PIN[i])
    {
      PIN = true;
    }
  }
  digitalWrite(10,PIN);
}

Ahh jetzt geht es

Sorry my_xy_projekt was soll die schleife ? bin ich irgendwie auf dem Holzweg ?? :pensive:

Gruß Heinz

Nein dein Vorschlag Funktioniert Super.
Danke :slightly_smiling_face: Rentner

Ach komm... :wink:
Ich wollte einfach mal. - Und ja, da fehlte dann die Ausgabe, welcher PIN HIGH ist. Aber das sollte der TO schon allein.

Hallo,
habe da noch eine Frage, ich habe so einen einfachen Drehimpulsgeber für Arduino. Der hat ein mechanisches Raster. Damit lässt sich allerdings dann nur bei jeder Rasterstellung um eins weiterzählen, eine Flanke je Raster. Du wertest jetzt ja jede der 4 Flanken aus, hat Dein Drehgeber keine Rasterstellung ? Kannst Du mit dem Ding vernünftig +-1 zählen ?
Heinz

Doch die hat er - habe den Von reichelt ( STEC12E05 Albs)

In #4 findest Du die Quellenangabe.

Bei mir funktioniert das Programm auch mit nicht entprellten Kontakten nur mit PullUp-Widerständen auf der Platine. Statistisch kann ich mit meiner geringen Anzahl logischerweise aber keine verläßliche allgemeine Aussage treffen.

Ich habe auf dem Steckbrett jeweils 10K Widerstände auf GND gesetzt

Hallo,

noch einen kleinen Performance Hinweis.

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');
    }
  }
}

In beiden Schleifen wird hier beim 8Bit Datentyp jeweils 28 mal ein Bit verschoben. Das kostet etwas Zeit die man vermeiden kann wenn man nicht jedesmal aufs neue die Bits komplett verschieben lässt. Man merkt sich die aktuelle Bitposition und schiebt sie je Durchlauf nur eins weiter und damit je Schleife nur 7 mal. Verhältnis 56 zu 14. Das wäre eine Ausnahme wo man nicht alles im Schleifenkopf definiert und da es in einer Funktion steckt bleibt der Zähler sowieso lokal. Wollte ich mal zum Besten geben. :wink:

Schöne Idee, eventuell so?

void ausgabe(uint8_t w) {
  uint8_t p = 0x80;
  while (p > 0) {
    if (w & p) {
      Serial.print('1');
    } else {
      Serial.print('0');
    }
    p = p >> 1;
  }
}

Unter Berücksichtigung der LED-Pins auch so:

void ausgabe(uint8_t w) {
  uint8_t p = 0x80;
  for (const byte lp : LED_PIN) {
    if (w & p) {
      Serial.print('1');
      digitalWrite(lp, HIGH);
    } else {
      Serial.print('0');
      digitalWrite(lp, LOW);
    }
    p = p >> 1;
  }
}

Im Zusammenhang:

// Quelle: https://github.com/pinae/Knob-Louder
// Beschreibung: c't 18/2020
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);
  for (const byte lp : LED_PIN) pinMode(lp, OUTPUT);
}

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) {
  uint8_t p = 0x80;
  for (const byte lp : LED_PIN) {
    if (w & p) {
      Serial.print('1');
      digitalWrite(lp, HIGH);
    } else {
      Serial.print('0');
      digitalWrite(lp, LOW);
    }
    p = p >> 1;
  }
}

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;
  }
}

Hallo,

genau. Mir fiel das einmal beim Bit Banging mit SPI auf. Man gewinnt im Vergleich zum Takt sehr viel Zeit vor allen dingen wenn man 16Bit raustaktet um so mehr.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.