[SOLVED] (Uno) Trouble passing serial data to board

Hey everyone, I'm having some pretty buggy results when passing data via JAVA to my arduino. This isn't my first rodeo with RXTX or anything and I have other working applications using effectively the same code. I might just be overlooking something small.

first things first -
I have the BAUD set to 9600 on both the application and the board.

What I am trying to do is pass 20 integer values over serial from java to the arduino, store the values into an array and use them later on.

Here's the data I am passing via JAVA
JAVA output (ignore the comma's each are separate integers)
317, 250, 251, 249, 250, 197, 249, 249, 182, 250

If you want to see the JAVA code I will send it, but here is the send function...

public void writeData(int data) {
		try {
			output.write(data & 0xFF);
			output.write((data >> 8) & 0xFF);
			output.flush();
		} catch (Exception e) {
			logTxt.append("\nCould not write to microcontroller...");
		}
	}

Then what I am getting via the arduino looks like this...
3197,249,249,182,250,0,0,0,0,0,0,0,0,0

It looks like blurred entries, and not all of the data was recieved.

Here is how I am reading the data via arduino.

  while(recievingCmds){
    if(Serial.available() > 2) {
      byte lowByte = Serial.read() & 0xff;
      byte highByte = Serial.read() & 0xff;
      nextCoord = (int) (highByte << 8 | lowByte);
      coords[index] = nextCoord;
      index++;
      //Check to see if we filled the command queae
      if(index > 19){recievingCmds = false; inprogress = true;}
	  
    }//end if
  }//end while

Any help would be hugely appreciated

    if(Serial.available() > 2) {

You wait for 3 bytes in order to read 2. Why is that?

oh. oh wow.... I fixed that up to a >= sign and am still getting choppy data

I just received, (the 249250 entry is not a typo)
250,249250, 49,2,0,0,0

So still missing data, things are certainly still choppy. Any other guesses?

Get your arduino code working with the serial monitor, then you will know if you have a java issue. Below is some basic serial test code you can try with the serial monitor. The end of each data packet is marked with a comma, like 317, 250, 251, 249, 250, 197, 249, 249, 182, 250,.

//zoomkat 3-5-12 simple delimited ',' string  
//from serial port input (via serial monitor)
//and print result out serial port

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like wer,qwe rty,123 456,hyre kjhg,
  //or like hello world,who are you?,bye!,
  
  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      //do stuff
      Serial.println(readString); //prints string to serial port out
      readString=""; //clears variable for new input      
     }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Any other guesses?

Not much into guessing games. What I would do is print the two bytes being sent by the PC application, and print the two bytes being received by the Arduino. Are they the same two bytes each time, or is data being lost?

Get your arduino code working with the serial monitor

It's a bit hard to pass binary data from the Serial Monitor application.

Intuitively, I suspect that the Arduino hears the transmission properly. I think that the data isn't properly getting from the Arduino to whatever gizmo is displaying the Arduino output for you. I base that on the fact that the "Arduino data" looks surprisingly like the "Java data," with characters missing. I'm assuming that the data you're showing us is in decimal, so, noting that the transmission appears to be binary, I don't see a way that the decimal representation would stay piecemeal intact if the binary transmission were garbled.

How are you displaying the Arduino data? Can you tell us about the hardware, and show us the code that did it? What kind of Arduino are you using for this project?

It's a bit hard to pass binary data from the Serial Monitor application.

I thought an ascii character is a binary byte.

I thought an ascii character is a binary byte.

It is. But, OP is trying to send a value like 347 as two bytes. Which two letters should he type in the Serial Monitor to get 347?

@TMD3 - I would normally think that you're probably right, in the scenario where I am checking the data the flow of data looks like this: JAVA -USB-> Arduino -USB-> Arduino IDE (serial monitor). I could change it to Java -> Arduino -> Java without any hardship though.

The arduino IDE is written in JAVA. I actually borrowed some of their code a few years ago for a project.

However why I am debugging this is because I noticed that with the same board and about the same code I was having a stepper motor move I dunno 200 times what it should have been which as you can imagine lead to me restarting the board over and over trying to find any errors. The serial output looks like the issue is with the data transfer itself but I could be wrong.

@PaulS - That's effectively what I am trying to do right now. I am sending two bytes (twenty times) from the computer to the arduino. The arduino is trying to read that data and store it. Then the arduino later serial writes that array to the serial monitor. The values are not the same. Unless you mean just do a basic test to see if I can pass serial data to it. If you want more code just ask I'll share.

@Zoomkat - I'm not entirely sure what you are suggesting. The commas are artifacts I added so I did not eat up 20 lines in a forum post of essentially arbitrary output values.

I should also state that earlier in the application I send the value "3333" to notify the arduino to receive these integer values. No issues with that transfer whatsoever

edit -

I just changed my data path to go JAVA -> arduino -> JAVA

Here's the input going from JAVA
317,250,251,249,250,197,249,249,182,250

Here's the output from the arduino back to my application
250, 251, 249, 250, 197, 249, 249, 182, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0

So now it looks like I am only missing one value. It's no longer being chopped.

So now it looks like I am only missing one value.

You'd need to post all of your Arduino code, if you want help figuring that out.

You got it PaulS

Ignore the method names(EX: the method "moveStage" simply regurgitates the array of integers down the serial). Hopefully I erased all the useless variables for the debugging code. Anyways here's the code that gave me the output

int coords[20];
int index = 0;
int nextCoord;

//Booleans to instigate soft-ware to instrument commands
boolean inprogress = false,
        recievingCmds = false;

void setup() {
  //Open the serial port for 115200 baud with some safety delays
  Serial.begin(9600);
  delay(500);
}

void loop() {
  //Handle software input if no routine is running
  if(!inprogress){ recieveInstrumentCommands(); }
  //Move Stage to create image.
  if(inprogress){ moveStage(); }
}

void sendTwoByteSignal (int signal){
  Serial.write(signal & 0xFF);
  Serial.write((signal >> 8) & 0xFF);
}

void recieveInstrumentCommands(){
  //Look for a character to explain what command to run
  while(!recievingCmds){
    if(Serial.available() > 0){
      char command = Serial.read();
      //Instantiate a drawing procedure*
      if(command == 'R'){
        inprogress = false;
	recievingCmds = true;
	index = 0;
      }
    }
  }
  //Fill array of drawing positions via serial communication
  while(recievingCmds){
    if(Serial.available() >= 2) {
      byte lowByte = Serial.read() & 0xff;
      byte highByte = Serial.read() & 0xff;
      nextCoord = (int) (highByte << 8 | lowByte);
      coords[index] = nextCoord;
      index++;
      //Check to see if we filled the command queae
      if(index > 19){recievingCmds = false; inprogress = true;}
	  
    }
  }//end if
  
}//End method

//Drawing
void moveStage(){;
  //Go through each array index
  for(int j = 0; j < 19; j++){
     sendTwoByteSignal(coords[j]); 
     delay(100);
  }
  inprogress = false;
  recievingCmds = false;
  index = 0;
}//End function

I don't know if you intended for the Arduino to transmit 20 values of coord[]. The posted sketch transmits 19.

The posted sketch sends data with Serial.write(), which sends the binary value of the byte. In my tests, the IDE's serial monitor doesn't print characters from 0 to 0x1F, and it prints the same reverse question mark for characters from 128 to 255. I don't see how you interpret the output data if you're viewing it on the IDE. How are you reading the data?

Have a look at the examples in serial input basics which are designed to read in all the data. Then you can parse it or whatever else needs to be done.

...R

@tmd3 - good catch

@robin2 - I solved the problem by passing an integer of value 0. The passing of a character then an array of integers was screwing things up.

Code that interprets data as it arrives can fail if there is a glitch in the transmission process and then it is harder to recover from the glitch.

Whereas if all the data is received first it is easy to check that what is received is valid before acting on any of it.

...R

Thanks for the suggestion Robin2.

I actually finally solved the problem.

What I did was before I sent the data I had the microcontroller pass a signal (say the integer value 1111) so the soft-ware knew the MC was ready to receive the array.

So it goes,

JAVA -> Arduino (Tells arduino I am getting ready to start a "new" run)
Arduino -> JAVA (Arduino tells soft-ware okay I'm ready)
JAVA -> Arduino (Data Transfer)
Arduino -> JAVA (Hey I just recieved everything is there more?)

etc..

Seems like the hand-shake technique was something I had done in my previous project then left out because I thought it was extraneous. It's not. It also allows for fail-safes on both ends. If a hand-shake isn't recieved then stop the algorithm in the soft-ware something went wrong.

Very similar to what you suggested robin just without the annoying parsing routines when I need to pass data and perform other operations quickly.

That sounds like a sensible approach. I'm not sure, however, if it is designed to deal with an error that might arise between Java sending and the Arduino receiving.

...R