Control RGB LED Strip with sharp distance sensor

This is a function you can add to your code to fade from the current colour to the one passed to it.
It is not tested so may contain errors but it illustrates how to fade colours.

// set up these global variables before the setup()
int currentRed = 0, currentGreen = 0, currentBlue = 0;

void fadeTo(int R, int G, int B, int fadeSteps) {  // fade from the current colour to the one passed to the function
  float deltaR, deltaG, deltaB;
  float tempR, tempG, tempB;
// set up the temp values to the current LED state
  tempR = currentRed;
  tempG = currentGreen;
  tempB = currentBlue;

// calculate the distance between each colour as it is now, and the target colour
  deltaR = ( float(R - currentRed)) / fadeSteps;
  deltaG = ( float(G - currentGreen)) / fadeSteps;
  deltaB = ( float(B - currentBlue)) / fadeSteps;

  // fade to new colour
  for (int i = 0; i < fadeSteps; i++) { 
 // calculate new intermediate colour
   tempR += deltaR;
   tempG += deltaG;
   tempB += deltaB;

  // set these LEDs to the new intermediate colour
    analogWrite(REDPIN, int(tempR));
    analogWrite(GREENPIN, int(tempG));
    analogWrite(BLUEPIN, int(tempB));

    delay(FADESPEED);
  } // end of for loop

// keep the global colour up to date
  currentRed = tempR;
  currentGreen = tempG;
  currentBlue = tempB;

}

Okay, I'll give it a try, so this should all still work with my distances??

so this should all still work with my distances??

No it's a function to add to your sketch to allow you to fade from one colour to another. How you incorporate that into distance is up to you.

If you just use that code without trying to understand what it is doing you will not learn anything, which is the object of the exercise.

hmmmm, okay, i see where you coming from, its for a school project with a dead line hence asking for codes etc as i don't have time to fully write them. although as we go i am starting to work out and understand a bit more.

do you know of a way i can incorporate the colour change into my distances, or am i better of with just going to a colour wheel and finding the number values for each colour i wan't and go that way??

do you know of a way i can incorporate the colour change into my distances

Yes call the function I gave you when you want to fade between two colours!!!!

its for a school project

I hope I get good marks.

Oh right, got ya

Ahah, I'll let you know what mark you get :stuck_out_tongue:

Thanks for all your help, greatly appriciated, and apologies if my newbie incopotance has frustrated you at all.

Any other issues I'll be sure to ask :slight_smile:

Okay, its been a while and that all works great,

Except, now i need some more help.

The 'H' and sensor work together perfectly, and now i need to add extra LED's into the equation. So around the outside of the pad is a warning border with 8 yellow LED's, and on each of the corners will be a green and red led.

I need it so that when it is greater than 80 that the yellow LED's are off, and that the whole time the red and green LED's blink opposite each other.

I copied the blink code and put it into my code, so as to make the yellows blink, except because of the delay in the blink code changes the delay of my sensor part. i need help in making them both work and if the way i have coded will work out, was going with the idea of putting the Red, Green and Yellow LED's onto separate pins. Oh and the yellow LED's are wired in both series and parallel whilst i will wire the red and green in just series.

Bellow is my full code.

// Complete Helipad Code
#define REDPIN 5                   // Defines the pin attached to colour
#define GREENPIN 6
#define BLUEPIN 3

// IR Sensor
int IRpin = 1;                      // analog pin for reading the IR sensor
void setup() {
  Serial.begin(9600);               // start the serial port
  // RGB Strip
  pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  // Yellow LEDs
  pinMode(13, OUTPUT);
}

void loop() {
 // IR Sensor
  float volts = analogRead(IRpin)*0.0048828125;   // Value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
  float distance = 27*pow(volts, -1.10);          // Worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk
  Serial.println(distance);                       // Print the distance
  delay(100);                                     // Arbitary wait ti0me.
// RGB Strip Colours
if (distance > 80 ) {                             // Dependeing on reading from sensor, change colour of strip.
    analogWrite(REDPIN, 255);                     // Starting on White
    analogWrite(GREENPIN, 255);
    analogWrite(BLUEPIN, 255);
  }
 if (distance <= 80 && distance > 75) {
    analogWrite(REDPIN, 0);
    analogWrite(GREENPIN, 255);
    analogWrite(BLUEPIN, 100);
  }
 if (distance <= 75 && distance > 70 ) {
    analogWrite(REDPIN, 255);
    analogWrite(GREENPIN, 0);
    analogWrite(BLUEPIN, 128);
  }
  if (distance <= 70 && distance > 65 ) {
    analogWrite(REDPIN, 255);
    analogWrite(GREENPIN, 0);
    analogWrite(BLUEPIN, 255);
  }
  if (distance <= 65 && distance > 60 ) {
    analogWrite(REDPIN, 128);
    analogWrite(GREENPIN, 0);
    analogWrite(BLUEPIN, 255);
  }
  if (distance <= 60 && distance > 55 ) {
    analogWrite(REDPIN, 0);
    analogWrite(GREENPIN, 0);
    analogWrite(BLUEPIN, 255);
  }
  if (distance <= 55 && distance > 50 ) {
    analogWrite(REDPIN, 0);
    analogWrite(GREENPIN, 128);
    analogWrite(BLUEPIN, 255);
  }
  if (distance <= 50 && distance > 45 ) {
    analogWrite(REDPIN, 0);
    analogWrite(GREENPIN, 255);
    analogWrite(BLUEPIN, 255);
  }
  if (distance <= 45 && distance > 40 ) {
    analogWrite(REDPIN, 0);
    analogWrite(GREENPIN, 255);
    analogWrite(BLUEPIN, 128);
  }
  if (distance <= 40 && distance > 35 ) {
    analogWrite(REDPIN, 0);
    analogWrite(GREENPIN, 255);
    analogWrite(BLUEPIN, 0);
  }
  if (distance <= 35 && distance > 30 ) {
    analogWrite(REDPIN, 128);
    analogWrite(GREENPIN, 255);
    analogWrite(BLUEPIN, 0);
  }
  if (distance <= 30 && distance > 25 ) {
    analogWrite(REDPIN, 255);
    analogWrite(GREENPIN, 255);
    analogWrite(BLUEPIN, 0);
  }
  if (distance <= 25 && distance > 20 ) {
    analogWrite(REDPIN, 255);
    analogWrite(GREENPIN, 128);
    analogWrite(BLUEPIN, 0);
  }
  if (distance <= 20) {                        // Ending on Red
    analogWrite(REDPIN, 255);
    analogWrite(GREENPIN, 0);
    analogWrite(BLUEPIN, 0);
  }
  // Yellow LEDs (Controls the warning border LEDs)
  if (distance <= 80) {
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);              // wait for a second
  }
}

n the blink code changes the delay of my sensor part.

The answer it not to use delay() as it effectively stops the processor from doing anything else.
The trick is to use the millis() timer to see when to do the next action of the blinking.
In the examples menu look at the blink without delay sketch, that shows the basic technique to use.

Awesome thanks again Mike, ill check that out and see how i go :slight_smile:

okay, next problem, do you know of a way i can have my green and red leds always flashing no matter distance, but at different intervals eg. red flash green flash etc etc

Again take the blink without delay example but this time use the distance sensor to change the time to the next blink instead of making it a fixed time. So when it is time to change the state of the LED (either on or off) you do the change then set the time for the next change. In the blink without delay this is a constant, you want to make it a function of you sensor. You can use a series of if statements if you want. Gather them into a function that returns a value for the next time timer.

okay, not sure i fully understand what you mean, and also cant see how by doing that i can alternate which led comes on, i want them to alternate at a fixed value (preferably time) like that would on a real helipad or even plane wing?

Again, a little bit of code helps to understand...

I am not sure what you want to do first you say:-

have my green and red leds always flashing no matter distance, but at different intervals eg. red flash green flash etc

This will flash the two LEDs at different rates

/* Blink without Delay
 
 Turns on and off two light emitting diodes(LEDs) connected to a digital  
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.
 
 The circuit:
 * Red LED attached from pin 11 to a resistor, with the other end of the resistor to ground.
 * Green LED attached from pin 12 to a resistor, with the other end of the resistor to ground. 
 
 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 
 modified by Mike Cook to show two blinking lights
 
 This example code is in the public domain.

 
 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

// constants won't change. Used here to 
// set pin numbers:
const int ledPinRed =  11;      // the number of the LED red pin
const int ledPinGreen =  12;      // the number of the LED green pin

// Variables will change:
int ledStateRed = LOW;             // ledState used to set the LED
int ledStateGreen = LOW;             // ledState used to set the LED
long previousMillisRed = 0;        // will store last time LED was updated
long previousMillisGreen = 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 intervalRed = 1000;           // interval at which to blink red (milliseconds)
long intervalGreen = 500;           // interval at which to blink green (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPinRed, OUTPUT); 
  pinMode(ledPinGreen, OUTPUT);   
}

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();
 
  if(currentMillis - previousMillisRed > intervalRed) {
    // save the last time you blinked the LED 
    previousMillisRed = currentMillis; 
      // to change the flash rate change intervalRed here  

    // if the LED is off turn it on and vice-versa:
    if (ledStateRed == LOW)
      ledStateRed = HIGH;
    else
      ledStateRed = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPinRed, ledStateRed);
  }
  
  if(currentMillis - previousMillisGreen > intervalGreen) {
    // save the last time you blinked the LED 
    previousMillisGreen = currentMillis;   
    // to change the flash rate change intervalGreen here

    // if the LED is off turn it on and vice-versa:
    if (ledStateGreen == LOW)
      ledStateGreen = HIGH;
    else
      ledStateGreen = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPinRed, ledStateRed);
  }
}

But do you want to alternate then, that is red on, red off green on green off and so on?

/* Blink without Delay
 
 Turns on and off a light emitting diode(LED) connected to a digital  
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.
 
 The circuit:
 * Red LED attached from pin 11 to a resistor, with the other end of the resistor to ground.
 * Green LED attached from pin 12 to a resistor, with the other end of the resistor to ground. 
 
 
 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 
  modified to alternate LEDs
  
 This example code is in the public domain.

 
 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

// constants won't change. Used here to 
// set pin numbers:
const int ledPinRed =  11;      // the number of the LED red pin
const int ledPinGreen =  12;      // the number of the LED green pin


// Variables will change:
int ledState = 0;             // ledState used to control the LED
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 = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPinRed, OUTPUT); 
  pinMode(ledPinGreen, OUTPUT);   
}

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();
 
  if(currentMillis - previousMillis > interval) { // change LED
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   
     ledState++; // increment the led state variable
     if(ledState >= 4) ledState=0; // wrap round the state variable
    // set the LED to the new state
    switch(ledState) {
    case 0:
            digitalWrite(ledPinRed, HIGH);  // turn on red
            // if you want to control how long it is on for change the interval variable here
            break;
    case 1:
            digitalWrite(ledPinRed, LOW);  // turn off red
            // if you want to control how long it is off for change the interval variable here
            break;
    case 2:
            digitalWrite(ledPinGreen, HIGH);  // turn on green
            // if you want to control how long it is on for change the interval variable here
            break;
    case 3:
            digitalWrite(ledPinGreen, LOW);  // turn off green
            // if you want to control how long it is off for change the interval variable here
            break;
   
      }   // end of switch
  } // end of change LED
}  // end of loop

okay sorry if i wasn't clear, i want them to both flash at the same rate, but alternate times, like the second one Red flash on/off then green flash on/off repeat etc.

ill give the second code a try thanks.

Also, a bit of wiring help here if you can do so. I have to groups of 4 LEDs wired in series, which the the two groups wired in parallel. in order to get them to work, do i have the positive end into say pin 13 and the negative into gnd?? and i am also guessing im gonna need transistor and such as the arduino wont be able to put out enough??

i can try and upload a picture if needed just ask.

oh and also, i am going on a school camp till the weekend so wont be checking till then, hence a late reply.

Thanks again Mike :slight_smile:

You need a certain amount of voltage to turn an LED on so if you wire 4 in series you have not got enough voltage to light them up with the 5V you get out of an arduino pin. You need a higher voltage and so a transistor to drive the higher voltage. With LEDs in series you need only one resistor but if you then wire two of these groups in parallel you will need one resistor for each of the series groups you wire in parallel.

Okay, but it still say go out of pin 13 to a breadboard(which I'm using) then ATM I have 1 220ohm resistor and tranasistor, you say I need to use two how just put int next to the other one??

And do I plug the positive or negative end into pin 13 and then where do I put the opposite one, gnd??

Use this arrangement:-

Replace the +ve of the battery with the arduino output pin and the -ve of the battery with ground. Note like this diagram you will only be able to power two LEDs in series. Do not exceed the 40mA current limit for a pin.

So are you saying that how ive wired them two lots of 4 LEDs in series won't work??

So are you saying that how ive wired them

It is my guess but a diagram from you would rearly help. From an arduino you do not have enough voltage for four LEDs in series.