Let's Make Robots!

Cant get my processing sketch to wait for a response from the arduino

sorry if im getting boring. i promise i will get onto a rock crawler rover thing once i have got some life out of the polargraph...

The code below, does exactly as i want in terms of processing the image, and converting it into a stream of values.
however i want it to
1) wait for an initial "ready" command from the ardunio
2) wait for a "ready" command from the arduino in between each and every number transmission.

the arduino is processing the numbers physically, and therefore takes time.

I have used "300" as my ready command because the sketch is dealing in shades between 0 and 255. I figure it it one less thing to worry about if i dont start chucking ascii in there too.
My "commands" can be 300, 301, 302 etc.

I THINK i have narrowed down the lines which need attention to lines 17 and 33. I pressume i need a "serial Event" void in there? but i am dont know what to do with it. All the tutorials i have read and watched (of which there are many) do different things with it, none of which i understand properly. I presume what is required here depends on the context?

Many thanks

Ol

http://pastebin.com/tXu9sgc6

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Im afraid i have made NO progress with the serial connection. I cant for the life of me see why it isnt working! (ive taken it out again to start from clean)

http://pastebin.com/f6x7QuQj

Just in case i havent been brutally clear. I needs to wait for an initial ready signal, send ONE number, wait till the arduino has done what it needs to do, (the arduino then sends a "lf") then it needs to send the next ONE number.

eugh.

so i gave up for a bit, and instead of doing fixed square pixels, decided to express the shades in single steps, of varying sizes.

works pretty well on processing, shame i cant get the arduino to play with it!

I guess i need to get a SUPER simple sketch going, then canibalise it...

But I'd rather just complain about it:

 

------

  myPort.clear();

  myPort.read();

  myPort.bufferUntil(ready); // ********this is SUPPOSED to wait for a "ready" signal from //the arduino (sent on button press) It doesn’t, obviosuy

----

Why do you clear and then read? Have you read the documentation for those functions? It's like checking for messages on a whiteboard by wiping the whiteboard first, looking at it (what do you expect too see now?), and then walking away. 

Why do you think it is SUPPOSED to wait? First of all, the documentation says "Sets a specific byte to buffer until before calling serialEvent().",the program will set the byte and happily continue on it's way to the next instruction. Second, you are not giving it a byte, you are giving it an int, wich the function probably accepts because Java is slightly silly and doesn't have an unsinged byte datatype so to give it the whole range of values from 0-255 you have to actually use an int, but that value you are giving it will never come in as a byte so the serialEvent function will most likely not be called at all.

So, to fix your code, you should have a function like this:

void waitUntil(int byteValue){

if (byteValue>255) throw new IllegalArgumentException("byte value out of range 0-255");

 int lastValue = -1;

while (lastValue!=byteValue) {

    if(Serial.available()>0) {

         lastValue=Serial.read()

    }

}

}

 

This function when used like this: waitUntil(111) should stop your program until the value 111 is sent by the arduino, and it should also prevent you from shooting yourself in the foot by waiting for a value that will never be returned by Serial.read().

You could enhance that function to time out if the specified character isn't sent within a set amount of time, but you'll probably mess up the code again...

but i think i will just ignore the snide comments instead

"This function when used like this: waitUntil(111) should stop your program until the value 111"

but it doesnt.

I appologize for the snide comments but it seemed like nobody was RTFMing that day...

As for the function, you must realize that I wrote it directly in the comment box so it wasn't guaranteed to work, it was just meant to give you an idea.

I don't like my code to be broken though, so here is the fixed version:

void waitUntil(Serial port, int byteValue){

  if (byteValue>255) throw new IllegalArgumentException("byte value out of range 0-255");
 
  int lastValue = -1;
 
  while (lastValue!=byteValue) {
      if(port.available()>0) {
           lastValue=port.read();
      }
  }
}

I've also written a processing sketch and its corresponding arduino sketch to test out the function

http://pastebin.com/ntbKmhBv

http://pastebin.com/a2rPhAyc

 

Yes, I think your whole deal comes down to that "buffer until". Put simply, the CR(13) or LF(10) are used to tell the reciever where the "end of the send" is. CR is carrage return --the same as hitting enter on your keyboard. So think of typing, "data, data, data, data, return." When we get the "return" we know we can take the stuff we have been storing in the buffer and do something with it.  --Remember, your transmitter will have to add this (13) to the end of its sends --Serial.print('\r')  or Serial.write(13). Or even easier is to simply do the Serial.println() and use (LF) as your finish.

Think of this situation. You have a joystick transmitter and 2 motors on your bot (L and R). You are sending 2 numbers, each number going to the speed of each wheel. These numbers get transmitted back to back to back. If the reciever keeps up, fine, but if it coughs once, or one bit of data gets lost, you loose your "rhythm". I.e. we were sending L,R      L,R     L,R     but then one of the "lefts" didn't come through, so now we are going, RL   RL   RL. Your steering is now backward, because the reciever is off one step. If you sent, L,R, 13     L,R  13     L,R 13, we now know where each packet starts and stops. If we loose data or bad data comes through, it does not matter --We will get caught right back up the next time we get a 13. We will never be "out of sync" for more than one "send".

On my Arduino side I'm reading sensor values and sending them using the RFBee to my PC, running a Processing sketch. I always make sure the last character I send from the Arduino is terminated with a '\n' which is ASCII value of 10, the NEWLINE or LINEFEED character.

On the Processing side I'm doing this (myPort is the Processing SerialPort object):

while (myPort.available () > 0) {
      String inBuffer = myPort.readStringUntil(10);

      .... do some stuff with the inBuffer String value

Seems to work well for me.....

 

For your image shades instead of 0 through 255, what about 0 through 250? Why not adjust the range of shades rather than force your arduino to read extra data? Consider a LED, if you cycle through a number of PWM values from 0 to 255 you will notice, or, not notice how the different PWM value isn't exactly noticeable. I realize light != marks on paper, but, there will be a bit of crossover in the fact that your drawing will only have a certain amount of resolution. With that level of resolution you will only really be able to tell the difference between a certain level of shades. I am sure you can prove/disprove my idea by looking at lines of all the shades you want to send, and, see if you can tell the difference between all of them.

The arduino currently maps the incoming to a resolution of only 6!.  ican just move that work to the processing sketch!  Also, it currently fills in square pixels with either 0,1, 2...6 steps to get the shade. If i  instead put in  one step at a time of varying size, and kept track of total steps  accosss the image it would look a lot more organic, and while it would take a fairly heavy rework of the processs at each end,, may end up actually easier. Thanks guys!

Awesome sauce. thanks Chris. , that is very encouraging. What you say about the bytes makes sense.

"the bit-shifting was a bit confusing in pratical use".

which is exactly why i was trying to dodge it, but it looks like i am going to have to face it like  a man

So i will try and get that sorted, and then then look at the Serial event routine. when you say "get into some kind of variable"

so i need to read the "LF" and then put it somewhere to be dealt with , rather than just try and respond to it directly?

Something to have a poke at tommorow evening :)

The plotter is plotting the shades fine, but the data is streaming without waiting, so it plots the first shade, then once it has finished, it takes the next number presented, but in the time it has taken to plot it, the numbers have moved on.so instead of getting a 1,2,3,4,5,6, it is kind of random 1,4,2,6, kind of thing. does that make sense? doesnt matter if not. anyway, once i get this "wait for me" thing going, we should be onto a winner :)

I think I have to do bullet points, we got  a few things to cover.

  • When doing serial-anything, everything gets sent as a byte. You cannot send your 300 (either way) via an int. Actually, depending on how your Processing is dealing with it, you are probably sending a 54. --Your 300 is overflowing the byte (going over 255), looping back to 0, then landing on 54.  Everything needs to be send as a byte, so if you have anything bigger than that, they would need to be "broken apart" into bytes, sent, then reassembled on the other side.
  • Typically your "ready" is done with a CR (Ascii 13) or LF (ascii 10)
  • Your serial event routine needs to get into some kind of variable. You are indeed reading what is coming in, but you are not putting the data anywhere so you can deal with it later. The ReadSerial stuff needs a variable in there.

I think that is the majors for now, the "everything gets sent as a byte" thing might take some time to get your head around --it did for me. Not the concept, mind you, but the bit-shifting was a bit confusing in pratical use. Other than the above, you are looking pretty good, actually. You are very close.