ESP8266 Tidy PWM

pwmIf you check out an earlier post I managed to get PWM working nicely on the ESP-12 on the otherwise unused GPIO15. Well, it was a little messy – so I’ve tidied it up with the use of a struct.

Here it is..  You’ll need to make minor mode to the PWM .C page as per my earlier blog.

In your variable setup…

typedef struct {
    uint8_t channel;
    uint16_t frequency;
    uint8_t actual;
    uint8_t bright;
    uint32_t timeout;
    uint8_t minimum;
} PWM;
PWM pwm;

And a 100 step gamma correction table…

static const uint8_t PWMTable[100] = {0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,

4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9,10, 11, 11, 12, 13, 13, 14, 15, 16,

17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 40, 42, 44,

46,48, 51, 53, 56, 59, 62, 64, 68, 71, 74, 78, 81, 85, 89, 93, 97, 102, 107, 111,

116, 122, 127, 133, 139, 145, 151, 157, 164, 171, 178, 186, 194, 202, 210, 218,

226, 234, 244, 250 ,255 };

In your INIT code

pwm.channel = 0;
pwm.frequency=500;
pwm_init(pwm.frequency, &pwm.channel);
pwm_set_duty(pwm.channel, 0);
pwm_start();

In your timer callback (mine is every 20ms)

if (pwm.timeout) {
    if (--pwm.timeout == 0) pwm.bright = pwm.minimum;
}
if (pwm.actual != pwm.bright) {
    if (pwm.bright > 99) pwm.bright = 99;
    if (pwm.actual > pwm.bright) pwm.actual--;
    else if (pwm.actual < pwm.bright) pwm.actual++;
    pwm.channel = PWMTable[pwm.actual];
    pwm_set_duty(pwm.channel, 0);
    pwm_start();
}

And that’s it – just adjust pwm.bright from 0-99 and if you set pwm.timeout the light will fade out after a while –and if you set pwm.minimum when it times out it will time out to that value.

Handy for general LED strip lighting, SAD lighting etc.

Facebooktwittergoogle_pluspinterestlinkedin

4 thoughts on “ESP8266 Tidy PWM

  1. First off, great blog! Been reading for a while now and doing a lot with ESP8266's myself.

    Just a quick add you could consider for this awesome PWM function is a thing called gamma correction. A LED typically won't dim linear between 0 and 100 procent. To compensate for this I often use a gamma correction table. A nice write up of this was done by Adafruit here: https://learn.adafruit.com/led-tricks-gamma-correction/the-longer-fix or this blogpost: https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/

    Hope this helps some people 🙂

    1. Well, it's funny you should mention that because when you looked at the blog item you may have noticed a lookup table reference that I forgot to include but that thanks to your intervention is now in (might want to hit refresh) - yup it's a 100 step gamma correction table.

    1. Well, in our case on our board as well as bringing GPIO15 out - and feeding it to a MOSFET, we also have a 10k resistor from GPIO15 to ground. That seems to work just fine. Thoughts?

Comments are closed.