Send String from Processing to Arduino

Hello all,

I have been working on a project with my Arduino Mega 2560 and WS2812B addressable LED lights. The Arduino IDE code determines the colour of each LED based on the letter in the corresponding string of characters e.g. “ABACBABABCABAB”. This is used to light up 254 LEDs and works as expected.

The trouble I am having is with the next step of being able to create a GUI that allows for a user to select a pattern from a list of 100s and for the Arduino to pick up on that new string of characters to change the LED pattern.

I am using the serial port to send this string to Arduino and when I enter a pattern into the Serial Monitor it works great. However, I am having trouble on communicating this string to the serial port using Processing.

The plan is to use processing to create a GUI that allows users to simply select the pattern and for it to send the string to the Serial Port. I am stuck at why this isn’t sending and can’t troubleshoot because I can’t open the serial monitor on Arduino and send the string from Processing at the same time.

Here is the Arduino code:

#include <FastLED.h>
#define NUM_LEDS 50
// Data pin that led data will be written out over
#define DATA_PIN 6
#define BRIGHTNESS  32
CRGB leds[NUM_LEDS];
const byte numChars = 200;
char receivedChars[numChars];

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
    FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
    FastLED.setBrightness(BRIGHTNESS);

}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
    String   str = receivedChars;
     for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      if (str.charAt(whiteLed) == 'A') {
      leds[whiteLed] = CRGB::Green;
      }
      if (str.charAt(whiteLed) == 'B') {
      leds[whiteLed] = CRGB::Blue;
      }
      if (str.charAt(whiteLed) == 'C') {
      leds[whiteLed] = CRGB::Yellow;
      }
      if (str.charAt(whiteLed) == 'D') {
      leds[whiteLed] = CRGB::Pink;
      }
      if (str.charAt(whiteLed) == 'E') {
      leds[whiteLed] = CRGB::Orange;
      }
      if (str.charAt(whiteLed) == 'F') {
      leds[whiteLed] = CRGB::White;
      }
      if (str.charAt(whiteLed) == 'G') {
      leds[whiteLed] = CRGB::Red;
      }
      if (str.charAt(whiteLed) == 'H') {
      leds[whiteLed] = CRGB::Brown;
      }
      if (str.charAt(whiteLed) == 'X') {
      leds[whiteLed] = CRGB::Black;
      }
      } 
      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

        newData = false;
    }
}

Here is the simple processing code

import processing.serial.*;       //use the Serial library
Serial myPort;                    // Create object from Serial class   

void setup() {
  
  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
   myPort = new Serial(this, portName, 9600);       //initialize the serial port object
}

void draw() {                    //this is like the 'loop' section of code on Arduino



String pattern = "<AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB>";
   myPort.write(pattern);
 
}

Any help is much appreciated, I am new to all of this so apologies for any mistakes.

D

Have you taken into account that when Processing opens the serial port the Arduino is reset ?

Are you sure that the Processing serial port that the Arduino is connected is the first in the serial list. Print the list to make sure.

Are you sure that the Processing serial port that the Arduino is connected is the first in the serial list (Serial.list[0]). Print the list to make sure.

  1. you can explicitly use this as well
myPort = new Serial(this, "COM6", 9600);  // assume arduino is on COM6
  1. you need to 'close' serial monitor(on arduino ide) for processing ide to 'talk' to arduino

  2. and this one sends string to arduino from processing

myPort.write("hello from processing ide");

check this out for more

groundFungus:
Are you sure that the Processing serial port that the Arduino is connected is the first in the serial list (Serial.list[0]). Print the list to make sure.

Hello,

Yes I believe so, just to double check, I have attached a print screen:

UKHeliBob:
Have you taken into account that when Processing opens the serial port the Arduino is reset ?

Hello, I upload the code from Arduino IDE then run the code on Processing, is this the correct order in doing it?

There is no correct order. The programs must be running on both sides. The opening of the Serial link causes Arduino to reset

UKHeliBob:
There is no correct order. The programs must be running on both sides. The opening of the Serial link causes Arduino to reset

This is what I am hoping for. The idea is that a user can use processing to send a string to arduino and for it to automatically reset and update the new pattern.

When I run the processing programme nothing seems to happen. Do I need to send each character one at a time or should I be able to send the full string to arduino and have it store it?

There is no need to reset the Arduino if you write the programs correctly. When the program is running on the Arduino, whether or not it is outputting a pattern it should be looking for Serial input with a view to reacting to it.

Using serial, only one character will be sent at a time in any case.

Write a simple Arduino sketch that waits until serial data is available and when a character arrives print it to the Serial monitor. User Serial1, Serial2 or Serial3 on the Mega so that you can use Serial to output the received characters to the Serial monitor

Yes I believe so, just to double check, I have attached a print screen:

It is the serial list in the processing program, not Arduino. Print the list. Is COM4 the first on the list?

Here is your processing code modified to print the port list. The Arduino's port needs to be the first on the list (leftmost). Or change the index of the list in the String portName = Serial.list()[0] line.

import processing.serial.*;       //use the Serial library
Serial myPort;                    // Create object from Serial class   

void setup() {
  print (Serial.list());  // print the port list
  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, portName, 9600);       //initialize the serial port object
}

void draw() {                    //this is like the 'loop' section of code on Arduino



  String pattern = "<AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB>";
  myPort.write(pattern);
}

The port list is in the red square

Just an outside idea, but does processing have a myPort.print(pattern); function instead of myPort.write(pattern);?

Just an outside idea, but does processing have a myPort.print(pattern); function instead of myPort.write(pattern);?

Nope.

"Nope."

Then I would study the magic behind the scenes differences between the "write" and "print" functions. I assume the serial monitor (which works for the OP) uses a "print" type function, where as the processing code usesn a "write" type function. I assume there is a difference between the two with the output result being different.

groundFungus:
It is the serial list in the processing program, not Arduino. Print the list. Is COM4 the first on the list?

Here is your processing code modified to print the port list. The Arduino's port needs to be the first on the list (leftmost). Or change the index of the list in the String portName = Serial.list()[0] line.

import processing.serial.*;       //use the Serial library

Serial myPort;                    // Create object from Serial class

void setup() {
 print (Serial.list());  // print the port list
 String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
 myPort = new Serial(this, portName, 9600);       //initialize the serial port object
}

void draw() {                    //this is like the 'loop' section of code on Arduino

String pattern = "";
 myPort.write(pattern);
}




The port list is in the red square
![port list.jpg|1107x781](upload://aohM9P02r5n4MQcwHkffizcXiWI.jpeg)

Yes it is COM4

zoomkat:
"Nope."

Then I would study the magic behind the scenes differences between the "write" and "print" functions. I assume the serial monitor (which works for the OP) uses a "print" type function, where as the processing code usesn a "write" type function. I assume there is a difference between the two with the output result being different.

I can't seem to find any other function for Processing that allows me to print to the serial port.

“I can’t seem to find any other function for Processing that allows me to print to the serial port.”

Looking at the below, does processing give any errors when it tries to “write” a “String” to the serial port? You might need to convert the String into an array and then “write” that to the serial port.

String pattern = "<AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB>";
myPort.write(pattern);

No errors. I set up an Uno with a software serial port for Processing to talk to and Serial prints the the serial monitor. Processing is sending the ASCII codes for the data.
Processing code:

import processing.serial.*;       //use the Serial library
Serial myPort;                    // Create object from Serial class   

void setup() {
 
  //String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
   myPort = new Serial(this, "COM7", 9600);       //initialize the serial port object
}

void draw() {                    //this is like the 'loop' section of code on Arduino
String pattern = "<AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB>";
   myPort.write(pattern);
   delay(1000);  // slow down the transmission of serial data 
}

Uno code:

#include <SoftwareSerial.h>

SoftwareSerial ssPort(4,7);

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

void loop()
{
  if(ssPort.available())
  {
   Serial.print(char(ssPort.read()));
  }
}

Uno serial monitor output:

<AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB><AAABBBABCCCAAABCCCCBAAAABCCCCCAAAABBB>

Hey all,

Thanks very much for help. I found this webpage that had some processing code. Link can be found here:

To my surprise copying this code into Processing, worked perfectly with my Arduino code.

Will have to read through it and try and understand the differences.

"To my surprise copying this code into Processing, worked perfectly with my Arduino code."

Which part of the code did you use, the writing to the serial port or the comport identification?