Maximum number of cases in switch?

Hi,

Do you know if there a limit with the number of "case" in a switch-case statement?

Less than 10 cases no problem. If more I have runtime problems..

Thanks
Fulvio

You should post your code. There should not be a problem with 11 case statements. Does your code compile cleanly and have you eyeballed it to see that it really tries to do what you think it does? Try stripping your code down to isolate the problem. What exactly does your code do that you think is wrong?

Apparently lots is the answer!

I've used about 20 before on a different compiler in C with no problems.

http://www.cplusplus.com/forum/general/27965/

Apparently lots is the answer!

There is virtually no limit on the number of cases, but there IS a limit on how much memory the Arduino has, and that limit is easily exceeded if the cases include a lot of function calls or variables or constant strings.

void loop() 
{
  while( Serial.available() > 0)
  {
    int byteIn = Serial.read();
    Serial.print("Received: ");
    Serial.println(byteIn,BYTE);
    switch(byteIn)
    {
      case 'P':
        Serial.print("Sending TV Power...\n");
        for(int i = 0; i < 4; i++)
        {
          irsend.sendRaw(S_pwr,68,38);
        }
        Serial.print("Sent.\n");
        break;
      case '0':
        Serial.print("Sending 0...\n");
        irsend.sendRaw(S_0,68,38);
        Serial.print("Sent.\n");
        break;
      case '1':
        Serial.print("Sending 1...\n");
        irsend.sendRaw(S_1,68,38);
        Serial.print("Sent.\n");
        break;
      case '2':
        Serial.print("Sending 2...\n");
        irsend.sendRaw(S_2,68,38);
        Serial.print("Sent.\n");
        break;
      case '3':
        Serial.print("Sending 3...\n");
        irsend.sendRaw(S_3,68,38);
        Serial.print("Sent.\n");
        break;
      case '4':
        Serial.print("Sending 4...\n");
        irsend.sendRaw(S_4,68,38);
        Serial.print("Sent.\n");
        break;
      case '5':
        Serial.print("Sending 5...\n");
        irsend.sendRaw(S_5,68,38);
        Serial.print("Sent.\n");
        break;
      case '6':
        Serial.print("Sending 6...\n");
        irsend.sendRaw(S_6,68,38);
        Serial.print("Sent.\n");
        break;
      case '7':
        Serial.print("Sending 7...\n");
        irsend.sendRaw(S_7,68,38);
        Serial.print("Sent.\n");
        break;
      case '8':
        Serial.print("Sending 8...\n");
        irsend.sendRaw(S_8,68,38);
        Serial.print("Sent.\n");
        break;
      case '9':
        Serial.print("Sending 9...\n");
        irsend.sendRaw(S_9,68,38);
        Serial.print("Sent.\n");
        break;
      case 'U': // channel up
        Serial.print("Sending ChaAnnel UP...\n");
        irsend.sendRaw(S_pup,68,38);
        Serial.print("Sent.\n");
        break;
      case 'D': // channel down
        Serial.print("Sending Channel DOWN...\n");
        irsend.sendRaw(S_pdown,68,38);
        Serial.print("Sent.\n");
        break;
      case 'A': // volume up
        Serial.print("Sending Volume UP...\n");
        irsend.sendRaw(S_vup,68,38);
        Serial.print("Sent.\n");
        break;
      case 'Z': // volume up
        Serial.print("Sending Volume DOWN...\n");
        irsend.sendRaw(S_vdown,68,38);
        Serial.print("Sent.\n");
        break;
        
        
      default:
        Serial.print("Something wrong!\n");
    }

    Serial.print("------------------------------\n");
    Serial.print("- SAMSUNG Remote Controller. -\n");
    Serial.print("------------------------------\n");
    Serial.print("Remote Commands:\nP) TV Power\nA) Volume UP\nZ) Volume Down\nU) Channel UP\nD) Channel DOWN\n");  
  }
}

If I remove case from '9' to 'Z' it works and Serial print right messages!

If I keep all cases it works too but Serial print strange chars like:

¼¼Ü¼¼Ü¼¼A
?Â?¼Ü¼Â?¼¼¼Â¼¼¼¼¼¼Ü¼Ü¼¼Ü¼?¼¼Ü¼?¼¼¼Â?¼¼Ü¼?¼¼Â¼¼¼¼Â?Â?Â?¼Ü¼¼Ü¼?¼Ü¼¼Ü¼¼U
¼¼Ü¼Ü¼¼Ü¼

In my mind there might be two answers. First, the technical one is probably hardware limited by SRAM or FLASH memory capacity or possibly some compiler imposed limit.

The second would be a more practical one of being able to be able to make the sketch readable and understandable. If I can't see all the case tests on one or two source screens I would probably think how I might restructure the main program flow to make it more compact. As each case test can call external functions if required, there is still room for a case structure with lots of elements in a relatively small space.

Maybe it's just me as a style preference, but I put lots of effort (later after lots of individual function testing) into making setup and loop functions as small as possible and rely on functions external to setup and loop to hold the bulk of the command statements and library calls.

Lefty

Once you know that one or two cases are invoked correctly, it is reasonable to assume that the rest of them will be, too.

So, the Serial.print() statements, which use up a lot of SRAM are not really needed, are they? If you still think that they are, make them as short as possible. "Sending 1..." really doesn't convey any more information than "1", but consumes 12 times as much SRAM.

Don't do this:-

int byteIn = Serial.read();

You are defining a variable for every byte you read in that loop. Instead define the byteIn variable at the start of the loop() and just do:-

byteIn = Serial.read();

in your while loop.
It might not solve the problem you have now but one day it could lead you into trouble.

Hi guys!
As you suggest I tryed to put switch-case statement into a function.
To check if it is a memory leaking problem I removed a lot of Serial.print() but the problem persists!
If I remove 5 case-statements ( doesn't matter which ones ) it works.
Here the code:

void loop() 
{
  if ( Serial.available() > 0 )
  {
    sendRemoteCommand(Serial.read());
  }  
}

void sendRemoteCommand(int com)
{
  Serial.print("Sending ");
  switch(com)
  {
    case 'P':
      Serial.print("TV Power.\n");
      for(int i = 0; i < 4; i++)
      {
        irsend.sendRaw(S_pwr,68,38);
      }
      break;
    case '0':
      Serial.print("0.\n");
      irsend.sendRaw(S_0,68,38);
      break;
    case '1':
      Serial.print("1.\n");
      irsend.sendRaw(S_1,68,38);
      break;
    case '2':
      Serial.print("2.\n");
      irsend.sendRaw(S_2,68,38);
      break;
    case '3':
      Serial.print("3.\n");
      irsend.sendRaw(S_3,68,38);
      break;
    case '4':
      Serial.print("4.\n");
      irsend.sendRaw(S_4,68,38);
      break;
    case '5':
      Serial.print("5.\n");
      irsend.sendRaw(S_5,68,38);
      break;
    case '6':
      Serial.print("6.\n");
      irsend.sendRaw(S_6,68,38);
      break;
    case '7':
      Serial.print("7.\n");
      irsend.sendRaw(S_7,68,38);
      break;
    case '8':
      Serial.print("8.\n");
      irsend.sendRaw(S_8,68,38);
      break;
    case '9':
      Serial.print("9.\n");
      irsend.sendRaw(S_9,68,38);
       break;
   case 'U': // channel up
      Serial.print("Ch UP.\n");
      irsend.sendRaw(S_pup,68,38);
      break;
    case 'D': // channel down
      Serial.print("Ch DOWN.\n");
      irsend.sendRaw(S_pdown,68,38);
      break;
    case 'A': // volume up
      Serial.print("Vol UP.\n");
      irsend.sendRaw(S_vup,68,38);
      break;
    case 'Z': // volume up
      Serial.print("Vol DOWN.\n");
      irsend.sendRaw(S_vdown,68,38);
      break;     
    default:
      Serial.print("??\n");
  }
  Serial.print("------------------------------\n");
  Serial.print("- SAMSUNG Remote Controller. -\n");
  Serial.print("------------------------------\n");
  Serial.print("Remote Commands:\nP) TV Power\nA) Volume UP\nZ) Volume Down\nU) Channel UP\nD) Channel DOWN\n");  
}

What device are you running this on?

Try removing (or greatly shortening) these lines and see what happens:

  Serial.print("------------------------------\n");
  Serial.print("- SAMSUNG Remote Controller. -\n");
  Serial.print("------------------------------\n");
  Serial.print("Remote Commands:\nP) TV Power\nA) Volume UP\nZ) Volume Down\nU) Channel UP\nD) Channel DOWN\n");

Can you post your whole sketch? What you have posted doesn't compile. Then we can analyze further.

Isn't there a "freemem" kind of command to see if all the SRAM is being used up?
I used 16
case '0' thru case 'f'
with no issue on a '328, but I also used very few serial print statements.

I'm using Arduino UNO.

Probably the are no limits to a number of "case".

The problem is on irsend instance.
If I comment just each "irsend.sendRaw(x,68,38);" I've no problem with Serial.print().
So i think IRremote library would be bug-affected... but it's very strange. I'm going to spend time to check it!

F.

So i think IRremote library would be bug-affected

Sure. That's why so many people have trouble with it. If you search the forum, you'll see that the only people having trouble with the library are either not understanding how to use it or have a boatload of Serial.print() statements, too.

Coincidence? I don't think so.

Another vote for post the whole sketch - I'd like to see how big those strings are (s_0, s_1 etc).

Here the entire code:

#include <IRremote.h>

const unsigned int BAUD_RATE = 9600;

// Power ON/OFF
unsigned int S_pwr[68]={4600,4350,700,1550,650,1550,650,1600,650,450,650,450,650,450,650,450,700,400,700,1550,650,1550,650,1600,650,450,650,450,650,450,700,450,650,450,650,450,650,1550,700,450,650,450,650,450,650,450,650,450,700,400,650,1600,650,450,650,1550,650,1600,650,1550,650,1550,700,1550,650,1550,650};

// channel 1 
unsigned int S_1[68]={4650,4300,700,1550,700,1550,650,1550,700,400,700,400,700,400,700,450,700,400,700,1500,700,1500,700,1550,700,450,650,400,700,450,650,450,700,400,700,400,700,450,650,1550,700,400,700,400,700,400,700,450,650,450,650,1550,700,1500,700,450,650,1550,700,1550,650,1550,700,1500,700,1550,650};

// channel 2
unsigned int S_2[68]={4600,4350,650,1550,700,1500,700,1550,700,400,700,400,700,450,650,450,700,400,700,1500,700,1500,700,1550,700,400,700,450,650,450,700,400,700,400,700,1500,700,400,700,1550,700,400,700,400,700,450,650,450,700,400,700,400,700,1550,650,450,700,1500,700,1550,650,1550,700,1500,700,1550,650};

// channel 3
unsigned int S_3[68]={4600,4350,700,1500,700,1550,650,1600,650,400,700,450,700,400,700,400,700,400,700,1550,650,1550,700,1500,700,400,700,450,700,400,700,400,700,400,700,400,700,1550,700,1500,700,450,650,450,700,400,700,400,700,400,700,1550,700,400,700,400,700,1550,650,1550,700,1500,700,1550,700,1500,700};

// channel 4
unsigned int S_4[68]={4600,4350,650,1550,700,1500,700,1550,700,400,700,400,700,450,650,450,700,400,700,1500,700,1550,650,1550,700,400,700,450,650,450,700,400,700,400,700,400,700,400,700,450,650,1550,700,400,700,400,700,450,700,400,700,1500,700,1550,650,1550,700,400,700,1550,650,1550,700,1500,700,1550,650};

// channel 5
unsigned int S_5[68]={4650,4350,700,1500,700,1550,650,1550,700,400,700,450,700,400,700,400,700,400,700,1500,700,1550,700,1500,700,450,650,450,700,400,700,400,700,400,700,1550,700,400,700,400,650,1550,700,450,650,450,700,400,700,450,650,450,650,1550,650,1550,700,400,700,1550,700,1500,700,1500,700,1550,700};

// channel 6
unsigned int S_6[68]={4600,4350,650,1550,700,1500,700,1550,700,400,700,400,700,450,650,450,700,400,700,1500,700,1550,650,1550,700,400,700,450,700,400,700,400,700,400,700,400,700,1550,700,400,700,1500,700,450,650,450,700,400,700,400,700,1550,650,450,650,1550,700,400,700,1550,650,1550,700,1500,700,1550,650};
 
// channel 7
unsigned int S_7[68]={4600,4350,700,1500,700,1550,650,1550,700,400,700,450,700,400,700,400,700,400,700,1550,650,1550,700,1500,700,400,700,450,700,400,700,400,700,400,700,450,650,450,650,1550,700,1500,700,450,700,400,700,400,700,450,650,1550,650,1550,700,450,650,400,700,1550,700,1500,700,1550,650,1550,700};
 
// channel 8
unsigned int S_8[68]={4600,4350,650,1600,650,1500,700,1550,700,400,700,400,700,400,700,450,700,400,700,1500,700,1550,650,1550,700,400,700,450,650,450,700,400,700,400,700,1550,650,450,650,1550,700,1500,700,450,700,400,700,400,700,400,700,400,700,1550,700,400,700,450,650,1550,650,1550,700,1500,700,1550,650};
 
// channel 9
unsigned int S_9[68]={4600,4350,700,1500,700,1550,650,1550,700,400,700,450,650,450,650,450,700,400,700,1500,700,1550,700,1550,650,400,700,450,700,400,700,400,700,400,700,450,650,1550,650,1600,650,1550,650,450,700,400,700,400,700,400,700,1550,700,400,700,400,700,400,700,1550,700,1500,700,1500,700,1550,700};
 
// channel 0
unsigned int S_0[68]={4650,4300,700,1550,700,1500,700,1550,700,400,700,400,700,400,700,450,650,450,650,1550,700,1550,650,1550,700,400,700,400,700,400,700,450,700,400,700,1550,650,400,700,450,700,400,650,1550,700,400,700,450,700,400,700,400,700,1500,700,1550,700,1500,700,400,700,1550,650,1550,700,1500,700};
 
// source
unsigned int S_scr[68]={4600,4350,700,1550,650,1550,700,1500,700,450,650,450,700,400,700,400,700,400,700,1550,700,1500,700,1550,700,400,700,400,700,400,700,400,700,400,700,1550,700,400,700,450,650,450,650,450,700,400,700,400,700,400,700,450,650,1550,700,1500,700,1550,650,1550,700,1500,700,1550,700,1500,700};
 
// channel up
unsigned int S_pup[68]={4600,4350,700,1500,700,1500,700,1550,700,450,650,400,700,450,650,450,700,400,700,1500,700,1550,650,1550,700,450,650,450,700,400,700,400,700,400,700,400,700,1550,700,400,700,400,700,1550,650,450,700,400,700,400,700,1550,650,450,650,1600,650,1550,650,450,700,1500,700,1500,700,1550,650};
 
// channel down
unsigned int S_pdown[68]={4650,4300,700,1550,700,1500,700,1550,700,400,700,400,700,400,700,450,650,450,650,1550,700,1500,700,1550,700,400,700,400,700,400,700,450,700,400,700,400,700,400,700,450,650,450,650,1550,700,400,700,450,650,400,700,1550,700,1500,700,1550,700,1500,700,400,700,1550,650,1550,700,1500,700};
 
// volume up
unsigned int S_vup[68]={4600,4350,650,1550,700,1500,700,1550,700,400,700,400,700,450,650,450,700,400,700,1500,700,1550,650,1550,700,400,700,400,700,450,650,450,700,400,700,1500,700,1550,650,1550,700,400,700,450,700,400,700,400,700,400,700,450,650,450,650,450,650,1550,700,1500,700,1550,700,1500,700,1550,650};

// volume down
unsigned int S_vdown[68]={4600,4350,700,1550,650,1550,700,1500,700,450,650,450,700,400,700,400,700,400,700,1550,700,1500,700,1550,700,400,700,400,700,400,700,450,650,450,650,1550,700,1500,700,450,650,1550,700,400,700,400,700,450,700,400,700,400,700,400,700,1550,700,400,700,1500,700,1500,700,1550,700,1500,700};

// TV/DTV
unsigned int S_tv[68]={4600,4350,650,1550,700,1500,700,1550,700,400,700,400,700,400,700,450,700,400,700,1500,700,1500,700,1550,700,400,700,400,700,450,650,450,700,400,700,1500,700,1550,700,400,700,400,700,400,700,400,700,1550,700,400,700,400,700,400,700,1550,700,1500,700,1550,650,1550,700,400,700,1500,700};
 
// guide
unsigned int S_guide[68]={4600,4350,700,1500,700,1550,700,1500,700,450,650,450,700,400,700,400,700,400,700,1550,650,1550,700,1500,700,450,650,450,700,400,700,400,700,400,700,1550,700,1500,700,1550,650,1550,700,400,700,400,700,1550,700,400,700,400,700,400,700,450,700,400,650,1550,700,1550,650,450,700,1500,700};

// exit
unsigned int S_exit[68]={4650,4300,700,1550,650,1550,700,1550,700,400,700,400,700,450,650,450,650,450,650,1550,700,1500,700,1550,700,450,650,400,700,450,650,450,700,400,700,1500,700,400,700,1550,700,1500,700,400,700,1550,700,450,650,400,700,450,650,1550,700,400,700,400,700,1550,650,450,650,1550,700,1500,700};
 
// mute
unsigned int S_mute[68]={4650,4350,650,1550,650,1550,700,1550,700,400,700,400,700,400,700,450,650,450,650,1550,700,1500,700,1550,700,400,700,450,650,400,700,450,700,400,700,1500,700,1550,650,1550,700,1500,700,450,700,400,700,400,700,400,700,400,700,450,650,450,700,400,700,1500,700,1550,650,1550,700,1500,700};

IRsend irsend;

void setup()
{
  Serial.begin(BAUD_RATE);
  delay(500);
  while (Serial.available()) {Serial.read();}
  Serial.print("------------------------------\n");
  Serial.print("- SAMSUNG Remote Controller. -\n");
  Serial.print("------------------------------\n");
  Serial.print("Remote Commands:\nP) TV Power\nA) Volume UP\nZ) Volume Down\nU) Channel UP\nD) Channel DOWN\n");
}

void loop() 
{
  if( Serial.available() > 0)
  {
     sendRemoteCommand(Serial.read());
  }
}



void sendRemoteCommand(int com)
{
  Serial.print("Sending ");
  switch(com)
  {
    case 'P':
      Serial.print("TV Power.\n");
      for(int i = 0; i < 4; i++)
      {
        irsend.sendRaw(S_pwr,68,38);
      }
      break;
    case '0':
      Serial.print("0.\n");
      irsend.sendRaw(S_0,68,38);
      break;
    case '1':
      Serial.print("1.\n");
      irsend.sendRaw(S_1,68,38);
      break;
    case '2':
      Serial.print("2.\n");
      irsend.sendRaw(S_2,68,38);
      break;
    case '3':
      Serial.print("3.\n");
      irsend.sendRaw(S_3,68,38);
      break;
    case '4':
      Serial.print("4.\n");
      irsend.sendRaw(S_4,68,38);
      break;
    case '5':
      Serial.print("5.\n");
      irsend.sendRaw(S_5,68,38);
      break;
    case '6':
      Serial.print("6.\n");
      irsend.sendRaw(S_6,68,38);
      break;
    case '7':
      Serial.print("7.\n");
      irsend.sendRaw(S_7,68,38);
      break;
    case '8':
      Serial.print("8.\n");
      irsend.sendRaw(S_8,68,38);
      break;
    case '9':
      Serial.print("9.\n");
      irsend.sendRaw(S_9,68,38);
       break;
    case 'U': // channel up
      Serial.print("Ch UP.\n");
      irsend.sendRaw(S_pup,68,38);
      break;
    case 'D': // channel down
      Serial.print("Ch DOWN.\n");
      irsend.sendRaw(S_pdown,68,38);
      break;
    case 'A': // volume up
      Serial.print("Vol UP.\n");
      irsend.sendRaw(S_vup,68,38);
      break;
    case 'Z': // volume up
      Serial.print("Vol DOWN.\n");
      irsend.sendRaw(S_vdown,68,38);
      break;
      
    default:
      Serial.print("??\n");
  }
  
  Serial.print("------------------------------\n");
  Serial.print("- SAMSUNG Remote Controller. -\n");
  Serial.print("------------------------------\n");
  Serial.print("Remote Commands:\nP) TV Power\nA) Volume UP\nZ) Volume Down\nU) Channel UP\nD) Channel DOWN\n");  
  
}

You have 20 arrays of 68 ints (or 136 bytes). That's 2,720 bytes. If this is on a 328 based Arduino, it only has 2000 bytes of SRAM.

If you don't actually use an array, it is optimized away (as though it didn't exist).

Since these arrays are read only, you could move them into (and out of, as required) PROGMEM.

Thank you PaulS!

but how can I move them into PROGMEM?

F.

but how can I move them into PROGMEM?

http://www.arduino.cc/en/Reference/PROGMEM

After a quick glance, all the values in those arrays are divisible by 50.
That could save some memory.
At least half.

EDIT: There are only eleven different values in that table (apart from zero). That's a big saving.