Sending X Y Coordinates Through Serial USB?

I am branNew to Processing/arduino.
Taking a class at school, but my class is behind me, and my teacher won't help me out until the class catches up.

I need to figure out how to get X and Y coords to the arduino through serial USB.

I cant figure out the ATOI thing. (but I understand what it should do - ASCII to Integer)

so.... the arduino only takes bites, or something.
you have to convert the ascii stuff.
and you only have up to number 255.

I thought it would be a simple task. I just need to get coords into my program and it is taking a Lot longer then I want it to.

spent a few hours looking at other posts!

I am pretty sure that

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231650517

is exactly what I am trying to do.

I just cant make any sense of it.

Are the X, Y coords being sent by Processing? As strings or as numbers? Are they sent one at a time, or together?

If the data is being sent by Processing as string data, and the numbers are sent together, you need to include some sort of beginning of packet and end of packet markers, as well as some delimiter between values. Say you send a string like this:

<12, 45>

The Arduino can then read serial data, discarding data until it sees a <. Then, it knows that the data stream now contains valid data.

It reads one character at a time, looking for a character that represents a digit, a comma, a space, a > or a <.

If the character represents a digit, it converts that character to a number, by subtracting '0' ('8' - '0' = 8; '5' - '0' = 5). It multiplies any previous value by 10 and adds the new value:

x *= 10;
x += n;

If x was 8 and n is 4, 8 * 10 = 80, plus 4 = 84.

If the character is, instead, a comma or a space, it is discarded, but the rest of the string now goes in y. If the character is a >, the end of the packet has been received, and x and y can be used.

If the character is a <, the packet was not completely sent, so the values in x and y are reset, and the new packet is processed.

If the data is sent as numbers, the two bytes (which are limited to 0 to 255) can be simply read and used.

You could send your X,Y coordinates in "binary" or "ASCII decimal number strings". If you use a single 8-bit byte to send a value, yes you are limited to 0-255 ... but if your data object is two bytes, you get 0-65535, and so on.

Taking the binary approach may be a little advanced for you, so consider a second approach:

Assuming X=123 and Y=56, have Processing send "123,056\n" - to keep things simple, make sure each coordinate is 3 digits - to the serial port on which the Arduino is listening.

The Arduino code reads one character at a time starting with the X coordinate numbers 1-2-3, recognizes the comma as a command to start receiving the Y coordinate numbers, receives the Y-coordinate numbers 0-5-6, and recognizes the newline character to start looking for the next X value. This is called a simple "parser".

If you look at an ASCII character set you will see the numbers 0-9 grouped together, which makes it very convenient to convert ASCII numbers to binary ... just subtract the character '0' from each ASCII number character received. So '1' (which is decimal 31 in the ASCII table) minus '0' (which is decimal 30) = 1.

So back to the Arudino code loop. Receive the first character '1' which you know is the hundreds digit, subtract '0' to get 1, multiply this by 100, and save it in a variable = 100.

Now receive the next digit, the tens digit '2'. Do the '0' subtraction to convert to binary 2, multiply by 10 making it 20, add to the variable saved previously - now you have 120.

Now receive the last digit, the ones digit '3'. Do the '0' subtraction to get binary 3, no need to multiply, add to the variable saved previously - now you have 123.

Now receive the next character - it is comma - set a flag in your code to start receiving the Y coordinate. Process the characters 0-5-6 in the same manner as for X. When the newline character is received, the code reverts to receiving the next X coordinate.

There may be a function Integer.ParseInt() which does the same thing for you, but you will still need to detect the comma and newline and "split" the input characters into 3-character strings for the X and Y values.

That was REALLY helpful thanks a lot!

I made it simpler, or perhaps maybe more difficult by just sending 8 digits. the first 4 are x second 4 are y.

It works great when I use the Serial Monitor in Arduino.
but when I make a code to send them in Processing, it screws up big time.

can you give me a sample processing code that can put these digits into a 8 digit long number and send it to the arduino?

thanks for your help!

      if (Serial.available() > 0) { 
  
  
  
  dig = dig +1;
// read the incoming byte:
incomingByte = Serial.read();

  digit = int(incomingByte) - '0';  // - 0, or ascii value -30 from the incoming digit.



  if(dig == 1){
  
 xval += digit * 1000;
}

if(dig == 2){
 xval += digit * 100;
 }


if(dig == 3){
  xval +=  digit * 10;}
 
  

if(dig == 4){
  xval += digit;


}



  if(dig == 5){
  
 yval += digit * 1000;
}

if(dig == 6){
 yval += digit * 100;
 }


if(dig == 7){
  yval +=  digit * 10;}
 
  

if(dig == 8){
  yval += digit;
dig = 0;

Serial.print(xval, DEC);
Serial.print(',');
Serial.println(yval, DEC); 
straightLine (xval, yval);

  xval = 0;
  yval = 0;

}
 }
}

with a little more messing around. I discovered that if I sent the data from Processing as follows:

myPort.write("*10001000");

it will do the correct movements.

Unfortunately I need to put a variable in there.
In my case, xy.

can someone explain this to me?

can someone explain this to me?

Explain what?

Why sending "*10001000" works? Need to see more of your Arduino code to answer that. Why the * is needed is not obvious from what you posted.

Or, how to send the value in a variable, instead? To answer that, we'd need to see your Processing code, to know what variable types you are using, and how you are sending the data.

ok, heres what I have so far:

Processing Code:

 int xsend = int(map(mouseX, 0, 800, 1000, 1800));   // Maps the mouseX so that it is always 4 characters long.
 
 
 int ysend = int(map(mouseY, 0, 800, 1000, 1800)); 
 
 xsend = xsend * 10000;    //tool to add 4 zeros onto xsend so that it can be added to ysend.
 
 xy = xsend += ysend;
 
 
print('*');                   //and asterisk will restart the digit counting in arduino so that it is clear when it starts reading a number


println(xy);     //this prints out exsactly what I would like to send to the arduino.


myPort.write("*");
myPort.write(xy);    //This is where I think my problems are.

//(myPort.write("*10001000");  //this works fine!

Arduino Code:

if (Serial.available() > 0) { 
  
  
  
  dig = dig +1;
// read the incoming byte:
incomingByte = Serial.read();

if (incomingByte == '*'){    //asterisk at the beginning will reset the xval and yval as well as which digit it will start looking for.


   xval = 0;
  yval = 0;
  
  dig = 0;
  
}

  digit = int(incomingByte) - '0';  // - 0, or ascii value -30 from the incoming digit.



  if(dig == 1){
  
 xval += digit * 1000;
}

if(dig == 2){
 xval += digit * 100;
 }


if(dig == 3){
  xval +=  digit * 10;}
 
  

if(dig == 4){
  xval += digit;       //notice how the first four digits go to the xval, the second four digits will go to the yval below.


}



  if(dig == 5){
  
 yval += digit * 1000;
}

if(dig == 6){
 yval += digit * 100;
 }


if(dig == 7){
  yval +=  digit * 10;}
 
  

if(dig == 8){
  yval += digit;


Serial.print(xval, DEC);
Serial.print(',');
Serial.println(yval, DEC);   


straightLine (xval, yval);  //sends commands to the stepper motors

 

}
 }

does this make it a little more clear?

myPort.write(xy);    //This is where I think my problems are.

//(myPort.write("*10001000");  //this works fine!

The commented out instance is writing a string. The un-commented line is writing an integer.

In both cases, the Arduino is trying to read a string.

In the processing code, you need to convert the 2 integers to 2 strings, pad both strings so that they are 4 characters each, then concatenate the strings and the '*', before sending the concatenated string.

Check out the nf() function in Processing, and the whole section on string processing.

Your getting close.

WOOOO WOOOO!!!

I DID IT!

thank you all soooo very much!

I have been working on this project for years! and now it is finally working! I am soo thrilled!

This is what I ended up doing

xy is now a declared as a String

 int xsend = int(nf(mouseX,4));
 
 
 int ysend = int(nf(mouseY,4));
 
 xsend = xsend * 10000;
 
 xy = nf(xsend += ysend, 8);
int xsend = int(nf(mouseX,4));


 int ysend = int(nf(mouseY,4));

 xsend = xsend * 10000;

 xy = nf(xsend += ysend, 8);

This is a lot more work than is necessary. You are converting an integer to a string, and then converting that string back to an integer.

You repeat that process for mouseY.

Then, you manipulate the integers, and convert the result to an 8 character string.

Only the last use of nf is required.

It would be better to convert mouseX to a string, as you are doing, then convert mouseY to a string, then concatenate the strings (or just send one string then the other string).

The reason for this suggestion? What happens if mouseX or mouseY goes negative? Your method using multiplication will fail if that happens. Using concatenation of strings will work just fine.