Mit switch case negativen Wertebereich?

switch case erlaubt wohl keinen negativen Wertebereich?

exit status 1
duplicate (or overlapping) case value

Mache ich was falsch oder gibt es Alternativen?

int Leistung0;
.
.
.
switch (Leistung0) {
        case -99 ... -50:
          //Relais1 = an;
          bitSet(befehl,0);               //1.Stelle(0) ganz rechts binär auf 1 setzen
          break;
        case -149 ... -50:
          //Relais2 = an;
          bitSet(befehl,1);               //2.Stelle(1) von ganz binär auf 1 setzen
          break;
        case -199 ... -50:
          //Relais3 = an;
          bitSet(befehl,2);               //3.Stelle(2) von ganz binär auf 1 setzen
          break;
        case -249 ... -50:
          //Relais4 = an;
          bitSet(befehl,3);               //4.Stelle(3) von ganz binär auf 1 setzen
          break;
        case 5:
          //do something when var equals 2
          break;
        case 6:
          //do something when var equals 2
          break;
        case 7:
          //do something when var equals 2
          break;
        case 8:
          //do something when var equals 2
          break;
        case 9:
          //do something when var equals 2
          break;
        case 10:
          //do something when var equals 2
          break;
        case 11:
          //do something when var equals 2
          break;
        case -49 ... 10000:
          //Relais1 = aus;
          bitClear(befehl,0);                     //1.Stelle(0) ganz rechts binär auf 0 setzen
          //Relais2 = aus;
          bitClear(befehl,1);                     //2.Stelle(1) ganz rechts binär auf 0 setzen
          //Relais3 = aus;
          bitClear(befehl,2);                     //3.Stelle(2) ganz rechts binär auf 0 setzen
          //Relais4 = aus;
          bitClear(befehl,3);                     //4.Stelle(3) ganz rechts binär auf 0 setzen
          break;                    
        default:
          //Relais1 = aus;
          //bitClear(befehl,0);                     //1.Stelle(0) ganz rechts binär auf 0 setzen
          break;
      }

das hat nichts mit negativen Werten zu tun, sondern deine Bereiche überschneiden sich.
Ganze Fehlermeldung in der IDE aktivieren und auch vollständig lesen.

sketch.ino:12:9: error: duplicate (or overlapping) case value
case -149 ... -50:
^~~~
sketch.ino:8:9: note: this is the first entry overlapping that value
case -99 ... -50:
^~~~

bitte poste künftig vollständigen Code den man in die IDE kopieren kann und einfach auf kompilieren drücken kann, so Codeschnippsel wo die Hälfte wieder fehlt kosten nur Zeit und nerven.

2 Likes

Klassisch mit if / else (ungetestet):

if ( Leistung0 < -200 ) bitSet(befehl,3);
else if ( Leistung0 < -150 ) bitSet(befehl,2);
else if ( Leistung0 < -100 ) bitSet(befehl,1);
else if ( Leistung0 <  -50 ) bitSet(befehl,0);
else {
  bitClear(befehl,0);
  bitClear(befehl,1);
  bitClear(befehl,2);
  bitClear(befehl,3);
}
1 Like

Stimmt, die Werte überschneiden sich.:thinking: Der Compiler lässt sich nicht beschummeln?!:grin:

Ja, in dem Fall wird wohl if else besser sein.:+1: Switch finde ich sonst übersichtlicher...

Da von Menschenhand gemacht, vermutlich doch, nur nicht so einfach.

Ich habe eine nachgefragte Alternative gezeigt, aber keine Wertung vorgenommen.

Mache es so, wie es für Dich am verständlichsten ist, nur mache es richtig :slightly_smiling_face:

Andererseits muß man bei Switch case keine break verwenden
man kann ohne Probleme zB

case -149 ... -100:
         mach  was
        case -99 ... -50:
        mach was anderes
break;

In diesem Fall wird zwischen -149 und -100 etwas gemacht und danach noch was anderes.
Zwischen -99 und -50 wird was anderes gemacht.

Grüße Uwe

1 Like

Wo soll der Vorteil sein? Leistung0 kann doch nur in einen der beiden Bereiche liegen.

Edit: Ah, hab’s geschnallt. Bei z.B. -130 wird mach was und mach was anderes ausgeführt . Verursacht durch das fehlende break

Ob das in diesem konkreten Fall ein möglicher Lösungsweg sein könnte weiß ich nicht zu sagen. Die Problemstellung ist zu unklar definiert.
Grüße Uwe

"else if " scheint auf dem ESP32 nicht zu funktionieren?

Es kommt als Ergebnis immer die letzte Möglichkeit von "else if" - in diesem Fall Task 4.

if (condition1) {
  // Tue Task 1
}
else if (condition2) {
  // Tue Task 2
}
else if (condition3) {
  // Tue Task 3
}
else if (condition4) {
  // Tue Task 4
}
else {
  // Tue Task 5
}

Das ist eine irrationale Annahme.

Darf ich dich fragen, warum du den Code bis zur Untestbarkeit verstümmelst?
(nein, ich möchte keine Antwort darauf, es reicht mir, wenn du das überdenkst)

Dem kann ich widersprechen!

Dein Fehler liegt an einer andere Stelle :wink:

Das widerspricht Deinem Ausgangscode:

Wenn Du willst, das zwischen -149 und -50 bit1 gesetzt wird UND zwischen -99 und -50 bit2, dann darfst Du das nicht ausschliessen.
Sprich: bei -70 würde bit1 und bit2 gesetzt?
Dann if ohne else.


void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));

  for (int i = 0; i >= -250; i -= 10)
  {
    Serial.println();
    Serial.print(F("Wert:"));
    Serial.println(i);
    if (i <= -50)
    {
      Serial.print(F("Gefunden:"));
      if (i >= -99)
      {
        Serial.print(F(" -99"));
      }
      if (i >= -149)
      {
        Serial.print(F(" -149"));
      }
      if (i >= -199)
      {
        Serial.print(F(" -199"));
      }
      if (i >= -249)
      {
        Serial.print(F(" -249"));
      }
    }
  }
  Serial.println();
}

void loop() {
}

Ausgabe:

Start....

Wert:0

Wert:-10

Wert:-20

Wert:-30

Wert:-40

Wert:-50
Gefunden: -99 -149 -199 -249
Wert:-60
Gefunden: -99 -149 -199 -249
Wert:-70
Gefunden: -99 -149 -199 -249
Wert:-80
Gefunden: -99 -149 -199 -249
Wert:-90
Gefunden: -99 -149 -199 -249
Wert:-100
Gefunden: -149 -199 -249
Wert:-110
Gefunden: -149 -199 -249
Wert:-120
Gefunden: -149 -199 -249
Wert:-130
Gefunden: -149 -199 -249
Wert:-140
Gefunden: -149 -199 -249
Wert:-150
Gefunden: -199 -249
Wert:-160
Gefunden: -199 -249
Wert:-170
Gefunden: -199 -249
Wert:-180
Gefunden: -199 -249
Wert:-190
Gefunden: -199 -249
Wert:-200
Gefunden: -249
Wert:-210
Gefunden: -249
Wert:-220
Gefunden: -249
Wert:-230
Gefunden: -249
Wert:-240
Gefunden: -249
Wert:-250

@stoni99 sollte das mit dem if zu kompliziert sein, machs mit switch case:


void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));

  for (int i = 0; i >= -250; i -= 10)
  {
    Serial.println();
    Serial.print(F("Wert:"));
    Serial.println(i);
    Serial.print(F("Setze:"));
    switch (i)
    {
      case -99 ... -50:
        Serial.print(F(" bit1"));
      case -149 ... -100:
        Serial.print(F(" bit2"));
      case -199 ... -150:
        Serial.print(F(" bit3"));
      case -249 ... -200:
        Serial.print(F(" bit4"));
        break;
      default:
        Serial.print(F(" kein bit!"));
    }
  }
  Serial.println();
}

void loop() {
}

Möglicherweise habe ich Dich mit dem else auch unnötig irritiert, es geht auch ohne (hemmungslos bei #12 bedient, getestet mit ESP32):

void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println(F("\nStart ..."));

  for (int i = -25; i >= -280; i -= 50)
  {
    byte befehl = 0;
    Serial.print(F("Wert:"));
    Serial.print(i);
    Serial.print('\t');
    if (i <= -50)
    {
      if (i >= -99)  bitSet(befehl, 0);
      if (i >= -149) bitSet(befehl, 1);
      if (i >= -199) bitSet(befehl, 2);
      if (i >= -249) bitSet(befehl, 3);
    }
    byte2bit(befehl);
  }
}

void loop() {
}

void byte2bit( byte wert )
{
  char zchn[] = {"00000000"};
  for (byte j = 0; j < 8; j++)
  {
    if ( bitRead(wert, 7 - j) ) zchn[j] = '1';
  }
  Serial.println(zchn);
}

Ausgabe:

Start ...
Wert:-25	00000000
Wert:-75	00001111
Wert:-125	00001110
Wert:-175	00001100
Wert:-225	00001000
Wert:-275	00000000

Ob das mit den Bits so gedacht ist?

@stoni99
bevor da weiter rumgeraten wird, ob ein if else funktioniert und was das break macht bzw. was passiert wenn es nicht gesetzt ist, würde ich an deiner Stelle erst mal auf Papier eine Tabelle machen was denn nun genau bei welchem Wert gesetzt werden soll.

Wenn man es auf Papier hat, kann man danach programmieren.
Rumtüfteln und rumraten bringt nicht viel.

Ich werde da nochmal tief in mich gehen!:hugs:

Meine Codes waren noch nicht fertig - ich habe erst mal etwas rumprobiert. Das sieht sicherlich wirr aus - sorry.:open_mouth:

Grundsätzlich werden die Relais per bit kaskadiert.
Relais1 50W
Relais2 100W
Relais3 200W
Relais4 200W
.
Relais6 200W

Die vorgegebene Leistung0 wird gelesen und, um z.B auf einen Sollwert von -350W zu kommen muss Relais 1 & 2 & 3 per bit gesetzt/gesendet werden. -450W 1 & 3 & 4.

Ich hoffe ich habe mich einigermaßen ausgedrückt.:grin:

Ich probiere das noch mal in Ruhe durch. :sunny:
Erst mal Danke für eure Geduld! :pray:

Na dann ist doch meine Logik richtig.
Nimm was Du willst, ich würde das switch case nehmen - aber das ist meine Geschmackssache.
Das if geht ja wohl auch, wie sich die hemmungslose Bedienung von @agmue darstellt. :slight_smile:

Ist es denn wirklich gewollt, dass bei z.B. dem größten Wert alle vier Bedingungen zutreffen? Oder soll bei jedem Wert nur eine Bedingung zutreffen und nur ein Bit(Wert) gesetzt werden?

Na sicher :wink:

Naja .. man könnte ja auch 8 Bits einzeln setzen und danach die Entscheidung treffen, was geschaltet wird. Das ginge ja bis 8 Relais....
Wäre möglicherweise ein bisschen schneller... aber das spielt wahrscheinlich keine Rolle.