VB => Arduino via serial

I’m trying to send the arduino 3 values from 0-9000. I don’t understand how to get more then 1 digit at a time.

all var are char

void loop()
{

if (Serial.available()>0) {

buff=Serial.read();
if (buff==‘X’) {
Xval=Serial.read(); //<need to be able to read from 0 to 9000
}
if (buff==‘Y’) {
Yval=Serial.read();
}
if (buff==‘Z’) {
Zval=Serial.read();
}

}
Serial.print(buff);
Serial.print(" Xval = “);
Serial.print(Xval);
Serial.print(” Yval = “);
Serial.print(Yval);
Serial.print(” Zval = ");
Serial.println(Zval);
delay(10);

}

A lot depends on HOW the data is written out. Most likely, the value being written is written as a string. So, a value like 8732 is output as '8', '7', '3, and '2'.

To read it back in:

int val = 0;
void loop()
{
   while(Serial.available() > 0)
   {
       val *=10; // 8*10 = 80; 87 * 10 = 870; ...
       val += (Serial.read() - '0'); // '8' - '0' = 8
   }
}

Thanks a bunch, it works.

but i dont understand how? any chance you could explain it a little better?

You are recieving the number 1 byte at a time as chars.

The expression (Serial.read() - '0'); will subtract the ascii value of the char 0 (48) from the ascii value of the char 8 (56) whic is exactly 8

So it is a smart way to convert the ascii value for a single digit to its numerical value.

i understand that part (mostly), its combining the bites '1' '2' '3' into 123 (one hundred and twenty three) that i don't understand.

You read the '1'. You multiply the previous value (0) by 10, and add the new value.

10 * 0 + 1 = 1

You read the '2'. You multiply the previous value (1) by 10, and add the new value.

10 * 1 + 2 = 10 + 2 = 12

You read the '3'. You multiply the previous value (12) by 10, and add the new value.

10 * 12 + 3 = 120 + 3 = 123.

ahh i see it now. last time i tried that method it took almost 20 lines of code (im not very efficient) and it still gave me issues.

I had hoped to find a way to input a string along the lines of “X2000Y4000Z4000” and have the arduino understand that i wanted:
x=2000
y=4000
z=4000

Is there any way to mix numbers and letters?

Thats a bit difficult when the number of digits in each number wil vary from time to time.

But you coud test each of the bytes one at a time, first you expect a letter then 1 to 4 digtis, then a letter then........

Actually, it’s not hard at all, if you add some sort of valid string delimiters.

For instance, if you pass in “”, then, you can start consuming the data when you see a <. The next character tells you where to store the number. The next digit is a number, so val *= 10 and val += character - ‘0’. Same for the next character.

Each time you read a character, you check to see if it is a digit or a letter. It’s a digit if character - ‘0’ is between 0 and 9. Otherwise, it’s a character. The characters tell you where to store the values, unless the character is a >, which tells you that it’s time to use the x, y, and z values.

So i can read the byte as a char, if its between or including 48-57 i say its its a number and use the method mentioned. if its between and including 65-90 i can tell the board to use it as a letter.

if i wanted to make words out of the letters how could i do that? i haven't seen much string manipulation.

if i wanted to make words out of the letters how could i do that?

Create an array of chars. Create an integer index, initialized to 0, into that array. Add each letter to the array, at the location pointed to by the index. Increment the index, and add a NULL at the new position.

char InData[20]; // Or whatever size you need
int   InIndex = 0;

void loop()
{
    while(Serial.available() > 0)
    {
        char inLetter = Serial.read();
        if((inLetter >= 'A' && inLetter <= 'Z') ||
            (inLetter >= 'a' && inLetter <= 'z')
        {
           InData[InIndex] = inLetter;
           inIndex++;
           InData[InIndex] = '\0'; // Keep string NULL terminated
        }
    }

    // InData now contains a string. Do whatever...
}

Thank you all for helping. This code will be used (hopefully) to build a small cnc machine. I needed to get 3 numbers to the board from a PC (I’m using VB.net).

the PC outputs “X1Y2Z3” where 1,2,3 could be multiple digits. the arduino then spits out " xval is: 1 yval is: 2 zval is: 3"

the code is as follows

int val=0;
int tempval=0;
char axis;
int xval=0;
int yval=0;
int zval=0;

void loop()
{

  while(Serial.available() > 0)
  {
    tempval=Serial.read();
    if (tempval=='x' || tempval == 'X')    {
     axis='x';
     val=0;
    }
    else if (tempval=='y' || tempval == 'Y')    {
      axis='y';
      val=0;
    }
    else if (tempval=='z' || tempval == 'Z')    {
      axis='z';
      val=0;
    }
    else if (tempval >='0' && tempval <= '9')    {
      Serial.println("tempval = number");
      val=val * 10;
      val=val + (tempval - '0');

      if (axis=='x'){
        xval=val;
      }
      else if (axis=='y'){
        yval=val;
      }
      else if (axis=='z'){
        zval=val;
      }
    }
    else    {
      Serial.println("tempval is other");
    }
  }  //end of input in serial buffer
  Serial.print(" xval is: ");
  Serial.print(xval);
  Serial.print(" yval is: ");
  Serial.print(yval);
  Serial.print(" zval is: ");
  Serial.println(zval);

}

(I’ve never used the /code command, I hope it worked…