"Switch" a "case" nějak nefungují

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Odpovědět
AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

"Switch" a "case" nějak nefungují

Příspěvek od AstroMiK » 07 bře 2020, 21:10

Prosím,
najděte mi někdo chybu v následujícím programu.


Očekávaná funkce:

V sériovém terminálu zadám "n98765" (bez uvozovek) a zobrazí se odpověď :

Kód: Vybrat vše

*** CISLO ***
98765
V sériovém terminálu zadám "l4,0" a zobrazí se odpověď :

Kód: Vybrat vše

*** LED ***
4
0

Až sem to funguje.
Ale teď to přichází:

V sériovém terminálu zadám "b54" a měla by se zobrazit odpověď :

Kód: Vybrat vše

*** BARGRAF ***
54

Ve skutečnosti se nezobrazí nic.
A přitom je to v podstatě úplně stejná část kódu, jako při zadávání čísla ("n98765"), která funguje bez problému.

A dále:
V sériovém terminálu zadám "xxx" a měla by se zobrazit odpověď :

Kód: Vybrat vše

*** NEZNAMA FUNKCE ***
Ani tady se ale nic nezobrazí.


Já už tam žádnou chybu nevidím.
Paměti RAM i ProgMEM jsou v pořádku (využitých asi 10%).
Závorky ani středníky v kódu nechybí - kompilace proběhne bez problémů.
Všechny case jsou správně ukončeny breakama (kromě posledního defaultu).

Vypadá to, jakoby nějak nefungovala ta konstrukce SWITCH - CASE.
Nebo má nějaké omezení, o kterém nevím.


NEFUNKČNÍ KÓD je tady:

Kód: Vybrat vše

long vstup;                                           // cislo zadavane pres seriovou linku 

void setup()
  {
    Serial.begin(9600); 
  }


void loop()
  { 
    if (Serial.available())
      {
        delay(50);
        
        char funkce = Serial.read();                  // prvni zadany znak udava funkci ('n', 'l', 'b')
        switch (funkce)
          {
            case 'n':                                 // podprogram pro zobrazeni cisla 
              vstup = Serial.parseInt();              //  (volba cisla -9999 az 99999)
              zobraz_cislo(vstup);
            break;

            case 'l':                                 // podprogram pro rozsveceni a zhasinani LED
              vstup = Serial.parseInt();              //  (volba LED 0 az 7)
              boolean sviti = Serial.parseInt();      //  (volba stavu prislusne LED: 0 nebo 1)
              zobraz_LED(vstup,sviti);
            break;

            case 'b':                                 // podprogram pro nastaveni bargrafu
              vstup = Serial.parseInt();              //   (volba hodnoty bargrafu 0 az 100)
              zobraz_bargraf(vstup);
            break;

            default:                                  // jakykoliv jiny uvodni znak by se mel zahlasit jako neznama funkce
              Serial.println("*** NEZNAMA FUNKCE ***");
          }

        while (Serial.available())                    // zbytek znaku se z prijimaciho serioveho bufferu vymaze
          {          
            Serial.read();     
          }

      }
  }



void zobraz_LED(long cislo_LED, boolean stav)
  {
    Serial.println("*** LED ***");
    Serial.println(cislo_LED);
    Serial.println(stav);   
  }

void zobraz_bargraf(long cislo)
  {
    Serial.println("*** BARGRAF ***");  
    Serial.println(cislo);
  }

void zobraz_cislo(long cislo)
  {
    Serial.println("*** CISLO ***");
    Serial.println(cislo);   
  }



-----------------------

Když tu konstrukci switch - case přepíšu pomocí jednoduchých podmínek IF ... , tak to funguje.
Funkční hlavní smyčka:

Kód: Vybrat vše

void loop()
  { 
    if (Serial.available())
      {
        delay(50);
        
        char funkce = Serial.read();                  // prvni zadany znak udava funkci ('n', 'l', 'b')
        if (funkce == 'n')
          {
            vstup = Serial.parseInt();              //  (volba cisla -9999 az 99999)
            zobraz_cislo(vstup);
          }

        if (funkce == 'l')
          {
            vstup = Serial.parseInt();              //  (volba LED 0 az 7)
            boolean sviti = Serial.parseInt();      //  (volba stavu prislusne LED: 0 nebo 1)
            zobraz_LED(vstup,sviti);
          }

         if (funkce == 'b')
          {
            vstup = Serial.parseInt();              //   (volba hodnoty bargrafu 0 az 100)
            zobraz_bargraf(vstup);
          }

         if (funkce != 'n' and funkce != 'l' and funkce != 'b')
           {
              Serial.println("*** NEZNAMA FUNKCE ***");
           }

        while (Serial.available())                    // zbytek znaku se z prijimaciho serioveho bufferu vymaze
          {          
            Serial.read();     
          }

      }
  }

RomanB
Příspěvky: 90
Registrován: 04 zář 2017, 14:28
Reputation: 0
Bydliště: Havířov

Re: "Switch" a "case" nějak nefungují

Příspěvek od RomanB » 07 bře 2020, 22:34

Arduino IDE 1.8.5 mi projekt se SWITCH CASE nechce přeložit,
chyba
crosses initialization of 'boolean sviti'
na řádku
boolean sviti = Serial.parseInt();
S projektem s IF no problem.

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: "Switch" a "case" nějak nefungují

Příspěvek od AstroMiK » 07 bře 2020, 23:02

To je zajímavý.
Já mám taky verzi IDE 1.8.5 a přeloží se to bez problému (akorát to pak v Arduinu nefunguje).

....

Na základě toho chybového hlášení jsem zkusil proměnnou 'sviti' nadeklarovat jako globální a už to šlape.
Tak jsem zkusil ještě hledat a našel jsem, že v konstrukci Switch / Case nesmí být deklarace proměnných.

DÍKY za nakopnutí...

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: "Switch" a "case" nějak nefungují

Příspěvek od AstroMiK » 07 bře 2020, 23:25

... a ještě jedno zjištění.

Problém se dá vyřešit uzavřením té problémové CASE větve do závorek:

Kód: Vybrat vše

...

            case 'l':                                // podprogram pro rozsveceni a zhasinani LED
              {
                vstup = Serial.parseInt();           //  (volba LED 0 az 7)
                boolean sviti = Serial.parseInt();   //  (volba stavu prislusne LED: 0 nebo 1)
                zobraz_LED(vstup,sviti);
                break;
              }


...

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: "Switch" a "case" nějak nefungují

Příspěvek od ondraN » 08 bře 2020, 07:35

To omezení je celkem jasné. v C a C++ je platnost proměnné dána blokem složených závorek. V rámci toho bloku musí bý deklarace nepodmíněná. Pokud byla deklarace v jedné větvi case, tak nebylo dodrženo, že je platná i v ostatní části bloku mezi {}. Jakmile jsi tam dal ty závorky, je to pro překladač jasné. Kdo začínal s C, tak s tím moc problémy nemá, potože tam je ta deklarace omezenější (nejde třeba deklarovat proměnnou v inicializační části for). V C++ je tohle volnější a člověk na to snáze zapomene.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 12 hostů