Arduino to Processing RGB Screen Communication

Hello everyone, I've only been working with the Arduino for about a week and Processing much less then that. I'm working very hard to teach myself how it all works for a big project I want to do in the future, but I really want to understand it, not just follow tutorials and be satisfied.

Recently I followed a tutorial by Jeremy Blum about controlling the a single color of your screen using a pot and Processing.

I followed it and got it working well, but then I wanted to push it to control RGB color using three pots. I made the Arduino code and got it outputting serial communication stating each RGB value separated by a char.

ie.. R255G255B0

I'm not sure if I'm going about this in the right way or not but I'm completely stuck on the Processing side. There are a few texts out there about it but they are as clear as mud to me. I just included the base code without trying to read each value, all attempts were major failures. :drooling_face: Any help would be greatly appreciated. Thank you very much.

Arduino Code:

int RedPotPin = 0;
int GreenPotPin= 1;
int BluePotPin= 2;

void setup()
{
  pinMode(RedPotPin, INPUT);
  pinMode(GreenPotPin, INPUT);
  pinMode(BluePotPin, INPUT);
  Serial.begin(9600);
}

void loop()
{
  int RedVal = map(analogRead(RedPotPin), 0, 1023, 0, 255);
  int GreenVal = map(analogRead(GreenPotPin), 33, 972, 0, 255);
  int BlueVal = map(analogRead(BluePotPin), 0, 1023, 0, 255);
  Serial.print('R');
  Serial.print(RedVal);
  Serial.print("G");
  Serial.print(GreenVal);
  Serial.print("B");
  Serial.print(BlueVal);
  Serial.println();
  delay(100);
}

Processing Code:

import processing.serial.*;
Serial port;
float brightnessRed = 0;
float brightnessGreen = 0;
float brightnessBlue = 0;

void setup()
{
  size (500,500);
  port = new Serial(this, "COM3", 9600);
  port.bufferUntil('\n');
  
}

void draw()
{
  background(brightnessRed,brightnessGreen,brightnessBlue);
}

void serialEvent (Serial port)
{
 brightnessRed = float(port.readStringUntil('G'));
}

P.S. I know this has no real world application, I'm just trying it to learn.

I just included the base code without trying to read each value, all attempts were major failures.

That code might work, or it might not. Right now, I'd tend to think not.

You are asking Processing to read the serial data until it encounters a 'G'. That should result in it reading "R255" the first time. Then, you want it to convert that to a float. I don't see how you can expect that to work.

Without worrying about parsing the data, yet, use the bufferUntil() method (yes, you need to search for it) to tell Processing not to invoke the serialEvent() callback until a carriage return has arrived.

Never mind, I see that you are doing that.

Then, provide a serialEvent() method (search for the signature),

Never mind, I see that you are doing that.

In the serialEvent() callback, just read ALL the serial data.

Use print() to echo what you read.

When you get what you expect, then you can worry about parsing it.

Processing can convert a delimited string of data to an array of numeric values automatically. That suggests that sending 200,92,148 instead of R200G92B148 will be a lot easier to deal with.

Keep us posted on your progress.

Thank you PaulS for the advice. I finally kept searching and turns out the answers were in the Tutorial section of the main Arudino.cc site the whole time. Face Palm Doh!

Any way I wanted to share the working sketches and the Arduino layout in case anyone else wanted to give it a shot. As always, advice is welcome and if you do this please share your experience. :slight_smile:

Arduino Layout:

Arduino Code:

/*

 This is the Arduino half of the code to enable you to controll an RGB color swatch on your PC using an Arduino and three potentiometers
 
 This code was adapted from a tutorial called   Serial Call and Response in ASCII and can be found at http://www.arduino.cc/en/Tutorial/SerialCallResponseASCII
 
 The original code and this adaptation are both in the public domain.
 
 A personal thank you to all the authors of this tutorial!
 */

int RedVal = 0;    
int GreenVal = 0;   
int BlueVal = 0;    
int inByte = 0;         // incoming serial byte
int RedPotPin= A0;
int GreenPotPin=A1;
int BluePotPin= A2;

void setup()
{
  // start serial port at 9600 bps and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  pinMode(RedPotPin, INPUT);   
  pinMode(GreenPotPin, INPUT);  
  pinMode(BluePotPin, INPUT);  
  establishContact();  // send a byte to establish contact until receiver responds 
}

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    // I had to map my potentiometers values as they did not all have the same resistance. 
    RedVal = map(analogRead(RedPotPin), 0, 1023, 0, 255);

    GreenVal = map(analogRead(GreenPotPin), 33, 972, 0, 255);

    BlueVal = map(analogRead(BluePotPin), 0, 1023, 0, 255);
    // send sensor values:
    Serial.print(RedVal);
    Serial.print(",");
    Serial.print(GreenVal);
    Serial.print(",");
    Serial.println(BlueVal);               
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("0,0,0");   // send an initial string
    delay(300);
  }
}

Processing Code:

/*
This is the Processing half of the code to enable you to controll an RGB color swatch on your PC using an Arduino and three potentiometers

This code was adapted from a tutorial called   Serial Call and Response in ASCII and can be found at http://www.arduino.cc/en/Tutorial/SerialCallResponseASCII

The original code and this adaptation are both in the public domain.

A personal thank you to all the authors of this tutorial!
*/


import processing.serial.*;     // import the Processing serial library
Serial myPort;                  // The serial port
float BrightnessRed;
float BrightnessGreen;
float BrightnessBlue;


void setup() {
  size(640,480);
  myPort = new Serial(this, "COM3" , 9600);

  // read bytes into a buffer until you get a linefeed (ASCII 10):
  myPort.bufferUntil('\n');

}

void draw() {
  background(BrightnessRed,BrightnessGreen,BrightnessBlue);
}

// serialEvent  method is run automatically by the Processing applet
// whenever the buffer reaches the  byte value set in the bufferUntil() 
// method in the setup():

void serialEvent(Serial myPort) { 
  // read the serial buffer:
  String myString = myPort.readStringUntil('\n');
  // if you got any bytes other than the linefeed:
    myString = trim(myString);
    
    // split the string at the commas
    // and convert the sections into integers:
    int sensors[] = int(split(myString, ','));
    // print out the values you got:
    for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
      print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t"); 
    }
    // add a linefeed after all the sensor values are printed:
        println();
    if (sensors.length > 1) {
      BrightnessRed =sensors[0];
      BrightnessGreen = sensors [1];
      BrightnessBlue= sensors [2];
    }
    // send a byte to ask for more data:
    myPort.write("A");
  }