4 Bit Display, Rotary und USB HID (Arduino Uno), Menü auswählen und USB HID senden

Warum wird das dann instabil?

Ich habe jetzt noch eingebaut, dass auch nur Zeichen versendet werden, wenn das Display an ist.
Und
Wenn man in der Mute* schleife ist erst wieder andere Menüs anwählen kann, wenn man nochmals Mute betätigt hat. (Bei Mute* und Mute werden nun auch Zeichen per HID versendet.

Ich habe allerdings das Problem, dass nun nur noch durch drehen das Display angeht (und dann auch Zeichen versendet werden können), schick wäre, wenn ein Tastendruck auch das Display einschalten würde, ich bekomme das aber nicht hin...
Hier der ganze Code inzwischen:

#include <LiquidCrystal.h>
const int rs = 4, en = 5, d4 = 6, d5 = 7, d6 = 8, d7 = 9;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

const byte encoderPinA = 2;
const byte encoderPinB = 3;
const byte encoderPinSW = 10;
volatile int8_t encoderPos = 0;          // a counter for the dial
int8_t lastReportedPos = -1;             // change management
bool rotating = false;                   // debounce management
bool neuePosition = false;
boolean A_set = false;                   // interrupt service routine vars
boolean B_set = false;                   // interrupt service routine vars
int8_t lastMutePos = 0;
bool displayOff = true;

void setup() {
  lcd.begin(20, 2);

  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  pinMode(encoderPinSW, INPUT_PULLUP);

  attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 0 (pin 2)
  attachInterrupt(1, doEncoderB, CHANGE); // encoder pin on interrupt 1 (pin 3)

  Serial.begin(9600);                     // output
}

void loop()
{
  const char * text[5] = {"Filter 1", "Filter 2", "Filter 3", "Filter 4", "  Mute  "};
  const uint8_t code[5][8] = {
    {0, 0,  8, 40, 0, 0, 0, 0},
    {0, 0, 21, 40, 0, 0, 0, 0},
    {0, 0, 23, 40, 0, 0, 0, 0},
    {0, 0, 28, 40, 0, 0, 0, 0},
    {0, 0, 29, 40, 0, 0, 0, 0}
    };
  rotating = true;  // reset the debouncer
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;
  const uint32_t intervall = 5000;        // Abschaltzeit nach Inaktivität in ms
  uint32_t jetzt2 = millis();
  static uint32_t vorhin2 = jetzt2;
  const uint32_t intervall2 = 20;         // Entprellen
  if (lastReportedPos != encoderPos)
  {
    lastReportedPos = encoderPos;
    vorhin = jetzt; // Monoflop retriggern
    displayOff = true;
    lcd.setCursor(0, 0);
    lcd.print("12345678901234567890");
    //    lcd.setCursor(6, 1);
    //    lcd.print("                    ");
    lcd.setCursor(6, 1);
    if (encoderPos < 0 && lastMutePos == 0) encoderPos = 0;
    if (encoderPos <= 3 && lastMutePos == 1) encoderPos = 4;                
    if (encoderPos > 4) encoderPos = 4;
    if (lastMutePos == 0)
    lcd.print(text[encoderPos]);
    neuePosition = true;
    if (encoderPos >3 && lastMutePos == 1)
    {
    lcd.print("  Mute*  ");
    }
  }
  if (displayOff && encoderPos <= 3 && lastMutePos == 0 && neuePosition && !digitalRead(encoderPinSW)) // nur beim Tastendruck des Encoders werden die Zeichen verschickt
  {
    neuePosition = false;
    Serial.write(code[encoderPos], 8);
    releaseKey();

  }
  if (encoderPos <= 3 && jetzt - vorhin >= intervall)
  {
    lcd.setCursor(0, 1);
    lcd.print("                    ");
    lcd.setCursor(0, 0);
    lcd.print("                    ");
    displayOff = false;
  }
  if (encoderPos > 3)
  {
    static bool tik = false;
    static bool tak = false;
    if (!digitalRead(encoderPinSW))
      {
        if (!tik && !tak)
          {
            vorhin2 = jetzt2;              // Monoflop retriggern für Entprellen
            tik = true;
            tak = true;
            lcd.setCursor(6, 1);
            lcd.print("  Mute* ");
            Serial.write(code[encoderPos], 8);
            releaseKey();
            lastMutePos = 1;
          }
            else if (!tik && tak && jetzt2 - vorhin2 >= intervall2)
          {
            tik = true;
            tak = false;
            lcd.setCursor(6, 1);
            lcd.print("  Mute  ");
            Serial.write(code[encoderPos], 8);
            releaseKey();
            lastMutePos = 0;
          }
      }
         else
          {
            tik = false;
          }
  }
}
void releaseKey() {
  uint8_t keyNone[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  Serial.write(keyNone, 8);                  // Send Release key
}

                                             
void doEncoderA()                            // Interrupt on A changing state
{
  if ( rotating ) delay (1);                 // wait a little until the bouncing is done
  if ( digitalRead(encoderPinA) != A_set ) 
  { // debounce once more
    A_set = !A_set;                                      
    if ( A_set && !B_set )                   // adjust counter + if A leads B
      encoderPos += 1;
    rotating = false;                        // no more debouncing until loop() hits again
  }
}

                                             
void doEncoderB()                            // Interrupt on B changing state, same as A above
{                         
  if ( rotating ) delay (1);
  if ( digitalRead(encoderPinB) != B_set ) 
  {
    B_set = !B_set;                                   
    if ( B_set && !A_set )                   //  adjust counter - 1 if B leads A
      encoderPos -= 1;
    rotating = false;
  }
}

Vielleicht hat ja jemand einen Tipp :slight_smile: