Help with controling the brightness of 3 LED's using processing.

Hi,

I am trying to use processing to allow my computer to control the brightness of the LED's in my sketch. I just can't figure out how to do it though. I am very new to Arduino and just got started a few days ago. Can someone add to my code so that it works? Also, can someone help simplify my code, as it is rather long. My sketch will automatically turn on the LED's and have them blink at the speed that is set with the pot if the room is dark. You can also force them to stay on and blink at the speed that is set with the pot if you press the button connected to the Arduino. I have connected everything using a breadboard. I am using the same processing code that is in this Arduino tutorial, http://arduino.cc/en/Tutorial/Dimmer. Here is my sketch.

/* This program uses a potentiometer, a light sensor, and a button to control the blinking of 3 LEDS
*/

// constants won't change
const int butPin = 2; // pin the button is on
const int potPin = A0; // pin the potentiometer is on
const int lightPin= A1; // pin the light sensor is on
const int redLedPin = 11; // pin the red LED is on
const int greenLedPin = 10; // pin the green LED is on
const int blueLedPin = 9; // pin the blue LED is on

// variables will change
int potVal; // the potentiometers value
int butVal; // the buttons value
int state = LOW; // state to put the LEDs in
int previous = LOW; // previous state of LEDs
int lightValue = 0; // the value of the light sensor
int lightMin = 1023; // the minimum light sensor value
int lightMax = 0; // the maximum light sensor value

long time = 0;
long debounce = 200; // the debounce timer

void setup() {
// we set the pin modes here, they should be self explanitory
pinMode(13, OUTPUT);
pinMode(butPin, INPUT);
pinMode(potPin, INPUT);
pinMode(lightPin, INPUT);
pinMode(redLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(blueLedPin, OUTPUT);
// we use an attachInterrupt here to interrupt the prgram and jump back to loop when the button is pressed
attachInterrupt(0, loop, RISING);
// serial for debugging
Serial.begin(9600);
// These lights tell uss when the calibration has begun and finished
digitalWrite(13, HIGH);
// we calibrate the light sensor here
while (millis() < 5000) {
lightValue = analogRead(lightPin);

if (lightValue < lightMax) {
lightMax = lightValue;
}

if (lightValue > lightMin) {
lightMin = lightValue;
}
}

digitalWrite(13, LOW);
}

void loop() {
// we check if the button has been pressed here
butVal = digitalRead(butPin);

if (butVal == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;

time = millis();
}

// we jump to void blinkLight() here
blinkLight();
}

void blinkLight() {
// we read the light sensor here
lightValue = analogRead(lightPin);
lightValue = map(lightValue, lightMin, lightMax, 0, 255);
lightValue = constrain(lightValue, 0, 255);
// print the serial information for debugging
Serial.println(lightValue);

// this if statement runs while lightValue greater then 90 and butVal does not equal HIGH. If the light value < 90 or butVal does equal HIGH,
// we jump to void blink()
if (lightValue > 90 && butVal != HIGH) {
potVal = analogRead(potPin);
analogWrite(redLedPin, lightValue);
delay(potVal);
potVal = analogRead(potPin);
digitalWrite(redLedPin, LOW);
delay(potVal);
potVal = analogRead(potPin);
analogWrite(greenLedPin, lightValue);
delay(potVal);
potVal = analogRead(potPin);
digitalWrite(greenLedPin, LOW);
delay(potVal);
potVal = analogRead(potPin);
analogWrite(blueLedPin, lightValue);
delay(potVal);
potVal = analogRead(potPin);
digitalWrite(blueLedPin, LOW);
delay(potVal);
}
// the else statement is used if the requirements for the if loop are false
else {
blink();
}
}

void blink() {
// we read the potentiometers value here
potVal = analogRead(potPin);
// we do the blinks here by first checking the state to see if it is HIGH or LOW, if it is HIGH, the LEDs will turn on and blink,
// if the state is LOW, they remain off. We also delay by the amount of the potentiometer, this is what is used to control the how fast
// the LEDs blink
digitalWrite(redLedPin, state);
delay(potVal);
digitalWrite(redLedPin, LOW);
delay(potVal);
potVal = analogRead(potPin);
digitalWrite(greenLedPin, state);
delay(potVal);
digitalWrite(greenLedPin, LOW);
delay(potVal);
potVal = analogRead(potPin);
digitalWrite(blueLedPin, state);
delay(potVal);
digitalWrite(blueLedPin, LOW);
delay(potVal);
}

This isn't a Processing question.
You can edit the title if you wish.

Hi,

I have changed the title. I still need help though. Can someone edit my code so that I can control the brightness of my 3 LED's using processing, and explain to me how it works? Also, can someone help simplify my code, and explain how to do this as well? Sorry for the novice questions, but I am really new to this.

Can someone edit my code so that I can control the brightness of my 3 LED's using processing, and explain to me how it works?

You need to download the Processing application. Have you done that?

Then, you need to define how the Processing application is supposed to know what brightness level you want the LED to have. Have you got a clue how it should know that?

Finally, you need to use the Serial class to send data to the Arduino. Then, you have to program the Arduino to read data from the serial port, convert that data to ints, and then call analogWrite() when the data has been received.

Also, can someone help simplify my code, and explain how to do this as well?

Not until you define the requirements for the program

Yes, I have downloaded the Processing application. I used the Processing code from the Dimer tutorial from the Arduino website, as it does what I want it to. I have done the Dimer tutorial, and that tutorial works as expected. When I try to use what the tutorial taught in my program, it does not work. I want my program to work as it does now, but I want to be able to control the brightness of the 3 LED's using my computer.

So, I want the LED's to automatically come on when the Arduino is in a dark room, i then want the LED's to blink at the rate set by a potentiometer, but I also want to be able to control the brightness of the LED's using my computer. Then, when the Arduino is back in a bright room, I want the LED's to shut off. I also want to be able to use the button to force the LED's on even when the Arduino is in a bright room, blink at the rate set by the potentiometer, and also be able to control the brightness of the 3 LED's using my computer. The button must act as a toggle button, as I don't want to have to hold the button to keep the LED's on.

Here is the Processing code from the Dimer tutorial:

import processing.serial.*;
Serial port;

void setup ()  {
  size(256, 150);
  
  println("Available serial ports:");
  println(Serial.list());
  
  port = new Serial(this, "COM6", 9600);
}

void draw()  {
  for (int i = 0; i <256; i++)  {
    stroke(i);
    line(i, 0, i, 150);
  }
  
  port.write(mouseX);
}

Hi,

I have gotten the program semi working with this code:

/* This program uses a potentiometer, a light sensor, and a button to control the blinking of 3 LEDS
 */

// constants won't change
const int butPin = 2;   // pin the button is on
const int potPin = A0;  // pin the potentiometer is on
const int lightPin= A1;  // pin the light sensor is on 
const int redLedPin = 11;  // pin the red LED is on
const int greenLedPin = 10;  // pin the green LED is on
const int blueLedPin = 9;  // pin the blue LED is on

// variables will change
int potVal;  // the potentiometers value 
int butVal;  // the buttons value
int state = HIGH;  // state to put the LEDs in
int previous = LOW;  // previous state of the button
int lightValue = 0;  // the value of the light sensor
int lightMin = 1023;  // the minimum light sensor value
int lightMax = 0;  // the maximum light sensor value
int brightVal;

long time = 0;
long debounce = 200;  // the debounce timer

void  setup()  {
  // we set the pin modes here, they should be self explanitory
  pinMode(13, OUTPUT);
  pinMode(butPin, INPUT);
  pinMode(potPin, INPUT);
  pinMode(lightPin, INPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(blueLedPin, OUTPUT);
  // we use an attachInterrupt here to interrupt the prgram and jump back to loop when the button is pressed
  attachInterrupt(0, loop, RISING);
  // serial for debugging
  Serial.begin(9600);
  // These lights tell uss when the calibration has begun and finished
  digitalWrite(13, HIGH);
  // we calibrate the light sensor here
  while (millis() < 5000)  {
    lightValue = analogRead(lightPin);

    if (lightValue < lightMax)  {
      lightMax = lightValue;
    }

    if (lightValue > lightMin)  {
      lightMin = lightValue;
    }
  }  

  digitalWrite(13, LOW);
}

void loop()  {
  // we check if the button has been pressed here
  butVal = digitalRead(butPin);

  if (butVal == HIGH && previous == LOW && millis() - time > debounce)  {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();
  }

  // we jump to void blinkLight() here
  blinkLight();
}


void blinkLight()  {
  // we read the light sensor here
  lightValue = analogRead(lightPin);
  lightValue = map(lightValue, lightMin, lightMax, 0, 255);
  lightValue = constrain(lightValue, 0, 255);
  // print the serial information for debugging
  // Serial.println(lightValue);

  // this if statement runs while lightValue greater then 90 and butVal does not equal HIGH. If the light value < 90 or butVal does 
  // equal HIGH,
  // we jump to void blink()
  if (lightValue > 90 && butVal != HIGH)  {
    if (Serial.available())
    potVal = analogRead(potPin);
    brightVal = Serial.read();
    analogWrite(redLedPin, brightVal);
    delay(potVal);
    potVal = analogRead(potPin);
    digitalWrite(redLedPin, LOW);
    delay(potVal);
    potVal = analogRead(potPin);
    brightVal = Serial.read();
    analogWrite(greenLedPin, brightVal);
    delay(potVal);
    potVal = analogRead(potPin);
    digitalWrite(greenLedPin, LOW);
    delay(potVal);
    potVal = analogRead(potPin);
    brightVal = Serial.read();
    analogWrite(blueLedPin, brightVal);
    delay(potVal);
    potVal = analogRead(potPin);
    digitalWrite(blueLedPin, LOW);
    delay(potVal);
  }
  // the else statement is used if the requirements for the if loop are false
  else {
    blink();
  }
}

void blink()  {
  if (state == LOW)  {
    if (Serial.available())
      byte brightVal;
    // we read the potentiometers value here
    potVal = analogRead(potPin);
    brightVal = Serial.read();
    // we do the blinks here by first checking the state to see if it is HIGH or LOW, if it is HIGH, the LEDs will turn on and blink,
    // if the state is LOW, they remain off. We also delay by the amount of the potentiometer, this is what is used to control how fast
    // the LEDs blink
    analogWrite(redLedPin, brightVal);
    delay(potVal);
    digitalWrite(redLedPin, LOW);
    delay(potVal);
    potVal = analogRead(potPin);
    brightVal = Serial.read();
    analogWrite(greenLedPin, brightVal);
    delay(potVal);
    digitalWrite(greenLedPin, LOW);
    delay(potVal);
    potVal = analogRead(potPin);
    brightVal = Serial.read();
    analogWrite(blueLedPin, brightVal);
    delay(potVal);
    digitalWrite(blueLedPin, LOW);
    delay(potVal);
  }
}

The problem is for some reason there is a huge delay when I try to change the brightness of the LED's. I have pin pointed the issue to the delay arguments I used to control the blink delay using the pot. Is there another way of controlling the speed of the blinking using the potentiometer without using the delay argument? I read the Blink without delay tutorial, but don't know how to use that code for a potentiometer controlling the delay speed.

For some reason there is a huge delay

Could that be due to the large number of large delays?
There is an example/tutorial called blink without delay.
Read it, without delay

Hi,

I have read the blink w/o delay tutorial, but I am confused about how to convert my delay(potVal); arguments into what the tutorial taught.

You just use the potVal as your interval variable.
Spending time playing with and understanding blink without delay is one of the best learning investments you can make.

That worked for using the potentiometer with it, but now I am stuck on how to use the brightness control with it, instead of the LED just being HIGH or LOW. How do I take something like this and convert it to what the blink w/o delay tutorial taught?

const int ledPin = 9;      // the pin that the LED is attached to

void setup()
{
  // initialize the serial communication:
  Serial.begin(9600);
  // initialize the ledPin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  byte brightness;

  // check if data has been sent from the computer:
  if (Serial.available()) {
    // read the most recent byte (which will be from 0 to 255):
    brightness = Serial.read();
    // set the brightness of the LED:
    analogWrite(ledPin, brightness);
  }
}

Hi,

I have just tried testing the processing brightness control with the Blink w/o delay tutorial sketch, but I am having still having the same huge delay issue. It takes at least 5 - 10 seconds to update the brightness of the LED's, even though I set the interval using the potentiometer to a few milliseconds. How can I get the brightness control to work without the huge delay?

Here is the Arduino sketch.

// constants won't change. Used here to
// set pin numbers:
const int redLedPin =  11;      // the number of the LED pin
const int greenLedPin =  10;
const int blueLedPin =  9;
const int potPin =  A0;
const int buttonPin =  2;

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
int buttonState = 0;
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(blueLedPin, OUTPUT);
  pinMode(potPin, INPUT);
  pinMode(buttonPin, INPUT);  
  Serial.begin(9600);
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();
  interval = analogRead(potPin);
  
  byte brightness;

  if(Serial.available() && currentMillis - previousMillis > interval)  {
    // save the last time you blinked the LED
    previousMillis = currentMillis; 
    // this is where we read the brightness from Serial
    brightness = Serial.read(); 
    // if the LED is off turn it on and vice-versa:
    if (buttonState == HIGH && ledState == LOW)
      ledState = brightness;
    else
      ledState = LOW;
    // set the LED with the ledState of the variable:
    analogWrite(redLedPin, ledState);
    analogWrite(greenLedPin, ledState);
    analogWrite(blueLedPin, ledState);
  }
}

Here is the processing sketch.

import processing.serial.*;
Serial port;

void setup ()  {
  size(256, 150);
  
  println("Available serial ports:");
  println(Serial.list());
  
  port = new Serial(this, "COM6", 9600);
}

void draw()  {
  for (int i = 0; i <256; i++)  {
    stroke(i);
    line(i, 0, i, 150);
  }
  
  port.write(mouseX);
}

You need to read characters as soon as they become available, not after your delay interval.

AWOL:
You need to read characters as soon as they become available, not after your delay interval.

What do you mean by this? Do you mean putting it before the if statement?

The availability of a character has nothing at all to do with the display cycle, so yes, it should be completely separate.

AWOL:
The availability of a character has nothing at all to do with the display cycle, so yes, it should be completely separate.

So I would do

if(Serial.available())  {
brightness = Serial.read()
}

Before the other if statement?

Why are you delaying at all? If the Processing app says "Make the LED brighter now" it does not mean "Make the LED brighter when you get around to it".