Increase LED brightness with multiple sensors

I am super rusty / pretty much a noob again.. but I am working on an interactive lighting project and I am trying to gradually increase the brightness of an LED strip with Multiple ultrasonic sensors (6). The idea is that as each distance sensor is triggered (object is closer than = x) it would increase the brightness of the LED by 15%. Then when the next Sensor is triggered, it would add an additional 15% (so now the LED is at 30%). Until all sensors are triggered and max brightness (90%) is achieved.

When a sensor is not triggered the brightness would decrease.

I have one sensor working to gradually increase the brightness of the LED, but I'm not sure how to limit how much each sensor contributes. Like how do I make it only increase 15% even if it is still getting as positive signal and limit the increase to 15%.... It just runs away on me.

and then is an effecient way to scale to 6 sensors!!

Any help would be much appreciated.

here is my code for one sensor.

#define LED 7  // define light
const int trig_pin = 24;
const int echo_pin = 25;
float timing = 0.0;
float distance = 0.0;
int i = 0;  // LED brightness
int x = 0;  // loop limit

void setup() {
  pinMode(echo_pin, INPUT);
  pinMode(trig_pin, OUTPUT);
  pinMode(LED, OUTPUT);

  digitalWrite(trig_pin, LOW);


  Serial.begin(9600);
}

void loop() {
  digitalWrite(trig_pin, LOW);
  delay(2);

  digitalWrite(trig_pin, HIGH);
  delay(10);
  digitalWrite(trig_pin, LOW);

  timing = pulseIn(echo_pin, HIGH);
  distance = (timing * 0.034) / 2;

  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.print("cm | ");
  Serial.print(distance / 2.54);
  Serial.println("in");


  if (distance <= 150) {

    // for (int x =0; x <15; x++){ // trying to limit # of steps
    // delay(20);
    i += 1;
    analogWrite(LED, i);

    delay(20);
  }
  // }

  else if (i > 1) {  // decreasing the brightness  (will be limited like above)
    i -= 1;
    analogWrite(LED, i);
    delay(20);
  }
  Serial.println(i);
  delay(300);
}

I think that part is relatively simple

  if (distance <= 150) {

    if (i < 15)
    {
      i += 1;
      analogWrite(LED, i);

      delay(20);
    }
    ...
    ...

It gets more complicated with multiple sensors. If you're out of reach of one sensor, it will decrement the value. But if you're in reach of another sensor, it will increment. So they will conflict with each other.

Maybe a better description of what needs to happen might be in place.

Note:
For your original code, if the distance is less than 150, you keep on incrementing the variable i. As a result, when it reaches 255 and increments to 256, the analogWrite() will use the value 0 again as that function takes an byte for its second argument; and at 257, it will be 1 etc.

2 Likes

Try this (untested)

#define LED 7  // define light
const byte sensors = 1;
const byte trig_pin[sensors] = {24};
const byte echo_pin[sensors] = {25};
float timing = 0.0;
float distance = 0.0;
int i = 0;  // LED brightness
int x = 0;  // loop limit
unsigned long ledAdjustTime;

void setup() {
  for(byte s=0; s<sensors; s++) {
    pinMode(echo_pin[s], INPUT);
    pinMode(trig_pin[s], OUTPUT);
    digitalWrite(trig_pin[s], LOW);
  }
  pinMode(LED, OUTPUT);

  Serial.begin(115200);
}

void loop() {

  byte targetBrightness = 0;

  for(byte s=0; s<sensors; s++) {
    digitalWrite(trig_pin[s], LOW);
    delay(2);

    digitalWrite(trig_pin[s], HIGH);
    delay(10);
    digitalWrite(trig_pin[s], LOW);

    timing = pulseIn(echo_pin[s], HIGH);
    distance = (timing * 0.034) / 2;

    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.print("cm | ");
    Serial.print(distance / 2.54);
    Serial.println("in");


    if (distance <= 150) {
      targetBrightness += 15;
    }

  }

  unsigned long timeNow = millis();

  //Is it time to adjust led brightness?
  if (timeNow - ledAdjustTime > 300) {

    ledAdjustTime = timeNow;

    if(targetBrightness > i) {
      i++;
    }
    else if(targetBrightness < i) {
      i--;
    }

    analogWrite(LED, i);

    Serial.println(i);

  }
}
1 Like

Hi, @dsmaker_001
Welcome to the forum.

Are all 6 ultrasonic sensors looking at the same area and all you want to do is increase the LED intensity as the object gets closer?

If so then you only need one ultrasonic sensor.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Thanks Sterretje, yes the way each sensor will fight eachother is something I've worried about. But your example gives me the idea to track each sensors' gain individually from the brightness. With a seperate integer/count that is limited to 15, which is then added to the brightness at each cycle. I'm working on it tonight and will post if something clicks!

Hi Paul,

This is very elegant, thank you...

I'm trying to understand it...

ok the first for loop in setup creates each sensor .. right now it says 1 but I'll set that variable to 6..

why the super high baud rate? I am using an arduino mega.?

ok.. void loop.

byte creates target brightness at 0... oh!!!... reset each cycle... right..

Ok, first 'for loop' cycles through each sensor to check the distance,,, AND adds the brightness.. so adds it all up and holds it in the byte...ok ok..
..

ok, now how does the timenow work? ... is it slowly bringing 'i' up to the match target?!!

This is cool.. I'm going to test it now.

Hi TomGeorge,
They are placed 360 around an object.. the intention is to brighten as more people (6) gather around the object, like a fire or idea or dinner table.

and now im researching gamma correction..

This worked flawlessly,

Added my sensors, and pin address and it drives it up and dials it back down!!!


The next step is to make the increases less linear!

It does not create the sensor; it (simply) configures the pins for the sensors.

Yes, and you need to expand the arrays that follow.

It doesn't matter too much. 9600 is just soooooooo outdated. By default I use 115200; if I have to cover long distances over serial I will bring it down as it will become less susceptible to noise from the environment.

Imagine you're boiling an egg in a pot of water. Water is boiling, you put an egg in and look at the clock and remember the time (that is lastAdjustTime). You walk away, do something else and come back, look at the clock and compare the current time with the time that you remembered. If it's time not time yet, you again go and do something else and come back. Till such time that the duration that you wanted to boil the egg for is over and you take the egg out and put the next egg in, remember the time and so on.

It's called non-blocking code. If it's not time yet to update the LED, the program goes back to the beginning of loop() to read the sensors again, checks if it's time etc.

It indeed applies the brightness in small steps (up or down).


The presented program suffers from the problem that I mentioned before; if the targetBrightness is 255 (actually 240 - 15) and is incremented, it will overflow and you will get a low value again. The same if the targetBrightness is below 15, you will get a near full brightness again.

Before incrementing, you will need to check if (for steps of 15) the targetBrightness is 240 or lower; before decrementing, you will need to check if (for steps of 15) is higher than or equal to 15.

What you have shown of your project in your pictures is fine for a prototype. But before it goes into an exhibition it will need soldering up on strip board and removing the solderless bread board otherwise your project will be unstable in the long term.

I also noticed a wire coming from an LED and not being connected to anything. Have you remembered that an LED needs to have a current limiting resistor in series with it to avoided damage to the LED and Arduino?.

It isn't super high, this is 2024, not 1984!

It ensures that the brightness only changes slowly towards the target brightness, by only increasing or decreasing it every 300ms, but without using delay(). Probably could have continued using delay() in this case, but if you had wanted to add more features later, using delay() might have become a problem.

1 Like

Hi, @dsmaker_001

Wil l you r project be inside or outside?

If outside be prepared for false triggering due to wind/breeze.

Tom.. :smiley: :+1: :coffee: :australia:

Haha, thanks yes we will be soldering up a few sheilds for the MEGA board to make assembly easier, (we are makeing 6 of these for the peice)

And thanks for noticing! the little LED was a tester before I had the MOSFET module to drive the strip of lights in the garbage can!

Thanks PaulRB, it all makes sense!

I had no idea the low baud rate was out of style!

We will be expanding it (this is a proof of concept). One stretch goal is to add in a 'celebration' sequence for when 100% brightness is reached, something like a fade up fade down sequence before resetting...

Thanks Sterretje,

We were testing it tonight and it doens't seem to overflow. (it does if we put in too big of a tep like you noted) but when its just climbing with i++ it does fine.

but we felt that the linear brightness was hard to notice so we added a switch sequence and lowered the timeNow to have finer control over what levels are achieved as each sensor is triggered. This also sets a stable target to avoid the overflow.

Here is where our code stands now.

#define LED 7  // define light
const byte sensors = 6;
const byte trig_pin[sensors] = { 24, 26, 28, 38, 40, 42 };
const byte echo_pin[sensors] = { 25, 27, 29, 39, 41, 43 };
float timing = 0.0;
float distance = 0.0;
int i = 0;  // LED brightness
//int x = 0;  // loop limit
unsigned long ledAdjustTime;
//int y;  /// 0 - 255


void setup() {
  for (byte s = 0; s < sensors; s++) {
    pinMode(echo_pin[s], INPUT);
    pinMode(trig_pin[s], OUTPUT);
    digitalWrite(trig_pin[s], LOW);
  }
  pinMode(LED, OUTPUT);

  Serial.begin(115200);
}

void loop() {

  byte SensPos = 0;
  byte targetBrightness = 1;

  for (byte s = 0; s < sensors; s++) {
    digitalWrite(trig_pin[s], LOW);
    delay(2);

    digitalWrite(trig_pin[s], HIGH);
    delay(10);
    digitalWrite(trig_pin[s], LOW);

    timing = pulseIn(echo_pin[s], HIGH);
    distance = (timing * 0.034) / 2;

    // Serial.print("Distance: ");
    // Serial.print(distance);
    // Serial.print("cm | ");
    // Serial.print(distance / 2.54);
    // Serial.println("in");

    if (distance <= 50) {
      SensPos++;
    }
    switch (SensPos) {
      case 0:
        targetBrightness = 1;
        break;
      case 1:
        targetBrightness = 8;
        break;
      case 2:
        targetBrightness = 16;
        break;
      case 3:
        targetBrightness = 32;
        break;
      case 4:
        targetBrightness = 64;
        break;
      case 5:
        targetBrightness = 128;
        break;
      case 6:
        targetBrightness = 255;
        break;
    }
  }




  unsigned long timeNow = millis();

  //Is it time to adjust led brightness?
  if (timeNow - ledAdjustTime > 20) {

    ledAdjustTime = timeNow;

    if (targetBrightness > i) {
      i += 1;
    } else if (targetBrightness < i) {
      i--;
    }



    analogWrite(LED, i);
   // Serial.println(i);
   // Serial.println(SensPos);
    Serial.println(targetBrightness);
  }
}

Here is the code now,

#define LED 7  // define light
const byte sensors = 6;
const byte trig_pin[sensors] = { 24, 26, 28, 38, 40, 42 };
const byte echo_pin[sensors] = { 25, 27, 29, 39, 41, 43 };
const byte targetBrightness[] = { 1, 8, 16, 32, 64, 128, 255 };

float timing = 0.0;
float distance = 0.0;
int i = 0;  // LED brightness
//int x = 0;  // loop limit
unsigned long ledAdjustTime;
//int y;  /// 0 - 255


void setup() {
  for (byte s = 0; s < sensors; s++) {
    pinMode(echo_pin[s], INPUT);
    pinMode(trig_pin[s], OUTPUT);
    digitalWrite(trig_pin[s], LOW);
  }
  pinMode(LED, OUTPUT);

  Serial.begin(115200);
}

void loop() {

  byte SensPos = 0;

  for (byte s = 0; s < sensors; s++) {
    digitalWrite(trig_pin[s], LOW);
    delay(2);

    digitalWrite(trig_pin[s], HIGH);
    delay(10);
    digitalWrite(trig_pin[s], LOW);

    timing = pulseIn(echo_pin[s], HIGH);
    distance = (timing * 0.034) / 2;

    // Serial.print("Distance: ");
    // Serial.print(distance);
    // Serial.print("cm | ");
    // Serial.print(distance / 2.54);
    // Serial.println("in");

    if (distance <= 50) {
      SensPos++;
    }
  }

  unsigned long timeNow = millis();

  //Is it time to adjust led brightness?
  if (timeNow - ledAdjustTime > 20) {

    ledAdjustTime = timeNow;

    if (targetBrightness[SensPos] > i) {
      i += 1;
    } else if (targetBrightness[SensPos] < i) {
      i--;
    }

    analogWrite(LED, i);
   // Serial.println(i);
   // Serial.println(SensPos);
    Serial.println(targetBrightness);
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.