How to receive two digit number by Serial.read()!n00b!

void setup() {
  Serial.begin(9600);
}
int get;
void loop () {
      if (Serial.available()>0){
        get = Serial.read(); 
         switch (get) {
           case '1': 
           // do something 
           break;
           case '2': 
           // do something 
           break;
/* 3, 4, 5, 6, 7, 8... */
           case '20': 
           // do something 
           break;
           default: 
           Serial.print("No command\n");
      }
    }
  }

just bought my Arduino I searched for it and read something about atoi() but can't make it work :cold_sweat:
so I ask for your help.

Need to get number 1 to 20 to do some actions but it always gets 1 and 2
so it makes action 1 and action 2 but not the action 20...

Serial.read() gets a single character.

'1' is a single character.
'2' is a single character.
'20' is two characters.

I recommend separating your numbers by some non-numeric character (typically a comma). Then you can read in characters until you see a comma, and pass those characters on to atoi() to get the int value of those characters. Done right, it should be able to handle any size number (though you will still be limited by the size of number int can store, or long if you switch to that datatype).

case '20':

Multicharacter constants are allowed, and are valid, but you're best sticking to decimal values.

case 20:

This subject comes up every other day here, it seems.
Have a look around the forum.

and pass those characters on to atoi()

...plus a terminating '\0'

Can someone please give me a clear example of atoi() working with case?

char buffer [10]; // 9 digits is overkill, I know.

buffer [0] = '1';
buffer [1] = '2';
buffer [3] = '\0';

int val = atoi (buffer);

There's a typo in the previous code example. The line with the null terminator should reference index 2 not 3. Revised code shown below.

char buffer [10]; // 9 digits is overkill, I know.

buffer [0] = '1';
buffer [1] = '2';
buffer [2] = '\0';

int val = atoi (buffer);

Oops, yes, you're quite right.

I've been trying but can't make it work :blush: can only make it work if I only print the result.
can someone please make the required changes so that it works whit case.

char buffer [10]; // 9 digits is overkill, I know.

buffer [0] = '1';  // these assignments are just for illustration, in reality
buffer [1] = '2';  // you would read your input one character at a time
buffer [2] = '\0'; // from Serial.
// be aware, however, that the Serial monitor doesn't send a delimiter at the end of
// input

int val = atoi (buffer);

switch (val)
{

 case 1: break;
 case 2: break; // and so on.
 
}

Your original multicharacter constant approach would work, but it gets a bit tricky beyond two digits for an 'int'

Below is some code i use to test servos which captures a string of characters and converts the string into a number. You might get some ideas from the code.

// zoomkat 10-4-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1);  
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n;
    char carray[6]; //converting string to number
    readString.toCharArray(carray, sizeof(carray));
    n = atoi(carray); 
    myservo.writeMicroseconds(n); // for microseconds
    //myservo.write(n); //for degees 0-180
    readString="";
  } 
}
1 Like