Go Down

Topic: Communication b/w Java Monkey Engine and Arduino (Read 1 time) previous topic - next topic

PaulS

Quote
No, but the servo that I wrote in the Java program is. I forgot to mention that it's superfluous because the angle is determined completely by the Java program, so changing it in the Arduino doesn't make sense. Also, my physical servo is 180 degrees.

Shouldn't the model (in Java) match the real world?

Quote
I'm not sending relative values, the Java program sends the value of the virtual servo's angle.

In your original post, you said you were.

Quote
The writestream in Java can only send integers, so I multiply it by 100 and cast it to an int to save the last couple of decimal points, then divide it by 100 on the Arduino side to return it to a float.

Why? The Servo.write() function takes integer input.

Monorail


Quote
No, but the servo that I wrote in the Java program is. I forgot to mention that it's superfluous because the angle is determined completely by the Java program, so changing it in the Arduino doesn't make sense. Also, my physical servo is 180 degrees.

Shouldn't the model (in Java) match the real world?


Right. So that's why I originally said that the line in the Arduino code isn't needed.

Quote
I'm not sending relative values, the Java program sends the value of the virtual servo's angle.

In your original post, you said you were.

My bad. I meant to say that the value of the servo is sent after being manipulated by the FSR.


Quote
The writestream in Java can only send integers, so I multiply it by 100 and cast it to an int to save the last couple of decimal points, then divide it by 100 on the Arduino side to return it to a float.

Why? The Servo.write() function takes integer input.

But it also takes float input, which is more precise.

This is the code that I'm using now.
Code: [Select]
  Serial.println(servoval);
  input = ""; //declared in higher scope
  while(Serial.available()){
  input += (char)Serial.read();
  }
   char carray[input.length() + 1]; //determine size of the array
   input.toCharArray(carray, sizeof(carray)); //put input an array
   servoval = atoi(carray)/100; //convert the array into an Integer
  myservo.write(servoval);

It seems to be having the same problem though. I also don't think that redeclaring carray each time is very efficient, but I'm not sure how to do it otherwise.
Once again, thanks. I really appreciate this.

PaulS

Quote
Right. So that's why I originally said that the line in the Arduino code isn't needed.

We seem to have a failure to communicate here. If the physical servo can move from 0 to 180, and the virtual servo can move from 0 to 360, the model DOES NOT match the physical world.

Quote
My bad. I meant to say that the value of the servo is sent after being manipulated by the FSR.

Now, this might be interesting to watch. I don't believe I have ever seen a force sensing resistor manipulate a servo. Does it get up and crank the servo around?

Quote
But it also takes float input, which is more precise.

From Servo.h:
Code: [Select]
  void write(int value);             // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
  void writeMicroseconds(int value); // Write pulse width in microseconds

Which of those methods "takes float input, which is more precise."?

Quote
It seems to be having the same problem though. I also don't think that redeclaring carray each time is very efficient, but I'm not sure how to do it otherwise.

The problem isn't with redeclaring carray each time.

The problem is that serial data transmission takes time.
Code: [Select]
while(Serial.available()){
   input += (char)Serial.read();
   }

Whatever serial data has arrived since the last time any data was read is read and stored in a String.

Whatever is in that String object is extracted, converted to an int and divided by 100 and used to position the servo.

Suppose the sender sent "15000". You will get the data in increments "1", "50", "0", "0", maybe.

Prove to yourself that that is what is happening. After the while loop, put a Serial.println(input); statement. What gets printed will not be what you expect.

Your sender needs to send some kind of end-of-packet marker, and the receiver needs to keep reading data until that end of packet marker arrives. Then, and only then, should it interpret and the value.

Monorail

#8
Mar 04, 2011, 07:25 pm Last Edit: Mar 04, 2011, 07:31 pm by Monorail Reason: 1

Quote
Right. So that's why I originally said that the line in the Arduino code isn't needed.

We seem to have a failure to communicate here. If the physical servo can move from 0 to 180, and the virtual servo can move from 0 to 360, the model DOES NOT match the physical world.

I have Java code that ensures that the virtual servo can only move between 0 and 180.


Quote
My bad. I meant to say that the value of the servo is sent after being manipulated by the FSR.

Now, this might be interesting to watch. I don't believe I have ever seen a force sensing resistor manipulate a servo. Does it get up and crank the servo around?

Not exactly sure what you mean. It moves the servo based on how hard the FSR is pressed.


Quote
But it also takes float input, which is more precise.

From Servo.h:
Code: [Select]
 void write(int value);             // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
 void writeMicroseconds(int value); // Write pulse width in microseconds

Which of those methods "takes float input, which is more precise."?

Guess I just had a misconception. If I'm only capable of writing integer values, then I could probably just send one byte containing the value of the servo's angle.


Quote
It seems to be having the same problem though. I also don't think that redeclaring carray each time is very efficient, but I'm not sure how to do it otherwise.

The problem isn't with redeclaring carray each time.

The problem is that serial data transmission takes time.
Code: [Select]
while(Serial.available()){
  input += (char)Serial.read();
  }

Whatever serial data has arrived since the last time any data was read is read and stored in a String.

Whatever is in that String object is extracted, converted to an int and divided by 100 and used to position the servo.

Suppose the sender sent "15000". You will get the data in increments "1", "50", "0", "0", maybe.

Prove to yourself that that is what is happening. After the while loop, put a Serial.println(input); statement. What gets printed will not be what you expect.

Your sender needs to send some kind of end-of-packet marker, and the receiver needs to keep reading data until that end of packet marker arrives. Then, and only then, should it interpret and the value.

That would be consistent with what is happening. Can you recommend a good way to denote the end of a packet? Maybe a standard character that is sent?

Thanks.

PaulS

Quote
I have Java code that ensures that the virtual servo can only move between 0 and 180.

Well,this explains why you need to constrain the value on the Arduino to -360 to +360. Or not.

Quote
It moves the servo based on how hard the FSR is pressed.

In that sentence, "It" is a pronoun with no referent. I have no idea what "it" is.

Quote
Guess I just had a misconception. If I'm only capable of writing integer values, then I could probably just send one byte containing the value of the servo's angle.

If the application is capable of sending binary data to the serial port, yes, you could.

Quote
That would be consistent with what is happening. Can you recommend a good way to denote the end of a packet? Maybe a standard character that is sent?

Any character that is not part of the normal stream of data - !, ;, or > arre typical end-of-packet markers, along with carriage return and line feed.

Go Up