switch case seriell steuern [gelöst]

Hallo, ich habe mehrere Neopixel LED Strip Abschnitte an 8 verschiedenen Arduino Pins, die ich alle separat ansteuern kann. Ich möchte diese nun über die serielle Schnittstelle ansprechen was auch funktioniert. Was mir jedoch nicht gelingt, ist es, daß ein case solange laufen soll, bis ein neuer buchstabe gesendet wird. Wie kann man das lösen? Danke!

void loop(){
    if (Serial.available() > 0) {
    int inByte = Serial.read();
        
    switch (inByte) {
      case 'a':
        A_RunningLights();
        break;
      case 'b':
        B_RunningLights();
        break;
      case 'c':
        C_RunningLights();
        break;
      case 'd':
        D_RunningLights();
        break;
      case 'x':
        X_Reset();
        break;
      default:
        // turn all the LEDs off:
        X_Reset();
        }
    }
}

    


///A Running Lights///////////////////////////////////////////////////////////////////////////////////////////

void A_RunningLights() {
  int thisinByte = 'a';     
  int inByte = Serial.read();
  
  while (inByte == thisinByte){
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;        // will store last time x.show() was updated
  static int DarkBluePosition = PIXEL_COUNT;
  static int BluePosition = 0;
  
  if (currentMillis - previousMillis >= INTERVALL)
  {
    previousMillis = currentMillis;
    DarkBluePosition++;
    BluePosition--;
    for (int i = 0; i < PIXEL_COUNT; i++)
    {
      A_DARKBLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+DarkBluePosition) * 50 + 205)/255)*100);
      A_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+BluePosition) * 50 + 205)/255)*255);
    }
    A_DARKBLUEPIXELS.show();
    A_BLUEPIXELS.show();
    
  }
 }
}

Du musst den entsprechenden Wert in eine Variable zwischspeichern und diese immer in der loop abfragen.

Hallo
probier mal die ungetestete Lösung:

void loop() {
  static int inByte;
  if (Serial.available() > 0) {
    inByte = Serial.read();
  }
  switch (inByte) {
    case 'a':
      A_RunningLights();
      break;
    case 'b':
      B_RunningLights();
      break;
    case 'c':
      C_RunningLights();
      break;
    case 'd':
      D_RunningLights();
      break;
    case 'x':
      X_Reset();
      break;
    default:
      // turn all the LEDs off:
      X_Reset();
  }

}




///A Running Lights///////////////////////////////////////////////////////////////////////////////////////////

void A_RunningLights() {
  int thisinByte = 'a';
  int inByte = Serial.read();

  while (inByte == thisinByte) {
    unsigned long currentMillis = millis();
    static unsigned long previousMillis = 0;        // will store last time x.show() was updated
    static int DarkBluePosition = PIXEL_COUNT;
    static int BluePosition = 0;

    if (currentMillis - previousMillis >= INTERVALL)
    {
      previousMillis = currentMillis;
      DarkBluePosition++;
      BluePosition--;
      for (int i = 0; i < PIXEL_COUNT; i++)
      {
        A_DARKBLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + DarkBluePosition) * 50 + 205) / 255) * 100);
        A_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + BluePosition) * 50 + 205) / 255) * 255);
      }
      A_DARKBLUEPIXELS.show();
      A_BLUEPIXELS.show();

    }
  }
}

HotSystems:
Du musst den entsprechenden Wert in eine Variable zwischspeichern und diese immer in der loop abfragen.

Das tue ich doch in Zeile 3 der loop.
Und dann auch innerhalb der while Schleife um diese zu unterbrechen.

Oder habe ich etwas übersehen?

petemanzel:
Das tue ich doch in Zeile 3 der loop.
Und dann auch innerhalb der while Schleife um diese zu unterbrechen.

Oder habe ich etwas übersehen?

Ja, du musst die switch/case ausserhalb der if-Abfrage schreiben, also direkt in der loop.

HotSystems:
Ja, du musst die switch/case ausserhalb der if-Abfrage schreiben, also direkt in der loop.

Sorry, ich kann dir nicht folgen. switch/case ist doch in keiner if-Abfrage.

paulpaulson:
Hallo
probier mal die ungetestete Lösung:

void loop() {

static int inByte;
  if (Serial.available() > 0) {
    inByte = Serial.read();
  }
  switch (inByte) {
    case ‘a’:
      A_RunningLights();
      break;
    case ‘b’:
      B_RunningLights();
      break;
    case ‘c’:
      C_RunningLights();
      break;
    case ‘d’:
      D_RunningLights();
      break;
    case ‘x’:
      X_Reset();
      break;
    default:
      // turn all the LEDs off:
      X_Reset();
  }

}

///A Running Lights///////////////////////////////////////////////////////////////////////////////////////////

void A_RunningLights() {
  int thisinByte = ‘a’;
  int inByte = Serial.read();

while (inByte == thisinByte) {
    unsigned long currentMillis = millis();
    static unsigned long previousMillis = 0;        // will store last time x.show() was updated
    static int DarkBluePosition = PIXEL_COUNT;
    static int BluePosition = 0;

if (currentMillis - previousMillis >= INTERVALL)
    {
      previousMillis = currentMillis;
      DarkBluePosition++;
      BluePosition–;
      for (int i = 0; i < PIXEL_COUNT; i++)
      {
        A_DARKBLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + DarkBluePosition) * 50 + 205) / 255) * 100);
        A_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + BluePosition) * 50 + 205) / 255) * 255);
      }
      A_DARKBLUEPIXELS.show();
      A_BLUEPIXELS.show();

}
  }
}

Funktionirt leider nicht. So reagiert nichts mehr.

Stell mal testweise im Monitor das Zeilenende ab (unten rechts).
Wenn es dann funktioniert, überlegst Du Dir noch einen Buchstaben für "aus", ergänzt dafür einen case, in dem dann das X_Reset() landet und ignorierst im default-Zweig des switch() alle Bytes (der bleibt dann leer).

Ich poste hier mal mein ganzes Programm:

#include <Adafruit_NeoPixel.h>

#define PIXEL_COUNT  3

#define A_DARKBLUEPIXEL_PIN 2
#define A_BLUEPIXEL_PIN 3

#define B_REDPIXEL_PIN 4
#define B_BLUEPIXEL_PIN 5

#define C_REDPIXEL_PIN 6
#define C_BLUEPIXEL_PIN 7

#define D_REDPIXEL_PIN 8
#define D_BLUEPIXEL_PIN 9

//Kamin A
Adafruit_NeoPixel A_DARKBLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, A_DARKBLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel A_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, A_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

//Kamin B
Adafruit_NeoPixel B_REDPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, B_REDPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel B_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, B_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

//Kamin C
Adafruit_NeoPixel C_REDPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, C_REDPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel C_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, C_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

//Kamin D
Adafruit_NeoPixel D_REDPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, D_REDPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel D_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, D_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

const long INTERVALL = 60;          // interval at which to to refresh x.show();




void setup(){
 Serial.begin(9600);
  
  A_DARKBLUEPIXELS.begin();
  A_DARKBLUEPIXELS.show(); // initialize all PIXELS to "off"

  A_BLUEPIXELS.begin();
  A_BLUEPIXELS.show(); 
  
  B_REDPIXELS.begin();
  B_REDPIXELS.show(); 

  B_BLUEPIXELS.begin();
  B_BLUEPIXELS.show();

  C_REDPIXELS.begin();
  C_REDPIXELS.show(); 

  C_BLUEPIXELS.begin();
  C_BLUEPIXELS.show();

  D_REDPIXELS.begin();
  D_REDPIXELS.show(); 

  D_BLUEPIXELS.begin();
  D_BLUEPIXELS.show();
}


void loop() {
  static int inByte;
  if (Serial.available() > 0) {
    inByte = Serial.read();
  }
  switch (inByte) {
    case 'a':
      A_RunningLights();
      break;
    case 'b':
      B_RunningLights();
      break;
    case 'c':
      C_RunningLights();
      break;
    case 'd':
      D_RunningLights();
      break;
    case 'x':
      X_Reset();
      break;
    default:
      // turn all the LEDs off:
      X_Reset();
  }

}




///A Running Lights///////////////////////////////////////////////////////////////////////////////////////////

void A_RunningLights() {
  int thisinByte = 'a';
  int inByte = Serial.read();

  while (inByte == thisinByte) {
    unsigned long currentMillis = millis();
    static unsigned long previousMillis = 0;        // will store last time x.show() was updated
    static int DarkBluePosition = PIXEL_COUNT;
    static int BluePosition = 0;

    if (currentMillis - previousMillis >= INTERVALL)
    {
      previousMillis = currentMillis;
      DarkBluePosition++;
      BluePosition--;
      for (int i = 0; i < PIXEL_COUNT; i++)
      {
        A_DARKBLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + DarkBluePosition) * 50 + 205) / 255) * 100);
        A_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + BluePosition) * 50 + 205) / 255) * 255);
      }
      A_DARKBLUEPIXELS.show();
      A_BLUEPIXELS.show();

    }
  }
}


///B Running Lights///////////////////////////////////////////////////////////////////////////////////////////

void B_RunningLights() {
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;        // will store last time x.show() was updated
  static int RedPosition = PIXEL_COUNT;
  static int BluePosition = 0;

  if (currentMillis - previousMillis >= INTERVALL)
  {
    previousMillis = currentMillis;
    RedPosition++;
    BluePosition--;
    for (int i = 0; i < PIXEL_COUNT; i++)
    {
      B_REDPIXELS.setPixelColor(i,((sin(i+RedPosition) * 50 + 205)/255)*255, 0, 0);
      B_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+BluePosition) * 100 + 155)/255)*150);
    }
    B_REDPIXELS.show();
    B_BLUEPIXELS.show();
  }
}


///C Running Lights/////////////////////////////////////////////////////////////////////////////////////////

void C_RunningLights() {
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;        // will store last time x.show() was updated
  static int RedPosition = PIXEL_COUNT;
  static int BluePosition = 0;

  if (currentMillis - previousMillis >= INTERVALL)
  {
    previousMillis = currentMillis;
    RedPosition++;
    BluePosition--;
    for (int i = 0; i < PIXEL_COUNT; i++)
    {
      C_REDPIXELS.setPixelColor(i,((sin(i+RedPosition) * 100 )/200)*120, 0, 0);
      C_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+BluePosition) * 100 + 155)/255)*150);
    }
    C_REDPIXELS.show();
    C_BLUEPIXELS.show();
  }
}


///D Running Lights////////////////////////////////////////////////////////////////////////////////////////

void D_RunningLights() {
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;        // will store last time x.show() was updated
  static int RedPosition = PIXEL_COUNT;
  static int BluePosition = 0;

  if (currentMillis - previousMillis >= INTERVALL)
  {
    previousMillis = currentMillis;
    RedPosition++;
    BluePosition--;
    for (int i = 0; i < PIXEL_COUNT; i++)
    {
      D_REDPIXELS.setPixelColor(i,((sin(i+RedPosition) * 50 + 205)/255)*255, 0, 0);
      D_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+BluePosition) * 100 + 155)/255)*150);
    }
    D_REDPIXELS.show();
    D_BLUEPIXELS.show();
  }
}


///X Reset//////////////////////////////////////////////////////////////////////////////////////////////////

void X_Reset() {
   
    A_DARKBLUEPIXELS.fill((0,0,0)); 
    A_BLUEPIXELS.fill((0,0,0)); 
    A_DARKBLUEPIXELS.show(); 
    A_BLUEPIXELS.show(); 
 
    B_REDPIXELS.fill((0,0,0)); 
    B_BLUEPIXELS.fill((0,0,0)); 
    B_REDPIXELS.show();
    B_BLUEPIXELS.show();
    
    C_REDPIXELS.fill((0,0,0)); 
    C_BLUEPIXELS.fill((0,0,0)); 
    C_REDPIXELS.show();
    C_BLUEPIXELS.show();
 
    D_REDPIXELS.fill((0,0,0)); 
    D_BLUEPIXELS.fill((0,0,0)); 
    D_REDPIXELS.show();
    D_BLUEPIXELS.show();
}

Das Problem bleibt dasselbe:
Nach dem 'a' sendet der Monitor noch Byte(s) für das Zeilenende. Damit landest Du im default() und schaltest alle LEDs aus.

wno158:
Das Problem bleibt dasselbe:
Nach dem 'a' sendet der Monitor noch Byte(s) für das Zeilenende. Damit landest Du im default() und schaltest alle LEDs aus.

Hab das Zeilenende abgestellt. Das Verhalten bleibt aber unverändert.

petemanzel:
Ich poste hier mal mein ganzes Programm:

DDAAAANKKEEE!

Keine #define wenn Sie nicht nötig sind!

#define PIXEL_COUNT  3

Gilt auch für den Rest.
Mach const draus!

Warum um alles in der Welt machen alle Leute das im setup()

  D_BLUEPIXELS.show();

Gilt auch für die rest .show()

Wenn Du nur ein byte einliest, ist die Variable nur ein byte.
Warum int?

 static int inByte;
  if (Serial.available() > 0) {
    inByte = Serial.read();

Und jetzt kommt der Auswahlfaktor:

Aus

void loop() {
  static int inByte;
  if (Serial.available() > 0) {
    inByte = Serial.read();
  }
  switch (inByte) {

wird:

void loop() {
  static byte lastchar;
  if (Serial.available() > 0) {
    byte inByte = Serial.read();
  }
  if (isAlpha(inByte))
  {
    if (lastchar != inByte)
    {
      lastchar = inByte
    }
  }

  switch (lastchar) {

ungetestet und nur angepinnt als Gedankengang

@my_xy_projekt
Vielen Dank. So läuft es jetzt!

Ich habe irrtümlicherweise gedacht, daß wenn ich einmal im switch/case bin, ich dort nur rausgekommen wäre, wenn ich dort auf einw neue Eingabe gewartet hätte.

“isAlpha” kannte ich auch nicht.
Hab heute Abend viel gelernt. Danke!

Das ist meine funktionierende Fassung:

#include <Adafruit_NeoPixel.h>
const byte PIXEL_COUNT = 3;

const byte A_DARKBLUEPIXEL_PIN = 2;
const byte A_BLUEPIXEL_PIN = 3;

const byte B_REDPIXEL_PIN = 4;
const byte B_BLUEPIXEL_PIN = 5;

const byte C_REDPIXEL_PIN = 6;
const byte C_BLUEPIXEL_PIN = 7;

const byte D_REDPIXEL_PIN = 8;
const byte D_BLUEPIXEL_PIN = 9;

//Kamin A
Adafruit_NeoPixel A_DARKBLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, A_DARKBLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel A_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, A_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

//Kamin B
Adafruit_NeoPixel B_REDPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, B_REDPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel B_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, B_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

//Kamin C
Adafruit_NeoPixel C_REDPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, C_REDPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel C_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, C_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

//Kamin D
Adafruit_NeoPixel D_REDPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, D_REDPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel D_BLUEPIXELS = Adafruit_NeoPixel(PIXEL_COUNT, D_BLUEPIXEL_PIN, NEO_GRB + NEO_KHZ800);

const long INTERVALL = 60;          // interval at which to to refresh x.show();




void setup(){
 Serial.begin(9600);
  
  A_DARKBLUEPIXELS.begin();
  A_BLUEPIXELS.begin();
  
  B_REDPIXELS.begin();
  B_BLUEPIXELS.begin();
  
  C_REDPIXELS.begin();
  C_BLUEPIXELS.begin();
  
  D_REDPIXELS.begin();
  D_BLUEPIXELS.begin();
  
  X_Reset();
}


void loop() {
  static char lastchar;
  char inByte;

  if (Serial.available() > 0) {
    inByte = Serial.read();
  }
  if (isAlpha(inByte))
  {
    if (lastchar != inByte)
    {
      X_Reset();
      lastchar = inByte;
    }
  }

  switch (lastchar) {
    case 'a':
      A_RunningLights();
      break;
    case 'b':
      B_RunningLights();
      break;
    case 'c':
      C_RunningLights();
      break;
    case 'd':
      D_RunningLights();
      break;
    case 'x':
      X_Reset();
      break;
    default:
      break;
  }

}




///A Running Lights///////////////////////////////////////////////////////////////////////////////////////////

void A_RunningLights() {
    unsigned long currentMillis = millis();
    static unsigned long previousMillis = 0;        // will store last time x.show() was updated
    static int DarkBluePosition = PIXEL_COUNT;
    static int BluePosition = 0;

    if (currentMillis - previousMillis >= INTERVALL)
    {
      previousMillis = currentMillis;
      DarkBluePosition++;
      BluePosition--;
      for (int i = 0; i < PIXEL_COUNT; i++)
      {
        A_DARKBLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + DarkBluePosition) * 50 + 205) / 255) * 100);
        A_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i + BluePosition) * 50 + 205) / 255) * 255);
      }
      A_DARKBLUEPIXELS.show();
      A_BLUEPIXELS.show();
    }
  }


///B Running Lights///////////////////////////////////////////////////////////////////////////////////////////

void B_RunningLights() {
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;        // will store last time x.show() was updated
  static int RedPosition = PIXEL_COUNT;
  static int BluePosition = 0;

  if (currentMillis - previousMillis >= INTERVALL)
  {
    previousMillis = currentMillis;
    RedPosition++;
    BluePosition--;
    for (int i = 0; i < PIXEL_COUNT; i++)
    {
      B_REDPIXELS.setPixelColor(i,((sin(i+RedPosition) * 50 + 205)/255)*255, 0, 0);
      B_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+BluePosition) * 100 + 155)/255)*150);
    }
    B_REDPIXELS.show();
    B_BLUEPIXELS.show();
  }
}


///C Running Lights/////////////////////////////////////////////////////////////////////////////////////////

void C_RunningLights() {
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;        // will store last time x.show() was updated
  static int RedPosition = PIXEL_COUNT;
  static int BluePosition = 0;

  if (currentMillis - previousMillis >= INTERVALL)
  {
    previousMillis = currentMillis;
    RedPosition++;
    BluePosition--;
    for (int i = 0; i < PIXEL_COUNT; i++)
    {
      C_REDPIXELS.setPixelColor(i,((sin(i+RedPosition) * 100 )/200)*120, 0, 0);
      C_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+BluePosition) * 100 + 155)/255)*150);
    }
    C_REDPIXELS.show();
    C_BLUEPIXELS.show();
  }
}


///D Running Lights////////////////////////////////////////////////////////////////////////////////////////

void D_RunningLights() {
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;        // will store last time x.show() was updated
  static int RedPosition = PIXEL_COUNT;
  static int BluePosition = 0;

  if (currentMillis - previousMillis >= INTERVALL)
  {
    previousMillis = currentMillis;
    RedPosition++;
    BluePosition--;
    for (int i = 0; i < PIXEL_COUNT; i++)
    {
      D_REDPIXELS.setPixelColor(i,((sin(i+RedPosition) * 50 + 205)/255)*255, 0, 0);
      D_BLUEPIXELS.setPixelColor(i, 0, 0, ((sin(i+BluePosition) * 100 + 155)/255)*150);
    }
    D_REDPIXELS.show();
    D_BLUEPIXELS.show();
  }
}


///X Reset//////////////////////////////////////////////////////////////////////////////////////////////////

void X_Reset() {
   
    A_DARKBLUEPIXELS.fill((0,0,0)); 
    A_BLUEPIXELS.fill((0,0,0)); 
    A_DARKBLUEPIXELS.show(); 
    A_BLUEPIXELS.show(); 
 
    B_REDPIXELS.fill((0,0,0)); 
    B_BLUEPIXELS.fill((0,0,0)); 
    B_REDPIXELS.show();
    B_BLUEPIXELS.show();
    
    C_REDPIXELS.fill((0,0,0)); 
    C_BLUEPIXELS.fill((0,0,0)); 
    C_REDPIXELS.show();
    C_BLUEPIXELS.show();
 
    D_REDPIXELS.fill((0,0,0)); 
    D_BLUEPIXELS.fill((0,0,0)); 
    D_REDPIXELS.show();
    D_BLUEPIXELS.show();
}

petemanzel:
Vielen Dank. So läuft es jetzt!

Nichts anderes erwartet :wink: Auch wenn ich den text tatsächlich direkt im Foreneditor geschrieben habe...

"isAlpha" kannte ich auch nicht.
Hab heute Abend viel gelernt. Danke!

Das ist meine funktionierende Fassung:

Von mir gibts nen ++.
So schnell mal alles umgesetzt, was angesprochen wurde ist schon lange nicht mehr hier gewesen.
Ich hab noch nicht über alles geschaut. Trotzdem die Bitte:
Im ersten Post von Dir noch die Betreffzeile editieren und ein [gelöst] an den Anfang setzen - das hilft der Nachwelt.

Und dann mein obligatorischer Hinweis:
https://www.arduinoforum.de/code-referenz
Dort findest Du ein .pdf runterladen und durchlesen. Nicht auswendig lernen!!

Viel Spass mit deinem Spielzeug!

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