ph1p / ikea-led-obegraensad

ESP32/Arduino hack for the ikea OBEGRÄNSAD led wall lamp
MIT License
610 stars 85 forks source link

Support of ambient light sensor #74

Open kohlsalem opened 11 months ago

kohlsalem commented 11 months ago

Not my idea, but mentioned in the german CT make and on the homepage of the author (http://blog.digital-image.de/2023/05/31/x-clock/):

With a cheap LDR it would be possible to measure the actual ambient light - and adjust the LED brightness.

I believe this is reasonably simple (for people who dare to solder on a 100€device), cheap, and far superior to any time base adjustment.

It could be an option to be compiled into the firmware.

Best Michael

kohlsalem commented 11 months ago

i hacked this at the end of my main, works great

// Define a tuple structure to hold sensor values and corresponding brightness levels
  typedef struct {
  int sensorValue;
  int brightnessLevel;
  } SensorBrightnessTuple;

  // Define the vector of tuples
  std::vector<SensorBrightnessTuple> sensorBrightnessValues = {
    {    0, 3},
    {1000, 100},
    {4095, 255}
    // Add more tuples as needed

  };
  const int analogInputPin = 34;  // GPIO15 / ADC13
  static unsigned long previousMillis;

  unsigned long currentMillis = millis();

  // Führe den Code nur alle 5 Sekunden aus
  if (currentMillis - previousMillis >= 1000) {//every Second
    previousMillis = currentMillis;
    int sensorValue = analogRead(analogInputPin);
    uint8_t newbrightness;  
    // Check if the sensor value is within the given range
    if (sensorValue <= sensorBrightnessValues.front().sensorValue) {
      newbrightness = sensorBrightnessValues.front().brightnessLevel;
    } else if (sensorValue >= sensorBrightnessValues.back().sensorValue) {
      newbrightness = sensorBrightnessValues.back().brightnessLevel;
    } else {
      // Perform linear interpolation for intermediate values
      for (size_t i = 0; i < sensorBrightnessValues.size() - 1; ++i) {
        if (sensorValue >= sensorBrightnessValues[i].sensorValue && sensorValue <= sensorBrightnessValues[i + 1].sensorValue) {
          // Linear interpolation formula
          newbrightness =  map(sensorValue, sensorBrightnessValues[i].sensorValue, sensorBrightnessValues[i + 1].sensorValue,
                          sensorBrightnessValues[i].brightnessLevel, sensorBrightnessValues[i + 1].brightnessLevel);
          break;
        }
      }
    }     
    Screen.setBrightness(newbrightness);
   // Screen.scrollText(std::to_string(sensorValue).append(">").append(std::to_string(newbrightness)));
  }

I made the mistake to develop my text pull request in the main branch, so i have no clue how to address a second feature meanwhile. to develop in main and a feature seams to be a broblem, at least GH allows now new bransch with open PR on feature...

WRedux commented 6 months ago

Hello,

i want to add the LDR-Featue to my OBEGRÄNSAD, but it wont work.

Dont know, wether its a Software or a Hardware-Thing

I wired like some Examples in the Web with a LDR at 3V3, a 10k Resistor to GND and GPIO15. http://www.esp32learning.com/code/esp32-and-ldr-example.php

To fix the Software-Side would you be so kind and post your Code?

Just putting it to the End of main.cpp gives me some Errors while compiling....

Thanx!

kohlsalem commented 6 months ago

It should be just somewhere within the loop…

WRedux commented 6 months ago

OK. Did that. Compiles, but seems to have still no Effect.

Tested with old LDR, changed LDR now:

I use a Type 5537 LDR now. Depends something in the Code of the LDR-Type? Dunno which LDR-Type I was using before (a old one I found) but the Behaviour is different now, not fully dimmed as before, but still shows no Reaction...

Thanx for reading!

kohlsalem commented 6 months ago

Just uncomment

// Screen.scrollText(std::to_string(sensorValue).append(">").append(std::to_string(newbrightness)));

This should show you what the reading was you got from the sensor and to which brightness it translated.

I'm not so much a electronic expert, but from what i got, the LDR and the "normal" resistor will just make a voltage divider.

The analog input measures the current left. So you should be able to see the changes with a multimeter (sensor vs. ground) or as changing sensor values.

My coding above just offeres a "profile" for what reading which brightness shall be set.

WRedux commented 6 months ago

Works for me too, now. Used the wrong Pinning. GPIO15 (as stated the Comments) has also an ADC, but its used by the Wifi. Switched to 34, so its OK now...