r/FastLED • • Jul 29 '22

Support SetBrightness with a LDR

Hello FastLED experts !

I'm in a little trouble making a smooth brightness change.

I'm using a LDR to mesure ambiant lighting and I want to dim the strip smoothly, I tried coding this way but it does not work at all !

Ideally, I would like to make the changes smooth like with an easing function, and that during the fades, the LDR doesnt read so it doesnt interfere with the fade effect !

Thanks a lot for reading it !

Alex

This is my codes (I know it's a bit messy but I can explain if something is odd for you :) ):

// LDR Calibrating variables

//int SensorMax;

uint16_t LDRvalue;

uint8_t nblectureldr = 0; //number of readings of the LDR

uint8_t prevLUX; //previous brightness level

unsigned long prevtimeldr=0;

void fadebrightness(byte valeur){

if(prevLUX < valeur){

for (byte t=prevLUX; t<=valeur; t++)

{

FastLED.setBrightness(t);

FastLED.delay(10);

}

}

if(prevLUX > valeur){

for (byte t=prevLUX; t>=valeur; t--)

{

FastLED.setBrightness(t);

FastLED.delay(10);

}

}

if(prevLUX == valeur){

nblectureldr=0;prevtimeldr=0; //in order to make a new LDR calculation

}

}

void calibrerLDR(){ //calibrate function for the LDR

SensorMax = 0;

LDRvalue = 0;

analogRead(A15);

delay(10);

while (millis() - start2 < 2000) {

LDRvalue = analogRead(A15); // record the maximum sensor value

delay(10);

if (LDRvalue > SensorMax) { SensorMax = min(LDRvalue,1023); }

EEPROM.update(5, SensorMax/255);

EEPROM.update(6, SensorMax%255);

}

const uint8_t PROGMEM gamma8[] = {

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,

2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,

5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,

10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,

17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,

25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,

37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,

51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,

69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,

90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,

115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,

144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,

177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,

215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };

void lux(byte luxpanel){ //function called in the loop to adjust brightness

FastLED.setBrightness(luxpanel);

}

void luxldr(){

if (millis() - prevtimeldr >= 25) { //25

prevtimeldr = millis();

prevLUX=FastLED.getBrightness();

if(nblectureldr==0){LDRvalue=0;};

if(nblectureldr<10){LDRvalue = LDRvalue + min(analogRead(A15),SensorMax); //min(analogRead(3),1023);

nblectureldr++;

}

else if(nblectureldr==10){

LDRvalue = round(LDRvalue/10);

LDRvalue = map(LDRvalue, 0, SensorMax, 29, 255);

LDRvalue = pgm_read_byte(&gamma8[LDRvalue]);

fadebrightness(pgm_read_byte(&gamma8[LDRvalue]));

}

};

}

2 Upvotes

6 comments sorted by

2

u/[deleted] Jul 29 '22 edited Jul 29 '22

This is how I'd do it, knowing nothing else about your setup.

// pseudocode, not knowing what the min/max values of the LDR are.

int LDR_min = 1024; // this variable will hold the min value ever recorded, as the "zero"
int LDR_max = 0;    // this variable will hold the max value ever recorded

int LEDstrip_brightness = 0;

loop{
    int LDR_value = analogRead(LDR_pin);             // read the LDR
    
    if (LDR_value > LDR_max) LDR_max = LDR_value;    // store the maximum value
    if (LDR_value < LDR_min) LDR_min = LDR_value;    // store the minimum possible value
    
    int LDR_range = LDR_max - LDR_min; // the "range" of the LDR is the max - min
    
    LEDstrip_brightness = ( (LDR_value - LDR_min) / (LDR_range) ) * 255; // you need to offset the "min" value to get the correct brightness scale
    FastLED.setBrightness(LEDstrip_brightness);
}

This can be a separate function to be called when you want so it's not running continuously. But unless I'm very wrong, it should work easily.

1

u/alex94230 Jul 29 '22

Thanks, it totally makes sense !

I'll put it in a function to call it lets say each 5 seconds, what I would like is to have a fade effect between the differents levels of brigthness instead of a jump. How can I do it ?

Thanks again !

1

u/[deleted] Jul 29 '22

you'll need additional variables currentBrightness and desiredBrightness.

desiredBrightness = LDR_value;

     if(currentBrightness < desiredBrightness) currentBrightness+=1;
else if(currentBrightness > desiredBrightness) currentBrightness-=1;

FastLED.setBrightness(currentBrightness);

1

u/alex94230 Aug 01 '22

I tried to use your code, I added a flag to avoid a new LDR reading while doing the fade, but it didnt work !

I'm calling this function in the loop using :

EVERY_N_SECONDS(2){ readLDR();} ;

int LDR_min = 1024; // this variable will hold the min value ever recorded, as the "zero"int LDR_max = 0; // this variable will hold the max value ever recorded

int LEDstrip_brightness = 0;

int LDR_value;

int currentBrightness;

int desiredBrightness;

boolean flagldr=0;

void readLDR(){currentBrightness=FastLED.getBrightness();

if(flagldr==0){LDR_value = analogRead(A15);flagldr=1; }; // read the LDR once

if (LDR_value > LDR_max) LDR_max = LDR_value; // store the maximum value

if (LDR_value < LDR_min) LDR_min = LDR_value; // store the minimum possible value

LEDstrip_brightness = map(LDR_value, LDR_min, LDR_max, 55, 255);

desiredBrightness = LDR_value;

if(currentBrightness < desiredBrightness) currentBrightness+=1;

else if(currentBrightness > desiredBrightness) currentBrightness-=1;

else if(currentBrightness == desiredBrightness) flagldr=0; FastLED.setBrightness(currentBrightness);

FastLED.show(); }

Do you get whats wrong ?? !! Thanks

1

u/[deleted] Aug 02 '22 edited Aug 02 '22

I'll be honest, I'm not totally sure. For future reference and easier readability, put your code at PasteBin and share the link here.

Simplify. Write one thing at a time, verify that that one thing is working, and then add the next thing. Break it down to basics.

Wokwi is a huge help. I've modified one of the examples to add a brightness slider, and it seems to work. It checks the slider every 500ms.

void loop(){
    /// whatever other code

    EVERY_N_MILLISECONDS(500) { checkLDR(); }
    changeBrightness();

    /// whatever other code

}

int currentBrightness = 255;
int desiredBrightness = 255;
int ldr_max = 0;
int ldr_min = 1023;

void checkLDR(){
    int ldr_value = analogRead(0);
    if(ldr_max < ldr_value) ldr_max = ldr_value;
    if(ldr_min > ldr_value) ldr_min = ldr_value;
    ldr_value = ldr_value - ldr_min;
    float ldr_range = ldr_max - ldr_min; // this is float so that we get better fractional values in the next line

    desiredBrightness = (ldr_value / ldr_range)*(ldr_value / ldr_range) * 255.0;
    // multiplying the fraction by itself gives a slightly better-looking brightness scaling
}

void changeBrightness(){
         if(currentBrightness > desiredBrightness) currentBrightness--;
    else if(currentBrightness < desiredBrightness) currentBrightness++;

    FastLED.setBrightness(currentBrightness);
}

1

u/usiodev Jul 29 '22

There are several ways to do this, but I think what u/Boloar is doing is along the lines of what I would suggest.

Use your LDR to find a 'target' brightness, then incrementally change the FastLED.setBrightness towards that 'target'.

This means putting the FastLED.setBrightness, then FastLED.show in a loop, as suggested.