Silly char comparison question

Hi all,

being not new to c programming, I wonder why my code always runs into the first if clause. Tomatoes on my eyes?

#include <Servo.h> 

Servo myservo;  
int pos = 0;  
char c = 0;

void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  myservo.write(0);
  Serial.begin(9600);
} 


void loop() 
{ 
  if (Serial.available() > 0)
  {
    c = Serial.read();
    if (c >= '0' && c <= '9')
    {
      pos *= 10;
      pos += c - '0';
    }
    else if (c == '\n')
    {
      Serial.println(pos);
      myservo.write(pos);
      pos = 0;
    }
  }
}

I wonder why my code always runs into the first if clause.

We have no idea what you are sending the Arduino, so how can we answer that question?

You can use Serial.print() to echo the character, if the sending program has a mechanism for reading from the serial port and showing the data. Perhaps that would be a clue-by-four.

Hi,

as I said - always.

It is intended to read decimal chars (hence the c >= ‘0’ && c <= ‘9’) and to convert and add them until a newline or carriage return is read. It works as expected when sending 0-9 only. However, whatever I send is being decoded, sending an ‘a’ + newline returns 49 (which should be ok given that ‘a’ is ascii #65, ‘a’-‘0’ should be 49).

Regards
Matthias

chars are synonymous with bytes, they are an 8-bit integer.

assigning 3 and subtracting two will always equal 1, even when using the ascii equivalents.

literal characters in assignments to char like 'a' just copy the ascii byte-value, it is just raw data.

to represent two or more consecutive characters use an array of chars.

char c_Str[3];

 c_Str[0] = 'a';
c_Str[1] = '\n';

to be semantically correct, use a terminating null

c_Str[2] = '\0';

just to clarify

char *c_Text = "text";

//is equivalent to

char c_Text[] = { 't', 'e', 'x', 't', '\0' };

//or

char c_Text[5];

c_Text[0] = 't';
c_Text[1] = 'e';
c_Text[2] = 'x';
c_Text[3] = 't';
c_Text[4] = '\0';

Other people will have different opinions, but in my opinion you should never rely on implicit operator precedence.

Instead of

if (c >= '0' && c <= '9')

put

if ( (c >= '0') && (c <= '9') )

It won’t make any difference to your code, unless you have made a mistaken assumption about what the precedence is, but it will save you and everyone else having to double check whether the precedence is as you assumed.

mrichwin:
It is intended to read decimal chars (hence the c >= ‘0’ && c <= ‘9’) and to convert and add them until a newline or carriage return is read. It works as expected when sending 0-9 only. However, whatever I send is being decoded, sending an ‘a’ + newline returns 49 (which should be ok given that ‘a’ is ascii #65, ‘a’-‘0’ should be 49).

I can’t reproduce that. Commenting out the server part, and then testing with numbers it works as you said, and with letters (eg. “a” + newline) it prints 0.

mrichwin: until a newline or carriage return is read

   else if (c == '\n')

The way your code is written, it is looking for '\n' ie: newline only, not '\r'. My suggestion, above what PaulS and others recommended, to write out what you've just read in as debugging, is to change this else to simply accept ANYTHING that isn't a digit as being the end of your number.