Aircoookie / Espalexa

Alexa voice control for ESP8266/ESP32 (including brightness and color!)
MIT License
544 stars 137 forks source link

"Fading to color" function not working #59

Open mano1979 opened 5 years ago

mano1979 commented 5 years ago

In the former firmware for my ledstrip controller I had a fade-over function to let the color change graduatly instead of instant. I implemented this function in my current sketch, but somehow the color changes instantly whatever I try. All values go through this function before they're written to "analogWrite" and when I disable this fade function, the ledstrip doesn't lit.

I even tried another fade function, hoping it would be something in the code that was misbehaving, but no. Same results. I'm at a loss here. Does anyone know why these functions don't work? I pasted the code of both functions below:

function 1 (original)

void adjustColor() {
  int i;
  int changed = 0;
  do {
    changed = 0;
    for (i = 0; i < 3; i++) {
      if (currentColor[i] != targetColor[i]) {
        int dir = currentColor[i] > targetColor[i] ? -1 : +1;
        currentColor[i] += dir;
        analogWrite(colorPin[i], currentColor[i]);    
        changed = 1;
      }
      delay(1);
    }
  } while(changed != 0);
}

function 2

int r = 0;
int g = 0;
int b = 0;

void adjustColor(int red, int green, int blue) {
  while ( r != red || g != green || b != blue ) {
    if ( r < red ) r += 1;
    if ( r > red ) r -= 1;

    if ( g < green ) g += 1;
    if ( g > green ) g -= 1;

    if ( b < blue ) b += 1;
    if ( b > blue ) b -= 1;

    analogWrite(REDPIN, r);
    analogWrite(GREENPIN, g);
    analogWrite(BLUEPIN, b); 
    delay(100);
  }
}
Aircoookie commented 5 years ago

Hi again! There are two main issues with your function:

  1. using delay() is a horrible idea with the ESP8266, as it blocks execution of the loop and therefore will at best make the firmware unresponsive and at worst crash it.
  2. just adding or subtracting some color will lead to a non-uniform transition.

Implementing the fade properly is a bit more involved. I can try to write you some code later, but keep in mind you are asking for programming help here. This is not an issue with the library. It may bother other library maintainers, although I do not mind helping out once in a while :)

Since you are building an alexa-controlled RGB strip, perhaps you are interested in my lightning project WLED! It offers Alexa color control, but many other features like effects, a nice web UI and more! There is a "hack" to use it with your kind of RGB LEDs (https://github.com/Aircoookie/WLED/issues/58), but if you end up liking it, I'd highly recommend upgrading to WS2812B individually addressable LEDs (they are $3/m shipped from china).

mano1979 commented 5 years ago

I have my entire apartment lit with esp8266 controlled ledstrips, so switching to ws2812b leds probably won't happen in the near future. Also because I have all the controllers already (I designed a entire line of products called WiFiDomo). Since the fade function worked fine on this hardware with the former firmware I wrote, can I assume it is the ESPAlexa library ( and specificly the Alexa server part) that will not work with this fading? Since I never had any issues with delay() or crashing programs?

I had a look at your WLED project. But is that programmable through the Arduino IDE? or do I need to switch to platformio?

eos1d3 commented 5 years ago

ESP8266 can never have long delay in loop(). My experince is that any long delay will cause exception and reset. It is nothing related to this library. That is why there is a need to call yield() if long delay is required in order to let TCP/IP stack work.

For ESP32 I just do not know if it is the same. Can anyone update this?

PlateformIO and Arduino are actually using the similar framework. I do not think they are different.

mano1979 commented 5 years ago

ok thank you.

I will look into it.

mano1979 commented 5 years ago

I got the fade function working.

Somehow, when I put that code for fading in a separate function like: void fadecolor(){ etc. and call that function from within the loop(), It will not accept any delay() and just does everything at once (or so it seems without delay).

I now have copied the code of that function into the main loop() and that works perfectly fine, even with a delay().

mano1979 commented 5 years ago

One more question:

I need to perform a color correction because the colors from Alexa (or the Alexa app) do not match up to the reality on my specific ledstrip. I need to tone down the green and blue.

While searching through the code I found some options for this in Espalexa/src/EspalexaDevice.cpp like the gamma-correction, but I have no clue on what to change exactly.

Can you tell me what values I need to change?