Simple variable question

I'm trying to read information from the keyboard via the Serial.read function, but i cant figure out the proper variable type. I want to be able to say "Hey user! Tell me the angle of the servo!". Right now I've been using int pos =Serial.read(); and I'm getting odd numbers.

How can I get "20" when I type "20" on the keyboard?

Your call to to Serial.read() returns an integer value of each ASCII character you send down the serial port from the Arduino IDE. For a table of the corresponding numeric values of each character, see this page.

So, if you type "20" in the serial monitor window, successive calls to Serial.Read() will return the numbers 50 then 48. Your program then needs to unravel those values and convert them back into an integer value.

You will also need to first check to see when input is available on the serial port input, via Serial.available().

Check out some of the examples here.

Yeah, thats my issue. How do i convert a DEC to asci character?

I suppose i could just save each digit and subtract 48, then how can i put them together? (1+4+5=145)

...after further thought and hitting myself in the head a few times i could just declare pos at a char. But i'm still left with 1+4+5=145.

has anyone tried this?

http://arduiniana.org/libraries/pstring/

You have to know how many digits you have and then you can do some math to multiply each one by the correct power of ten and add them up.

So, if you know they are all numeric digits, you can subtract 48 from each digit's value and then multiply and add.

For an example, say you have three digits. It would be something like:

if (Serial.available ()) int d100 = Serial.read () - 48;
if (Serial.available ()) int d10  = Serial.read () - 48;
if (Serial.available ()) int d1   = Serial.read () - 48;
int value = (d100 * 100) + (d10 * 10) + d1;

but only if you knew ahead of time to expect exactly three digits!

For a real program there are much better ways to code this; I was just using the snippet to illustrate the logic.

Make sense?

If you terminate the string, you can use the atoi or atol functions to perform the conversion.

Or replace your code with something like:

int d = 0;
if(Serial.available()>=3)
{
   for(int i=0;i<3;i++)
  {
      d*=10;
      d+= Serial.read() - '0';
   }
}

which reads three digits into variable d.

has anyone tried this?
PString | Arduiniana

I have. It's awesome! But it's really designed for rendering values into strings, not the other way around.

-- Mikal, the author :slight_smile:

Below is the code ive got so far. Sadly the math is wrong once i get into triple digits. Any idea why?

void loop()
{
long total = 0;
int pos =0;
int figure =0;
// read the sensor:
if (Serial.available() > 0)
{
delay(15); //delay so it has time to read all in buffer
int av = Serial.available();
Serial.print(av);
Serial.println(" bytes are availible");
for (int counter = 0; counter < av; counter++)
{
pos = Serial.read();
Serial.print("At position ");
figure=av-1-counter;
Serial.print(figure);
Serial.print(" you said pos = ");
pos=pos-48;
Serial.print(pos);
long temp = pow(10,figure);
Serial.print ("(temp = ");
Serial.print (temp);
Serial.print (")");
total = total+pos*temp;
Serial.print(" Totaling ");
Serial.println(total);
}
}
}

Sadly the math is wrong once i get into triple digits. Any idea why?

You don't say in what way it is "wrong".

(Can you please use the "Code" (#) button when posting code?)

Hi Rob--

You shouldn't use pow() for an operation like this, because pow() is a floating point library function and, as such, consumes a lot of resources and can introduce inaccuracies. Fortunately, you don't need it. Try something like the below instead. Also, instead of

pos=pos-48;

it's much clearer to write the equivalent

pos=pos-'0';

or, more concisely still

pos -= '0';

void loop() 
{
 long total = 0;
 int pos = 0;
 int figure = 0;
 // read the serial port:
 if (Serial.available() > 0)
 {
   delay(15);  //delay so it has time to read all in buffer
   int av = Serial.available();
   Serial.print(av);
   Serial.println(" bytes are available");
   for (int counter = 0; counter < av; counter++) 
   {
     pos = Serial.read();
     Serial.print("At position ");
     figure = av-1-counter;
     Serial.print(figure);
     Serial.print(" you said pos = ");
     pos -= '0';
     Serial.print(pos);
     total = 10 * total + pos;
     Serial.print(" Totaling ");
     Serial.println(total);
   }
 } 
}

Hope that helps.

Mikal

Or, make your own power function:

[UNTESTED GENERIC RECURSIVE FUNCTION]

template<typename T>
T power( T base, int exponent ) {
  if (exponent==0){ return (T)1; }
  return ( power(base , exponent-1) * base );
}

:slight_smile: