"Switch statement expects single number values for each case"

Hi Community!
I have a question regards to Digital Write Pin HIGH/LOW
Is it true that you can only activate ON/OFF switch by using a single character when communicating thru USB? If so how would you fully control 53 PINS?
"The switch statement expects single number values for each case;"

Are you referring to the example here: https://www.arduino.cc/en/Tutorial/switchCase2?

The switch statement takes a single integer value. In C char is a type of integer.

Why are you talking about USB?

Yes that will be the sample,
I am communicating thru USB - serial connection to send commands for digital pins
Basically program will define which pins are off or on. "Case" statements seems like an ideal option

Ah, yes so a character is a natural thing to use to name pins. A character can have 256 possible values, should be enough. You might just want to map directly to pin numbers rather than use a huge switch statement, all pin numbers are valid char values.

Thank you for the information,

Question: Is "digitalWrite(VALUE, HIGH);

VALUE accepted as int only? It also translate to DEC on input for example "if I send SPACE I get 32 in return"
Can I actually Send Value as Value which can be used without translation?

It doesn't look like I can use a full string command.....

Please state your full intent along with posting your code in code tag.
Collectively, we are smarter than you, so stop testing us about things you don't know.

Full intent is above: ON/OFF for all 52 switches controlled by software, using USB connection, Serial Interface. Meaning by I type PIN 1 ON, PIN 1 goes ON, PIN 1 OFF, PIN 1 goes OFF.

Either way works for me,

NOT sure what is "testing bla bla bla" means, perhaps you should review the post before responding.

A case can also be a continuous range of integer values, separated by ellipses, thuscase 12 ... 15:

My main problem is I run out of characters to Control the switches as Mark stated there is 256 possibilities which is 8-bit. I don't know How to utilize all of them since "Arduino Reference - Arduino Reference"
only has 127 and even at that I cant utilize them all because some are not typable commands and more responsive to key commands.
On top of that "Serial Read" takes one character at the time... so when I type 12 it translates as 1,2.
I think I missing something really simple here.....

Full intent is above: ON/OFF for all 52 switches controlled by software, using USB connection, Serial Interface. Meaning by I type PIN 1 ON, PIN 1 goes ON, PIN 1 OFF, PIN 1 goes OFF.

If you want to enter Serial messages like "PIN 1 ON" and parse the pin number and state from the message it would serve you well to review Robin2's excellent tutorial on Serial Input Basics.

Klide:
Full intent is above: ON/OFF for all 52 switches controlled by software, using USB connection, Serial Interface. Meaning by I type PIN 1 ON, PIN 1 goes ON, PIN 1 OFF, PIN 1 goes OFF.

You better leave pin 1 alone, it is used for USB communication on a Mega.

const byte maxMsgLen = 32;

const byte cbLF = 10;
const byte cbCR = 13;

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

void loop() {
  static uint8_t bIndex;
  static int8_t buffer[maxMsgLen + 1];
  bool lineReady = false;
  if (Serial.available()) {
    uint8_t inChar = Serial.read();
    if (inChar != cbLF) {
      if (inChar == cbCR) {
        lineReady = true;
      } else {
        buffer[bIndex++] = inChar;
        lineReady = (bIndex == maxMsgLen);
      }
      if (lineReady) {
        buffer[bIndex] = 0;
        bIndex = 0;
        bool syntaxError = true;
        if (!strncmp_P((const char*)buffer, PSTR("PIN "), 4)) {
          char* behind;
          uint32_t val = strtoul((const char*)buffer + 4, &behind, 0);
          if (!strcmp_P(behind, PSTR(" ON")) || !strcmp_P(behind, PSTR(" OFF"))) {
            if (val < 2 || val > 53) {
              Serial.println(F("you can only use pins 2 to 53"));
            } else {
              Serial.print(F("-> digitalWrite("));
              Serial.print(val);
              Serial.print(F(", "));
              Serial.print(behind[2] == 'N' ? F("HIGH") : F("LOW"));
              Serial.println(F(");"));
              syntaxError = false;
            }
          }
        }
        if (syntaxError) {
          Serial.println(F("you have to write 'PIN # (ON|OFF)'"));
        }
      }
    }
  }
}

Whandall:
You better leave pin 1 alone, it is used for USB communication on a Mega.

const byte maxMsgLen = 32;

const byte cbLF = 10;
const byte cbCR = 13;

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

void loop() {
 static uint8_t bIndex;
 static int8_t buffer[maxMsgLen + 1];
 bool lineReady = false;
 if (Serial.available()) {
   uint8_t inChar = Serial.read();
   if (inChar != cbLF) {
     if (inChar == cbCR) {
       lineReady = true;
     } else {
       buffer[bIndex++] = inChar;
       lineReady = (bIndex == maxMsgLen);
     }
     if (lineReady) {
       buffer[bIndex] = 0;
       bIndex = 0;
       bool syntaxError = true;
       if (!strncmp_P((const char*)buffer, PSTR("PIN "), 4)) {
         char* behind;
         uint32_t val = strtoul((const char*)buffer + 4, &behind, 0);
         if (!strcmp_P(behind, PSTR(" ON")) || !strcmp_P(behind, PSTR(" OFF"))) {
           if (val < 2 || val > 53) {
             Serial.println(F("you can only use pins 2 to 53"));
           } else {
             Serial.print(F("-> digitalWrite("));
             Serial.print(val);
             Serial.print(F(", "));
             Serial.print(behind[2] == 'N' ? F("HIGH") : F("LOW"));
             Serial.println(F(");"));
             syntaxError = false;
           }
         }
       }
       if (syntaxError) {
         Serial.println(F("you have to write 'PIN # (ON|OFF)'"));
       }
     }
   }
 }
}

Hello, unfortunately code didn't work.... I also little confused how this can active the switches since Write is in print command, thanks!

cattledog:
If you want to enter Serial messages like "PIN 1 ON" and parse the pin number and state from the message it would serve you well to review Robin2's excellent tutorial on Serial Input Basics.

Thank you! I have reviewed the examples and they are great, however some how value "receivedChars" is NOT usable meaning I can't set statements based on this value and its super confusing since I can clearly see the value in the print... I would think once array is complete I can use this data to compare and do something..

some how value "receivedChars" is NOT usable meaning I can't set statements based on this value and its super confusing since I can clearly see the value in the print... I would think once array is complete I can use this data to compare and do something..

You can definitely extract the information you want from "receivedChars". That part of the process is called "parsing".

If you post your code you will receive assistance. Please read How to Use this Forum to see how to format your code and post it using code tags.

Klide:
...however some how value "receivedChars" is NOT usable meaning I can't set statements based on this value...

receivedChars is an *array * of character values - it is not a numeric value. Scroll down the SIB page and find example #4. This converts the individual ASCII character values you entered to the integer equivalent.

cattledog:
You can definitely extract the information you want from "receivedChars". That part of the process is called "parsing".

If you post your code you will receive assistance. Please read How to Use this Forum to see how to format your code and post it using code tags.

Hi, here is my code I got it working by using Example 2 and specifying Character as String(C++.....) I am NOT to proficient in C++ last time I used this language was a very long time ago... Now I rather don't write a 100 Else If statements for every switch.....". I assume I could extract Integers(1,2,3...) and words "HIGH/LOW" form the string and plug these values in "DirectWrite" Line. I tried to use stream string example but it didn't work... I am not to sure if this even supported since it requires #include #include
As Note PINs HIGHs and LOWs will be a software input it can be even as 2 for Pin 2 to be ON, -2 for Pin 2 to be OFF

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;


void setup() {
    // initialize serial communication:
 Serial.begin(9600);
 Serial.println("<Arduino is ready>");
    for (int thisPin = 2; thisPin >49; thisPin++)
    {
           pinMode(thisPin, OUTPUT);
}
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
   
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
  
    }
     
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        String s = receivedChars;
    if (s =="PIN2ON") {
         digitalWrite(2, HIGH);
         Serial.print("Pin 2 ON\n");
         delay(50);
            } 
    if (s == "PIN2OFF")
{
   digitalWrite(2, LOW);
         Serial.print("Pin 2 OFF\n");
         delay(50);
}  
        newData = false;
    }       
    }

There is an error in this line setting pinModes. You want numbers <49 not >49

for (int thisPin = 2; thisPin <49; thisPin++)
  {
     pinMode(thisPin, OUTPUT);
  }

There is no need to use the String objects. You can use the c-string functions atoi()and strstr() to parse the pinNumber and pinState from the received chars. You can use these values directly in digitalWrite(pinNumber,pinState)

This code assumes you always begin the entry with PIN, then a number, and finally an ON or OFF. More error checking might be useful, but this can get you started.

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;
byte pinNumber;
byte pinState;

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  for (int thisPin = 2; thisPin < 49; thisPin++)
  {
    pinMode(thisPin, OUTPUT);
  }
}

void loop() {
  recvWithEndMarker();
  showNewData();
}

void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    pinNumber = atoi(&receivedChars[3]);//number always after PIN
    if (strstr(receivedChars, "ON"))
      pinState = 1;
    else if (strstr(receivedChars, "OFF"))
      pinState = 0;
    digitalWrite(pinNumber,pinState);
  }
  newData = false;
}

cattledog:
There is an error in this line setting pinModes. You want numbers <49 not >49

for (int thisPin = 2; thisPin <49; thisPin++)

{
    pinMode(thisPin, OUTPUT);
 }




There is no need to use the String objects. You can use the c-string functions atoi()and strstr() to parse the pinNumber and pinState from the received chars. You can use these values directly in digitalWrite(pinNumber,pinState)

This code assumes you always begin the entry with PIN, then a number, and finally an ON or OFF. More error checking might be useful, but this can get you started.



const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;
byte pinNumber;
byte pinState;

void setup() {
 // initialize serial communication:
 Serial.begin(9600);
 Serial.println("");
 for (int thisPin = 2; thisPin < 49; thisPin++)
 {
   pinMode(thisPin, OUTPUT);
 }
}

void loop() {
 recvWithEndMarker();
 showNewData();
}

void recvWithEndMarker() {
 static byte ndx = 0;
 char endMarker = '\n';
 char rc;

while (Serial.available() > 0 && newData == false) {
   rc = Serial.read();

if (rc != endMarker) {
     receivedChars[ndx] = rc;
     ndx++;
     if (ndx >= numChars) {
       ndx = numChars - 1;
     }
   }
   else {
     receivedChars[ndx] = '\0'; // terminate the string
     ndx = 0;
     newData = true;
   }
 }
}

void showNewData() {
 if (newData == true) {
   Serial.print("This just in ... ");
   Serial.println(receivedChars);
   pinNumber = atoi(&receivedChars[3]);//number always after PIN
   if (strstr(receivedChars, "ON"))
     pinState = 1;
   else if (strstr(receivedChars, "OFF"))
     pinState = 0;
   digitalWrite(pinNumber,pinState);
 }
 newData = false;
}

Thanks! This works perfect! Just to confirm so I understood everything correctly "atoi" will take a value after 3 characters and will convert it to integer, in this case it will disregard "ON and OFF" or any other characters that are not the numbers?

strstr will compare and look for "ON or OFF" in the string and return the value accordingly?

Please correct if I misunderstood anything I should defiantly refresh my memory for c, c++ :slight_smile: