PROBLEM SOVLED !! 8)
With determination and a LOT of experiments and researching I have found a cure. Posting my bit of code for anyone else who might have a similar problem. It would seem that when sending strings over serial using serial.println on the Arduino, several things must be considered to receive the data as a signed integer in Processing…
- a myPort.read() in processing proves to only grab one character/byte at a time and in ASCII format.
- using serial.println, the whitespace characters are also sent as part of the string (i.e \n or other formatters)
- when you do receive all of the data and assemble the full string, a simple (int) conversion from a (str) does not work.
- I avoided using void SerialEvent() because of timing issues and the way draw() and SerialEvent() continue to loop simultaneously
So on the Arduino side here’s what I did…first of all a handshaking method like so:
void establishContact() // Serial handshaking method
{
while (Serial.available() <= 0) // If nothing has been heard from the PC
{
Serial.println(“A”); // send a capital A
delay(20);
}
}
When processing wants new magnetometer data, it simply sends a myPort.write(‘A’); and the Arduino checks this with this…
if (inChar == ‘A’) // our RTS signal received
{
firstContact = true;
digitalWrite(statusLED, HIGH); // Handshaking Success Status LED
}
else
{
firstContact = false; // demands another handshake from processing
digitalWrite(statusLED, LOW);
}
So while firstContact is true, the data is sent using headers to identify WHAT magnetometer value is being sent. I had to do this else the data ended up being stored in random variables in processing. Here’s the arduino code I’m using to send the magnetometer data and data headers:
if (firstContact == true)
{
Serial.flush();
Serial.print(“x”);
Serial.println(xscaled); // send x data over serial
Serial.print(“y”);
Serial.println(yscaled);
Serial.print(“z”);
Serial.println(zscaled);
Serial.print(“d”);
Serial.println(degree);
}
Now to Processing to receive and digest the data. I used a similar handshaking method as on the arduino. Again, I avoided using the SerialEvent() function and wrote this:
void getData()
{
while(myPort.available() > 0) // process serial data until buffer is empty. each axis is tagged with
{ // a header character so it ends up in the right variable
int Header = myPort.read(); // this also makes sure the buffer gets totally cleared
switch(Header)
{
case ‘x’:
bxString = myPort.readStringUntil(lf);
break;
case ‘y’:
byString = myPort.readStringUntil(lf);
break;
case ‘z’:
bzString = myPort.readStringUntil(lf);
break;
case ‘d’:
degreeString = myPort.readStringUntil(lf);
break;
}
}
}
With the addition of the header tags, the data now always ends up where it should. The string is compiled until it reaches the \n character, or ASCII 10 (linefeed).
Now all that is needed is to use trim() to remove the whitespace characters from the strings and convert them to integers. Code example below:
if(bxString != null)
{
bxString = trim(bxString); // trim off the newline char
Bx = Integer.valueOf(bxString).intValue(); // convert the string to an integer
}
if(byString != null)
{
byString = trim(byString);
By = Integer.valueOf(byString).intValue();
}
This is working great now for signed and unsigned integers. I’m sure there is an easier way, but I’m going to stick with what (finally) works! I hope someone can find this useful.