LED CONTROL Serial myPort vs. Serial port

I am trying to control multiple LEDs but I am not quite sure on how to adjust my code accordingly. I have a master code that runs an RTC clock module and a light sensor to an LED. I have separated both my codes. I was able to control an LED simply by connecting it to ground and pin 9 on an Arduino board. After running processing for just that, I was able to turn the LED on/off. Once I tried to combine it with my master code, I believe the problem was that I am using

port = new Serial(this, "/dev/cu.usbmodem14331", 9600); 

and

  myPort = new Serial(this, Serial.list()[3], 9600); 
  myPort.bufferUntil(lf);
  delay(1000);

(this is for the sensor)

together.

Below is the Processing code for only the on/off buttons.

import controlP5.*; //library
import processing.serial.*; //library
Serial port; //do not change
ControlP5 cp5; //create ControlP5 object
PFont font; //do not change

void setup() { //same as arduino program

size(300, 300); //window size, (width, height)
port = new Serial(this, "/dev/cu.usbmodem14331", 9600); //connected arduino port
cp5 = new ControlP5(this); //do not change
font = createFont("Georgia Bold", 20); //font for buttons and title

cp5.addButton("ON") //name of button
.setPosition(95, 50) //x and y upper left corner of button
.setSize(120, 70) //(width, height)
.setFont(font) //font`
.setColorBackground(color(255, 0, 0)) //background r,g,b
.setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
.setColorLabel(color(0, 0, 0)) //text color r,g,b
;

cp5.addButton("OFF")
.setPosition(95, 150)
.setSize(120, 70)
.setFont(font)
.setColorBackground(color(255, 0, 0))
.setColorForeground(color(0, 255, 0))
.setColorLabel(color(0, 0, 0))
;
}

void draw() {

background(0, 0, 0); // background color of window (r, g, b)

}

void ON() {
port.write(1);
}

void OFF() {
port.write(2);
}

Below is the Arduino code for only the on/off button:

void setup() {

pinMode(9, OUTPUT); //set pin as output , red led

Serial.begin(9600); //start serial
}

void loop(){

if(Serial.available()){ //id data available

int val = Serial.read();

if(val == 1){ //if 1 received
digitalWrite(9, HIGH); //turn on
}
if(val == 2){ //if 2 received
digitalWrite(9, LOW); //turn off
}

}
}

What I am trying to do is to combine these codes into my master, but I am still getting errors with the port.

Here is my master code for Processing:

import controlP5.*; //import ControlPS library
import processing.serial.*;
Serial port; 
Serial myPort; //serial port
String inString; //input string from serial port
int lf = 10; //ASCII linefeed

ControlP5 cp5; //create ControlPS object
PFont font;


void setup(){
  size(600,800); //window size, (width, height)
  
  
  
  //adding buttons
  
  cp5 = new ControlP5(this);
 
  font = createFont("calibri light", 14); //fonts for buttons and title
  
  
    cp5.addButton("Room 1 ON")
    .setPosition(50, 50) //x and y coordinates of upper left corner of button
    .setSize(120, 70) //(width, height)
    .setFont (font)
    .setColorBackground(color(255, 0, 0)) //background r,g,b
    .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
    .setColorLabel(color(0, 0, 0))
    ;
    
     cp5.addButton("Room 1 OFF")
    .setPosition(180, 50) //x and y coordinates of upper left corner of button
    .setSize(120, 70) //(width, height)
    .setFont (font)
    .setColorBackground(color(255, 0, 0)) //background r,g,b
    .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
    .setColorLabel(color(0, 0, 0))
  ;
    cp5.addButton("Room 2 ON")
    .setPosition(50, 200) //x and y coordinates of upper left corner of button
    .setSize(120, 70) //(width, height)
    .setFont (font)
    .setColorBackground(color(255, 0, 0)) //background r,g,b
    .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
    .setColorLabel(color(0, 0, 0))
    ;
    
     cp5.addButton("Room 2 OFF")
    .setPosition(180, 200) //x and y coordinates of upper left corner of button
    .setSize(120, 70) //(width, height)
    .setFont (font)
    .setColorBackground(color(255, 0, 0)) //background r,g,b
    .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
    .setColorLabel(color(0, 0, 0))
    
  ;    cp5.addButton("Room 3 ON")
    .setPosition(50, 350) //x and y coordinates of upper left corner of button
    .setSize(120, 70) //(width, height)
    .setFont (font)
    .setColorBackground(color(255, 0, 0)) //background r,g,b
    .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
    .setColorLabel(color(0, 0, 0))
    ;
    
     cp5.addButton("Room 3 OFF")
    .setPosition(180, 350) //x and y coordinates of upper left corner of button
    .setSize(120, 70) //(width, height)
    .setFont (font)
    .setColorBackground(color(255, 0, 0)) //background r,g,b
    .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
    .setColorLabel(color(0, 0, 0))
  ;
  
    
  // List all the available serial ports: 
  printArray(Serial.list()); 
  
  // Open whatever port is the one you're using. 
  myPort = new Serial(this, Serial.list()[3], 9600); 
  myPort.bufferUntil(lf);
  delay(1000);
    
  myPort = new Serial(this, Serial.list()[2], 9600); 
  myPort.bufferUntil(lf);
  delay(1000);
  
  myPort = new Serial(this, Serial.list()[1], 9600); 
  myPort.bufferUntil(lf);
  delay(1000);
 
  ;  
  cp5.addButton("Errors")
    .setPosition(60, 500)
    .setSize(125, 100)
    .setFont (font)
  ;
  cp5.addButton("Alarms")
    .setPosition(60, 650)
    .setSize(125, 100)
    .setFont (font)
  ;
}
void draw(){ 
  background(0, 0, 0); //background color of window 
  
  //text
  fill(0, 255, 0); // (r, g, b) or (0 to 255)
  text("CONTROL CENTER", 250, 30);

background(0); 
  text("Sensor Reading 1: " + inString, 325,100); 
  text("Sensor Reading 2: " + inString, 325,250);  //will need to revise once 3 sensors connected
  text("Sensor Reading 3: " + inString, 325,400); 
  } 
  
void ON() {
port.write(1);
}

void OFF() {
port.write(2);
}

 
void serialEvent(Serial p) 
  { 
  inString = p.readString(); 

}

Below is my master Arduino code:

#include <TimeLib.h>
#include <TimeAlarms.h>
#include <Wire.h>
#include <SparkFunDS1307RTC.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h" // the photoresistor module

const int led = 9;
int brightness = 255; // how bright the LED is
int fadeAmount = 1; // how many points to fade the LED by
int targetbrightness = 255; // target brightness
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);
//configure TSL2591
void configureSensor(void)
{
  tsl.setGain(TSL2591_GAIN_MED);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
  
  Serial.println(F("------------------------------------"));
  Serial.print  (F("Gain:         "));
  tsl2591Gain_t gain = tsl.getGain();
  switch(gain)
  {
    case TSL2591_GAIN_LOW:
      Serial.println(F("1x (Low)"));
      break;
    case TSL2591_GAIN_MED:
      Serial.println(F("25x (Medium)"));
      break;
    case TSL2591_GAIN_HIGH:
      Serial.println(F("428x (High)"));
      break;
    case TSL2591_GAIN_MAX:
      Serial.println(F("9876x (Max)"));
      break;
  }
  Serial.print  (F("Timing:       "));
  Serial.print((tsl.getTiming() + 1) * 100, DEC); 
  Serial.println(F(" ms"));
  Serial.println(F("------------------------------------"));
}
void setup() {
  // prepare pin as output
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW); 
  Serial.begin(9600);
  rtc.autoTime();
  // wait for Arduino Serial Monitor
  while (!Serial) ;
  
  // get and set the time from the RTC
  setSyncProvider(RTC.get);  
  if (timeStatus() != timeSet)
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");    
  
  // To test your project, we can set the time manually by uncommenting bottom line
  //setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011

  // create the alarms, to trigger functions at specific times
  Alarm.alarmRepeat(6,00,0,MorningAlarm);  // 9:00am every day
  Alarm.alarmRepeat(19,00,0,EveningAlarm);  // 19:00 -> 7:00pm every day
  // TSL2591
    Serial.println(F("Starting Adafruit TSL2591..."));
  
  if (tsl.begin()) 
  {
    Serial.println(F("Found a TSL2591 sensor"));
  } 
  else 
  {
    Serial.println(F("No sensor found ..."));
    while (1);
  }
  configureSensor();
}

// The first "flag" for checking the Lux levels. If the Lux level is less than 500 then luxCheck will be 0.
int luxCheck;

// Reads IR and full spectrum then converts to Lux and checks for less than 500 Lux value
void advancedRead(void)
{
  sensors_event_t event;
  tsl.getEvent(&event);
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;
  Serial.println(tsl.calculateLux(full, ir), 6);
  if ((event.light < 500))
    {
      luxCheck = 0;
      Serial.println(F("WARNING: LUX NOT WITHIN DESIRED RANGE!"));
      Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 2);
    }
    else
      { 
        luxCheck = 1;
        Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 2);
      }
}


void loop() {
  analogWrite(led, brightness);
  if (hour() >= 6 && hour()<= 11) {
    brightness = brightness + fadeAmount/18000;
  }
  else if (hour() > 11 && hour() <= 19) {
    brightness = brightness - fadeAmount/28800;
  }
  else { brightness = 0;
  }
  
  // wait one second between each clock display in serial monitor
  Alarm.delay(1000);
  advancedRead();
}

// functions to be called when an alarm triggers
void MorningAlarm() {
  // write here the task to perform every morning
  Serial.println("Turn light on");
  digitalWrite(led, HIGH);
}
void EveningAlarm() {
  // write here the task to perform every evening
  Serial.println("Turn light off");
  digitalWrite(led, LOW);
}

void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}
void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Please let me know if you have any suggestions that will help me. Thank you in advance.

1 Like

Serial.list() will return the available ports.
As they are used up, the list would change.

Try this:

String[] availablePorts = Serial.list();

printArray(availablePorts); 

myPort = new Serial(this, availablePorts[3], 9600); 
// etc.
1 Like

Some references:

https://processing.org/reference/libraries/serial/Serial.html
https://processing.org/reference/libraries/serial/Serial_list_.html

1 Like

Is there a way to combine the two codes?

I tried that but the LED won’t turn on/off. When I try to paste the Arduino code into the master file, it gives me errors. I’m already using the port for my sensor so I’m not quite sure if it’ll still pull the same one for the LEDs. The problem now is combining the two codes to run properly.

I did not see in your code initializing “port”.

Serial port; 

Not setting that would cause an null pointer exception in either ON() or OFF() functions.

void ON() {
port.write(1);
}

void OFF() {
port.write(2);
}

Each of your serial ports are created with a reference of “myPort” but only the last one will be remain assigned to that variable.

Did you mean to set “port” to one of those?

1 Like

You need to have a current limiting resistor in series with the LED.
See discussion here:
Arduino Digital Pins
Do I really need resistors when controlling LEDs with Arduino?

Is this (below) correct?

  • One Arduino is connected to one Processing sketch though one serial port.
  • Arduino is sending sensor data to Processing
  • Processing is sending “LED state” data to Arduino
1 Like

I have the resistor connected in series with the LED but for some reason I am getting errors on the coding portion of both processing and arduino when combining the two.

What specific errors are you getting?

This section is still of interest to me:

  printArray(Serial.list()); 
  
  // Open whatever port is the one you're using. 
  myPort = new Serial(this, Serial.list()[3], 9600); 
  myPort.bufferUntil(lf);
  delay(1000);
    
  myPort = new Serial(this, Serial.list()[2], 9600); 
  myPort.bufferUntil(lf);
  delay(1000);
  
  myPort = new Serial(this, Serial.list()[1], 9600); 
  myPort.bufferUntil(lf);
  delay(1000);

What is printed when you add “printArray(Serial.list());” after each delay?

This is the error I get back when combining the processing code.
“printArray(Serial.list());” displays the lux readings from the light sensor. It takes the data from the serial monitor of the Arduino and transfers it over into Processing.

I expect “printArray(Serial.list());” to show available serial ports on your computer.

Port busy

Do you still have the Arduino monitor open when trying to run the Processing sketch?

Sorry, you are correct. I misread.
The Arduino monitor is not opened when I am running the Processing sketch.

The “port busy” suggests that the port has already been asigned to something.

Are you able to run a multi-LED setup? (without other sensors)
The following is based on your initial example.

Disclaimer: I currently do not have access to multiple devices to try this.

import controlP5.*; //library
import processing.serial.*; //library
Serial port1, port2, port3; //do not change
ControlP5 cp5; //create ControlP5 object
PFont font; //do not change


String SERIAL_PORT_1 = "Set these to device serial ports";
String SERIAL_PORT_2 = "Set these to device serial ports";
String SERIAL_PORT_3 = "Set these to device serial ports";


void setup()
{
  size(640, 480); //window size, (width, height)
  port1 = new Serial(this, SERIAL_PORT_1, 9600); //connected arduino port
  port2 = new Serial(this, SERIAL_PORT_2, 9600); //connected arduino port
  port3 = new Serial(this, SERIAL_PORT_3, 9600); //connected arduino port
  
  cp5 = new ControlP5(this); //do not change
  font = createFont("Georgia Bold", 20); //font for buttons and title

  cp5.addButton("ON_1") //name of button
  .setPosition(20, 20) //x and y upper left corner of button
  .setSize(120, 70) //(width, height)
  .setFont(font) //font`
  .setColorBackground(color(255, 0, 0)) //background r,g,b
  .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
  .setColorLabel(color(0, 0, 0)) //text color r,g,b
  ;

  cp5.addButton("OFF_1")
  .setPosition(20, 100)
  .setSize(120, 70)
  .setFont(font)
  .setColorBackground(color(255, 0, 0))
  .setColorForeground(color(0, 255, 0))
  .setColorLabel(color(0, 0, 0))
  ;
  
  
  cp5.addButton("ON_2") //name of button
  .setPosition(160, 20) //x and y upper left corner of button
  .setSize(120, 70) //(width, height)
  .setFont(font) //font`
  .setColorBackground(color(255, 0, 0)) //background r,g,b
  .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
  .setColorLabel(color(0, 0, 0)) //text color r,g,b
  ;

  cp5.addButton("OFF_2")
  .setPosition(160, 100)
  .setSize(120, 70)
  .setFont(font)
  .setColorBackground(color(255, 0, 0))
  .setColorForeground(color(0, 255, 0))
  .setColorLabel(color(0, 0, 0))
  ;
  
  
  cp5.addButton("ON_3") //name of button
  .setPosition(300, 20) //x and y upper left corner of button
  .setSize(120, 70) //(width, height)
  .setFont(font) //font`
  .setColorBackground(color(255, 0, 0)) //background r,g,b
  .setColorForeground(color(0, 255, 0)) //mouse over color r,g,b
  .setColorLabel(color(0, 0, 0)) //text color r,g,b
  ;

  cp5.addButton("OFF_3")
  .setPosition(300, 100)
  .setSize(120, 70)
  .setFont(font)
  .setColorBackground(color(255, 0, 0))
  .setColorForeground(color(0, 255, 0))
  .setColorLabel(color(0, 0, 0))
  ;
}

void draw()
{
  background(0, 0, 0); // background color of window (r, g, b)
}

void ON_1() {
  port1.write(1);
}

void OFF_1() {
  port1.write(2);
}


void ON_2() {
  port2.write(1);
}

void OFF_2() {
  port2.write(2);
}

void ON_3() {
  port3.write(1);
}

void OFF_3() {
  port3.write(2);
}
1 Like

I did not get an answer to this:

You only require one serial port connection between Arduino and Processing for above.

If you are sending a single byte from Processing to Arduino to control LEDs you have 256 states to chose from (0 to 255) and these can control the LEDs and be sent with one serial port; you do not need multiple serial ports.

0, 1 can be ON, OFF for LED 1
2, 3 can be ON, OFF for LED 2
etc.

The same serial port can receive data from Arduino to Processing.

This statement is not correct:

See reference:
https://processing.org/reference/libraries/serial/Serial_list_.html

There are a lot of resources out there for communicating between Arduino and Processing; I encourage you do do some more research on the subject before tackling this exercise.

1 Like

“Error importing serial port Set these to device serial ports: Port not found”

I am only testing on an individual LED as of now, with a single sensor. I keep getting errors when trying to to combine the processing codes still.

Those Strings must match the serial port path to each of your devices.
From your previous example:

"/dev/cu.usbmodem14331"

That is also why it is very important to know what is coming from the following prior to selecting an index from it:

Serial.list()
1 Like