0
votes

I'm trying to send a number value over serial to an Arduino to control an Individually Addressable LEDstrip. Using the Arduino IDE "Serial Monitor" I'm able to send a number to the light strip with no issue. However when i try to do it externally by reading from a text file in processing it doesn't go through.

After some debugging I can see that Processing has the number right and its stored in the variable. However the lightstip will only ever light up on led, instead of the number given.

Processing Code:

import processing.serial.*;
import java.io.*;


Serial myPort;  // Create object from Serial class

void setup() 
{
  size(200,200); //make our canvas 200 x 200 pixels big
  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, portName, 9600);
}
void draw() 
{
  while(true) {
  // Read data from the file
  {
    String[] lines = loadStrings("Lifenumber.txt");
    int number = Integer.parseInt(lines[0]);
    println(number);
    myPort.write(number);
    delay(5000);
  }
  }
}

Arduino Code:

if ( Serial.available()) // Check to see if at least one character is available
  {
    char ch = Serial.read();
      if(index <  3 && ch >= '0' && ch <= '9'){
      strValue[index++] = ch; 
      }
      else
      {
        Lnum = atoi(strValue);
        Serial.println(Lnum);
        for(i = 0; i < 144; i++)
        {
          leds[i] = CRGB::Black; 
          FastLED.show(); 
          delay(1);

        }
        re = 1;
        index = 0;
        strValue[index] = 0; 
        strValue[index+1] = 0; 
        strValue[index+2] = 0; 
    }
  }

What I want the program to do is read a number from a text file and light up that number of LEDs on the 144led lightstrip.

1
A big difference between write and println. ( You want myPort.println(number); )datafiddler
@datafiddler It says The Function "println(int)" does not existEpsilon Rho
@EpsilonRho what does that number from the text file look like and what does it represent ? (e.g. is it the number of LEDs you want turned on ? is it a brightness value for all LEDs ? )George Profenza
Also, do you need to reload that text file every 5 seconds ?George Profenza
@George Profenza They Don't, I just have it on a loop for testing. and yes the number in the text file represents how many leds should light up.Epsilon Rho

1 Answers

0
votes

Here are a couple of comments on your code that should help make improvements in the future. It's important to form good coding habits early on: it will make your life so much easier (I'm speaking a mostly self taught programmer that started with flash so I know what messy and hacky is ;) )

import processing.serial.*;
//import java.io.*; // don't include unused imports


Serial myPort;  // Create object from Serial class

void setup() 
{
  size(200,200); //make our canvas 200 x 200 pixels big
  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  // handle error initialising Serial
  try{
    myPort = new Serial(this, portName, 9600);
  }catch(Exception e){
    println("Error initializing Serial port " + portName);
    e.printStackTrace();
  }
}
void draw() 
{
  // don't use blocking while, draw() already gets called continuously
  //while(true) {
  // Read data from the file
  //{
    // don't load the file over and over again
    String[] lines = loadStrings("Lifenumber.txt");
    int number = Integer.parseInt(lines[0]);// int(lines[0]) works in Processing, but the Java approach is ok too
    println("parsed number: " + number);
    if(myPort != null){
      myPort.write(number);
    }
    // don't use blocking delays, ideally not even in Arduino
    //delay(5000);
  //}
  //}
}

Here's a version of the Processing code that loads the text file, parses the integer then sends it to serial only once (if everything is ok, otherwise basic error checking should reveal debug friendly information):

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

void setup() 
{
  size(200,200); //make our canvas 200 x 200 pixels big
  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  // handle error initialising Serial
  try{
    myPort = new Serial(this, portName, 9600);
  }catch(Exception e){
    println("Error initializing Serial port " + portName);
    e.printStackTrace();
  }
  // Read data from the file
  try{
    String[] lines = loadStrings("Lifenumber.txt");
    int number = Integer.parseInt(lines[0]);
    println("parsed number: " + number);
    // validate the data, just in case something went wrong
    if(number < 0 && number > 255){
      println("invalid number: " + number + ", expecting 0-255 byte sized values only");
      return;
    }
    if(myPort != null){
      myPort.write(number);
    }
  }catch(Exception e){
    println("Error loading text file");
    e.printStackTrace();
  }
}
void draw() 
{
  // display the latest value if you want
}

// add a keyboard shortcut to reload if you need to

Your strip has 144 leds (less than 255) which fits nicely in a single byte which is what the Processing sketch sends

On the Arduino side there's nothing too crazy going on, so as long as you validate the data coming in should be fine:

#include "FastLED.h"

#define NUM_LEDS 64 
#define DATA_PIN 7
#define CLOCK_PIN 13

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

int numLEDsLit = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("resetting");
  LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
  LEDS.setBrightness(84);
}

void loop() {
  updateSerial();
  updateLEDs();
}

void updateSerial(){
  // if there's at least one byte to read
  if( Serial.available() > 0 )
  {
    // read it and assign it to the number of LEDs to light up
    numLEDsLit = Serial.read();
    // constrain to a valid range (just in case something goes funny and we get a -1, etc.)
    numLEDsLit = constrain(numLEDsLit,0,NUM_LEDS);
  }  
}

// uses blacking delay
void updateLEDs(){
  // for each LED
  for(int i = 0; i < 144; i++)
  {
    // light up only the number of LEDs received via Serial, turn the LEDs off otherwise
    if(i < numLEDsLit){
      leds[i] = CRGB::White;
    }else{
      leds[i] = CRGB::Black;
    }
    FastLED.show(); 
    delay(1);  
  }
}

Adjust the pins/LED chipsets/etc. based on your actual physical setup.