StefanBruens / ESP8266_new_pwm

This is a drop-in replacement for the ESP8266 SDK PWM
GNU General Public License v2.0
196 stars 46 forks source link

Drop-out when multi-channel reach full-duty cycle. #32

Open devarishi7 opened 3 years ago

devarishi7 commented 3 years ago

For of all, one can not praise people, that put their code online and provide support, enough, so " Thank you so much !" I wouldn't be writing if i would not be experiencing an issue, and i fact i had not even noticed the issue my self. The application is using an ESP-01 (a 8685 to be exact) as a controller for 5050 RGB ledstrip, using mosfets to drive them. Since nearly all available pins need to be pulled 'HIGH' at boot, and that would cause the strip to be 'fully-on' i added a 7402, and used pin 3 to block the signal initially. This means that as a result the signal is inverted. 100 duty cycle is 'OFF' and 0% duty cycle is 'ON' Now what happens is that when 2 of my 3 channels (or all of them) reach 100%, from a lesser duty cycle, a drop out occurs, which in this case causes a short flash. The solution i found so far is to reduce the PWM PEROD to 1024 (from 5000) and it appears to have resolved the issue (I can't see it anymore, but more testing is required) but i am also curious as to what could be the cause. This is my SetColor() function, which is called repeatedly from loop()

void SetColor(uint32_t color32) {
  uint8_t i = 3;
  while (i) {
    i--;
    float gamma = color32 & 0xFF;
    float bright = BrightnessFade();
    gamma = gamma * bright;
    if (gamma > 255) gamma = 255 ;

    uint16_t gamma16 = Cosine(gamma);
    if (!INVERT) gamma16 = PWM_PERIOD - gamma16;
    pwm_set_duty(gamma16, i);    
    color32 = color32 >> 8;
  }
  pwm_start();
}

uint16_t Cosine(float gamma) {
  float cosval = cos (( gamma * PI  ) / 510.0) * PWM_PERIOD;
  int cosine = (int) cosval; 
  if (cosine < 0) cosine = 0;
  if (cosine > PWM_PERIOD) cosine = PWM_PERIOD;
  return (uint16_t) cosine;
}

BrightnessFade() can be considered to return 1.0 . As you can see i've been making trying to make sure that Cosine() doesn't return a value outside of it's range, but that is probably not at all required. I don't have anything else that is interrupt based running except for wifi connections (both AP & STA) and i required i can try and connect an oscilloscope though mine isn't very good.