Help with Arduino-Processing Serial Communication

Hi!

I hope this is the right place to post this. I am working on what I would like to be a big LED project using an interface between arduino and processing, with Processing generating patterns and sending them to the Arduino to display. To test the feasibility of this, I wrote a test code for Processing to send a string of data to the Arduino via Serial, and for the Arduino to read that string and display the corresponding pattern on a 3 by 3 LED matrix. However, the code produces absolutely no result, and I can’t for the life of me figure out why.

Here is my Arduino code

#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 9

// define the Data Pin
#define DATA_PIN 2

// Define the array of leds
CRGB leds[NUM_LEDS];

// Use a reading boolean
boolean reading = false;
String string = ""; // where we ll store the pattern data


void setup() {
  Serial.begin(9600);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
}


void loop() {
  if (Serial.available() ) {
    if (reading == false) {
      char ch = Serial.read();
      if (ch == '9') {
        reading = true;
      }
    }else{
      char ch = Serial.read();
      if (ch != 8) {
        string = string + ch;
      } else {
        readLights(string);
        reading = false;
        string = "";
      }
    }
  }
  FastLED.show();
}

void readLights(String string) {
  for(int i=1; i<10; i++){ // read only the characters that aren't the 9 which means start and the 8 which means end
    char c = string.charAt(i);
    if(c == 1) {
        leds[i-1] = CRGB(0, 0, 225);
    }else{
      leds[i-1] = CRGB(255, 0, 0);
    }
  }
}

And here is my processing code:

import processing.serial.*;

Serial myPort;
//the string I want to send
String stringOut = "91211211218"; //9 means start, 8 means end, the rest is the pattern

char[] strChar;

void setup() {
  // punt my string from a string to a char array
  strChar = stringOut.toCharArray();
  //set up serial port for your arduino
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 9600);
}

//global index into the char array
int i=0;


void draw() {
  // nothing to draw all don upstairs in serial event
  for (int i = 0; i<stringOut.length(); i++) {
    myPort.write(strChar[i]);
  }
}

If anyone had any idea of what I am doing wrong it would be amazing!! Also, is there any other way to communicate strings to the Arduino than via Serial? I have heard good things about Firmata but it doesn’t look compatible with the FastLED library.
Anyway thanks a lot if anyone have an idea on what I am doing wrong! It’s probably very obvious but I am completely new to Arduino :frowning:

String stringOut = "91211211218"; //9 means start, 8 means end, the rest is the pattern

Why not use some characters that are recognizably different.

String stringOut = "<121121121>"; // < means start, > means end, the rest is the pattern

Why not use the traditional 1 = on, 0 = off values?

String portName = Serial.list()[1];
myPort = new Serial(this, portName, 9600);

Are you ABSOLUTELY certain that the Arduino is listening to the 2nd port in the list?

  // nothing to draw all don upstairs in serial event
  for (int i = 0; i<stringOut.length(); i++) {
    myPort.write(strChar[i]);
  }

The comment is nonsense. There is no serialEvent() function. Even if there was, it is not “upstairs”.

The write() method CAN take a String.

void readLights(String string) {
  for(int i=1; i<10; i++){ // read only the characters that aren't the 9 which means start and the 8 which means end
    char c = string.charAt(i);
    if(c == 1) {
        leds[i-1] = CRGB(0, 0, 225);

You did NOT store the 9 or the 8 in the String, so “avoiding” them is not necessary. You stored some number of characters in the String, so the length of the String should define the number of iterations - NOT a hard-coded value.

Put every { and every } on lines by themselves. Use Tools + Auto Format.

}else{

Just plain looks stupid. At the very least, use spaces between the } and the statement and between the statement and the {.

Thanks a lot for the help! The comment was something from a previous try I forgot to delete, and writing parentheses on the same line is just how I learned Processing, I find it quite hard to do without now…
Anyway, I cleaned up the code following your advice and now when I run the Processing sketch all my lights turn green, which is progress but still extremely puzzling…

New arduino code:

#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 9

// Define the data pin of the LEDs
#define DATA_PIN 2

// Define the array of leds
CRGB leds[NUM_LEDS];

// Use a reading boolean
boolean reading = false;
String string = "";

void setup() {
  Serial.begin(9600);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
}


void loop() {
  if (Serial.available() ) {
    if (reading == false) {
      char ch = Serial.read();
      if (ch == '<') {
        reading = true;
      }
    } else {
      char ch = Serial.read();
      if (ch != '>') {
        string = string + ch;
      } else {
        readLights(string);
        reading = false;
        string = "";
      }
    }
  }
}

New Processing code

import processing.serial.*;

Serial myPort;
//the string I want to send
String stringOut = "<121121121>";


void setup() {
  // punt my string from a string to a char array
  //set up serial port for your arduino
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  myPort.write(stringOut);
}

At least I know some communication is happening, but I still don’t really understand the result…

when I run the Processing sketch all my lights turn green, which is progress but still extremely puzzling...

New arduino code:

That is missing the readLights() function, which needed changes, too.

Oh my bad! It was in a different tab and I forgot to copy paste it…

void readLights(String string) {
  for (int i = 0; i < string.length(); i++) {
    char c = string.charAt(i);
    if (c == 1) {
      leds[i] = CRGB(0, 0, 255);
    } else {
      leds[i] = CRGB(255, 0, 0);
    }
  }
  FastLED.show();
}
    char c = string.charAt(i);
    if (c == 1) {
      leds[i] = CRGB(0, 0, 255);
    } else {
      leds[i] = CRGB(255, 0, 0);
    }

The character '1' is not the same value as the number 1.

   if(c == '1')

Oh god how can I be so blind. Thanks a lot for the help, much appreciated, the test works now!

Oh god how can I be so blind.

It's amazingly easy, really. Done there; done that; got the t-shirt!