how to serial.read multiple vars at once [solved]

Hi!

I want to build my own ambilight system using Arduino and processing, but so far I've got some communication errors.

I want to send an array to arduino containing e.g. RGB-values for each LED, so far so good, I draw a coloured square and want to send mouse position to arduino.

import processing.serial.*;
Serial Arduino;

byte[] col = new byte[2]; 


void setup(){
  size(255,255,P2D); 

  println("Available serial ports:");
  println(Serial.list());

  Arduino = new Serial(this, Serial.list()[0],9600);


    for(int d = 0; d < 255; d++){  
    for(int c = 0; c < 255; c++){
      
      stroke(c,d,0);
      point(d,c);
      
    }
  }


}

void draw(){

  col[0] = byte(mouseX);
  col[1] = byte(mouseY);


  Arduino.write(col);



}

as I understand one can only send an array of bytes to arduino, correct?
An array was chosen because this should be the simplest (and fastest) way to send data to arduino.

well however arduino refuses to read this array.

color = Serial.read();

color is an array size 2.

the error I get: incompatible types on 'int' to 'int[2]'

I've tried using color as byte, converting Serial.read to byte, but nothing seems to work.

So, how can I receive an array send from processing as an array in Arduino?

regards!

Serial.read returns only single bytes (or -1 if no data is available), encoded in an "int".
On the Arduino, an "int" is two bytes, so you need to arrange for the appropriate number of bytes to be read using, for example, a "for" loop.
Always use "Serial.available" before a read to ensure there is sufficient data in the buffer.

If you're sending two "byte"s, why not read two "byte"s?

thanks, ok, so if I want to control e.g. a robot and do the calculating on my PC the easyiest way to do this would be creating arrays convert them to byte, and send them to arduino, then again, assign them to the corresponding variables?

p.s.
does someone know an easy-to-read source how serial communication works?

regards

All you really need to know about serial comms is that, as far as the Arduino is concerned, data are transmitted and received as bytes; it is up to you to recombine those bytes as larger data types, or break down the data types into bytes.
The other thing is, serial is relatively slow - a single byte at 9600 baud takes nearly a millisecond to transmit, so just because "Serial.available" has returned a 1, don't assume that as soon as you've read that character that there'll be another immediately available.
You could go round "loop()" many times in the time it takes for another character to be ready, even if they were transmitted one after the other.

Ok, thanks for the fast replys! again :slight_smile:

There are a number of simple example programs on the page that AWOL linked. I would start there to get some ideas about how to use the Serial library.

Hmm how should I use the for-loop?
Because if I send the whole array, how do I know when I got the first, and when the second number?

If I send them just one line after the other, they will be stored in the same variable.

Using a for loop like this, nothing will happen.

//arduino
  if(Serial.available()){
    for(int i = 0; i > 1; i++){
      col[i] = Serial.read();
    }
  }
//processing
  Arduino.write(col[0]);
  Arduino.write(col[1]);

Want I need is some way to say:

  1. byte = red
  2. byte = green
  3. byte = blue
    (1.)4. byte = red
    (2.)5. byte = green
    (3.)6. byte = blue

and all I get is:

  1. byte + 2. byte = red
    no byte for green...

regards

p.s.
I'm familiar with the Serial commands, I just lack the knowledge on how to integrate them into what I want to do.

p.p.s.
I somehow can't find a decent example where a larger amount of data is sent to arduino (which should suffice for gettinge the idea), only vice versa.

Want I need is some way to say:

  1. byte = red
  2. byte = green
  3. byte = blue
    (1.)4. byte = red
    (2.)5. byte = green
    (3.)6. byte = blue

Something like
"R123B345G678"
?
Or, if you want hex, since B(lue) is a valid hex digit, call it "H" instead:
"R1AG2BHAF"
or something similar.
Delimiters are going to be a problem if you want to send just binary, since all the ASCII character values fall in the range 0..127.

ehm sorry, I don't quite understand what you mean?

I just need a working example of how to send multiple values at (literaly) the same time >.<

No no byte is fine, I just need a working example. (damn the other way around is much easyier)

You need to have some mechanism to synchronise your receiver with the transmitter.
Imagine your tranmitter sends out a continuous stream of groups of three bytes:

RGBRGBRGBRGBRGB
^
Now, your receiver expects to get R followed by G followed by G.
But imagine it doesn't start running until the point indicated by the arrow.
It receives the value meant for the green channel, and puts it into the value for the red, then it gets the value meant for the blue channel and puts it into the green, and so on.
You could have a missed character, or a corrupted one.

There are lots of ways around this, but they need some thought.

ok now i got something like this:

//arduino
if(Serial.available()){

    switch (Serial.available()){

    case 'r':
      col[0] = Serial.read();

      break;
      
    case 'b':
      col[1] = Serial.read();

      break;

    }
  }
//processing
  Arduino.write('b');

  Arduino.write(mouseX + 3);

  Arduino.write('r');

  Arduino.write(mouseY + 3);

with the result that I get the blue LED to flicker, but the red one isn't on at all.
hmm in my mind this code makes sense >.<
if receive "b"
receive next value as blue
if receive "r"
receive next value as red

something like:

R(val)B(val)R(val)B(val)R(val)B(val)

regards

if(Serial.available()){

    switch (Serial.available()){

    case 'r':
      col[0] = Serial.read();

      break;

Serial. available tells you how many characters are available, not their value.
You can't use it in this way.

Hossa!

I got it :slight_smile: (with some help of a friend)
and thanks to the Board Members!

//arduino
  if(Serial.available() >= 2){

    switch (byte(Serial.read())){

    case 'r':
      colorRGB[0] = Serial.read();

      break;
      
    case 'b':
      colorRGB[1] = Serial.read();

      break;

    }
  }

Data is created like this: [R(val)G(val)B(val)R(val)G(val)B(val)]

Serial.available waits for 2 bytes to arrive, [R(val)]

then switch statement reads the first byte, [R(val)]
(clears it)

and the second byte containing RGB value goes into my array [(val)]
(clears it too)

//processing

  char rred = 'r'
  char ggreen = 'g'


void draw(){

  colorRed[0] = byte(rred);
  colorRed[1] = byte(mouseX);

  colorGreen[0] = byte(ggreen);
  colorGreen[1] = byte(mouseY);


Arduino.write(colorRed);
Arduino.write(colorGreen);

note that my code is thus far only for two colors...

regards!

Hi,

I have set up MAX/MSP with TouchOSC, I have got MAX to send RGB values to the Arduino board as follows:

255 0 0

I can't figure out how to use the serial.read to read the values into integers or an array, I could do with a bit of advice of how to do this. I am going to be using DMXSimple.

Thanks for help in advance,
Jack