Serial input not what I expected

I’m still pretty fresh to all this. I have a series of 5 blinking lights and a function with a case statement that I want to use to change the style of the blinking lights based on the input of an integer to the serial connection. The problem is that when I go the the arduino serial monitor and type in 1 or 2 and press “Send” it responds saying I typed something like 49. I’m guessing I don’t know what I’m doing so I submit my code for review. It’ll probably look very familiar as I’ve borrowed code from lots of places.

int lightArray[] = { 11, 9, 6, 5, 3 };
int timer = 100;
int count = 0;
int style = 2;

void setup()                      // run once, when the sketch starts
{
  for (count=0; count<6; count++)  // setup the pins for output
  {
   pinMode(lightArray[count], OUTPUT);
  }
  Serial.begin(9600);             // tell arduino to start up serial comms
}
  
void loop()                       // run over and over again
{
  for (count=0; count<6; count++) // iterate over pins 
  {
    blink(count, style);          // blink the pin you want in the style you want
  }
  
  for (count=5; count>0; count--)  // iterate over pins in reverse order
  {
    blink(count, style);
  }
  
  style = styleCheck();             // check to see if the preferred style has changed
}

int styleCheck()                   // get the style input from the serial port
{
  int input = style;
  Serial.println("Which style? (0-3)");
  
  if( Serial.available() ){
    input = (int)Serial.read();
  }
  
  Serial.println(input);
  return input;
}

void blink(int pin, int type)        // blink lights according to the chosen style
{
  switch (type) {
    
    case 1:
      digitalWrite(lightArray[pin], HIGH);
      delay(timer);
      digitalWrite(lightArray[pin + 1], HIGH);
      delay(timer);
      digitalWrite(lightArray[pin], LOW);
      delay(timer*2);
      break;
      
    case 2:
      digitalWrite(lightArray[pin], HIGH);
      delay(timer);
      digitalWrite(lightArray[pin + 1], HIGH);
      delay(timer);
      digitalWrite(lightArray[pin], LOW);
      delay(timer);
      digitalWrite(lightArray[pin + 1], LOW);
      delay(timer);
      break;
      
    default:
      digitalWrite(lightArray[pin], HIGH);
      delay(timer*5);
      digitalWrite(lightArray[pin], LOW);
      delay(timer);
  }
}

When you hit "1", you're sending the ASCII code for the character "1", which is 0x31, or 49 decimal. When you hit "2", you're sending ASCII "2", which is 0x32, or 50 decimal. Decimal digits run from "0" which is 0x30 (decimal 48) to "9" which is 0x30 + 9 = 57 .

If you subtract 48 from "input" in "styleCheck" "return input -48;" you should be OK.

That int casting you're doing for the input is just pulling in the value of the ASCII character as your int. Aka 1 = 49 in ascii. You need to pull it in as a string and use something like

 inputInt = atoi(input);

atoi converts strings to integers. Should fix you right up, cheers!

I wouldn't recommend AWOL's method if you're going to use more than a single character input. If it's only 0-9 then go for it but otherwise you'll have to read individual characters, look for an escape character, parse the data, then combine them back to a single int.

Thanks guys, I was starting to realize a pattern and you guys jump me forward a bit of thinking. That atoi() stuff is very good to know. :-)

Strictly speaking, “atoi” works on strings, not characters.

“int atoi(const char *str)”

I wouldn’t recommend AWOL’s method

I would - unless you’re inputting a string, which you’re not.

EDIT:

int styleCheck()                   // get the style input from the serial port
{
  int input = style;
  Serial.println("Which style? (0-3)");
  
  if( Serial.available() ){
    input = (int)Serial.read();
  }
  
  Serial.println(input);
  return input;
}

should probably read:

int styleCheck()                   // get the style input from the serial port
{
  int input = style;
  Serial.println("Which style? (0-3)");
  
  if( Serial.available() ){
    int temp = (int)Serial.read();
    if ( (temp >= '0') && (temp <= '3')) {
      input = temp - 0x30;
      Serial.println(input, DEC);
    } else {
       Serial.println ("??");
    }
  }
  return input;
}