If 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.
Isn’t gpio15 need to be connected to GND for the esp to start the firmware?
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?
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 🙂
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.