2

I am trying to send color() data from Processing to Arduino.

Here is my code from Processing:

import processing.serial.*;
Serial myPort;

void setup(){
  myPort = new Serial(this, Serial.list()[7], 9600);
}


void draw(){
  color[] c1 = {color(99,0,0),color(255,0,0) };
  for (int i = 0; i < c1.length; i++ ){
    int value = int(red(c1[0]));
    myPort.write(value);
    println(value);
    delay(2000);
  }
}

It sends the 99.0 data to Arduino. Here is the Arduino code for getting:

void setup(){
  Serial.begin(9600);
}

void loop(){
  while(Serial.available() > 0){
    int recieved = Serial.read();    
      Serial.print(recieved);
    }
} 

The problem is when Arduino receive data it doesn't take one by one. When i watch Arduino serial monitor, the data comes at different chunks like, 9...99...999..9.. etc.

I am trying to send several color info from Processing into arduino, it might be a long array of value. What is the best way to achieve this?

4 Answers 4

5

The 'best' solution depends on many things, your skill, the performance of the system, and the other tasks it needs to do in the available time. There are some examples of doing data transfer between Processing and the Arduino in the Arduino example programs. So it is worth looking through them.

There seems to be some inconsistencies in your question.

You wrote "It sends the 99.0 data to Arduino", which has a decimal point.

Yet the code is printing an int i.e.

int value = int(red(c1[0]));
myPort.write(value); 

Further, the processing code only looks at the red component of c1[0]:

int value = int(red(c1[0])); 

so it can only send a sequence of '9'. So that looks like a bug.

There are a few basic strategies to write data that can be easily read. Two popular ways are:

  • send fixed length messages, or prefix a message with the size of the data, and have a fixed format of data. For example, use a one byte count to say how many colours are being sent, then send three bytes, in the same order, for each colour
  • use non-data bytes to separate the data. For example use a ',' between R, G or B and '\n' to mark the end of the data. To keep things simple, never use those values as data values. That is pretty much how programming languages work. It is much more complex to read than fixed format data, but can give more flexibility.

Data is often sent as printable characters (e.g. 173 would be three bytes havig the ASCII values '1', '7', '3'). If it is fixed format, it would always be three bytes. For your purposes, I'd probably send each data byte as two hex characters (ASCII '0' to '9' and 'A' to 'F'. This is slightly more complex than pure binary. However it is fixed format, and more importantly it is easier to test by hand using the Arduino serial monitor, you can just type stuff and it is relatively easy to do.

Pure binary data is much more difficult to fully test, and often relies on a piece of software which also needs testing.

Summary: There are a couple of ways, it is hard to say which is best. For simplicity try to make it simple by being fixed format.

1
  • I put the dots for trying to visualise serial monitor in real time. Take them as waiting intervals. My point was Arduino is receiving at different order or rate. i tried sending "\n" with looking at this example but it did not work. Anyway, thanks for the suggestions.
    – orionlogic
    Commented Oct 3, 2014 at 13:52
4

You have to implement a serial protocol.

This can be either binary or ASCII. Binary has the advantage that the messages are short and well structured due to fixed parameter size. ASCII has advantage that you can type the messages into the serial monitor for debugging and typically data bytes are numerical ('0', '1' etc) while message bytes are text ('setcolour' etc) which means conflicting bytes do not have to be escaped.

To get started, try the Messenger library. Note that #include "WProgram.h" has to be changed to #include "Arduino.h" in the .cpp and .h files.

For the set colour message, if you used something like:

setcolour,99,0,0,255,0,0\n

You could use Messenger to parse it like:

Preamble:

#include "Messenger.h"
Messenger message = Messenger(','); //Message values separated by ','

In setup():

message.attach(messageCompleted);

In loop():

while(Serial.available()) {
    byte inbyte = Serial.read();
    message.process(inbyte);
}

Then implement the callback function:

void messageCompleted()
{
    if (message.checkString("setcolour")) {
        colour1[0] = message.readInt();
        colour1[1] = message.readInt();
        colour1[2] = message.readInt();
        colour2[0] = message.readInt();
        colour2[1] = message.readInt();
        colour2[2] = message.readInt();
    }
}

where colour1 and colour2 store the two RGB values.

6
  • Thanks for the answer. I am going to try this method. I am so new to programming so excuse my noob questions. First of all, this library seems to be obsolete, can i still use this one? Second question is i do not understand the changing #include thing. i try to use your code as written and it gives 'Messenger does not name a type'.
    – orionlogic
    Commented Oct 9, 2014 at 21:17
  • The library is still good, even though the page recommends to use CmdMessenger I find that that library is more complex than for what I need. To use the library, unzip it and then copy the Messenger folder (under Firmware) into you Arduino library folder (check where it is in preferences) and restart the Arduino IDE. In the file Messenger.cpp the 7th line is #include "WProgram.h". Change this to #include "Arduino.h", as this is the new header file used by the 1.XX versions of the Arduino system. Commented Oct 9, 2014 at 22:58
  • The error means the compiler can't find the definition of the class Messenger. The fix is to make sure that Messenger library is in the right place (as described above) and to put #include "Messenger.h" near the top of you sketch. Commented Oct 9, 2014 at 23:00
  • I try sketch examples for Messenger and still not compiles. Now it gives several errors which starts "WProgram.h: No such file or directory".
    – orionlogic
    Commented Oct 10, 2014 at 12:18
  • Change "WProgram.h" to "Arduino.h" in the examples. Commented Oct 10, 2014 at 12:30
1

int value = int(red(c1[0])); gives you 99 not 99.0

You could read a byte (that's what Serial.read returns; not an int), and make some decision based on that character, then read again.

Or, you could read all the available data till '\n' new line character comes. What println(value); line does it sends 99+'\n

Code:

// Buffer to store incoming commands from serial port
String inData;

void setup() {
    Serial.begin(9600);
    Serial.println("Waiting for Processing color...\n");
}

void loop() {
    while (Serial.available() > 0)
    {
        char recieved = Serial.read();
        inData += recieved; 

        // Process message when new line character is recieved
        if (recieved == '\n')
        {
            Serial.print("Arduino Received: ");
            Serial.print(inData);

            inData = ""; // Clear recieved buffer
        }
    }
}

In case this is not working change your processing code line:

myPort.write(value);

to

myPort.println(value);

or

myPort.write(value);
myPort.write('\n'); 
-1

The communication between the arduino and processing is 9600bit/s I suppose.

This will mean, that one bit needs 0.104ms to be sent. But with your Arduino code and the while-function you don't wait till the 8 bits of your byte are arrived and the arduino-loop is to fast for the serial connection. Wit other words: you cant use our wihile() function, use an if statement:

int x;
if (Serial.available()>0) {
  x = Serial.read();
}

and for debugging you can include once more the Serial.print()-function

(Sorry for my terrible English...)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.