Flickering problem with RGB leds and a simple solution
-
I've noticed with some of the RGB nodes around the house an annoying flickering problem. It occurs when none of the R G B channels is driven at full brightness. This is especially disturbing when a lower light level is desired.
Tried to find out a reason for this. It was not related to the Arduino used, whether it being a Nano, Uno, official or not. Also not related to using gw.wait or delay in the main loop. Or adding resistors to the fet data pins.
Turns out it is related to the Arduino PWM not being very optimal. Tried to solve the problem by using a different approach, softPWM [e.g. https://github.com/Palatis/arduino-softpwm] but they conflicted with servo library (that uses various timers also, as soft pwms do).
Jeelabs brought a solution; tweaking the frequency of some timers. Just tested it, and seems that the flickering is totally gone AND still the servos AND the MySensor communication works. Very happy with the result.
This is the blog post describing the issue, the solution I used is in the comments http://jeelabs.org/wp-content/uploads/2011/11/8/fixing-the-arduinos-pwm/index.html.
So, flickering fixed by adding TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20) to the setup. Will need to update a few nodes now!
-
I can confirm this fixing the flickering problem. The only problem it introduces - some high pitch whine from arduino.
-
Some background, why the solution works without changing the timer prescale:
The default prescale of all timers are 64, so they should work the same, but the default mode is different:
Timer 0: Fast PWM mode = 0..255,0..255,... (timer is used for internal calculations millis() / delay() /..., so this setting is required)
Timer 2: Phase-correct mode = 0..255..0..255...
Timer 1 is 16 bit and the pins are blocked by the radio, so I'll leave them out here.
The frequency of the timer is comparable to a timer round trip (values are calculated with a 16 MHz IO-frequency like with ATmega168 or ATmega328 used in nano):
Timer 0: 16 MHz / 64 / 256 = 976.5625 Hz
Timer 2: 16 MHz / 64 / 510 = 490.1961 Hz
Fast PWM uses 0..255 = 256 for a round trip.
Phase-corrected mode uses 0..255,254..1 = 256 + 254 = 510 (all numbers are double except 0 and 255!)NOW the command:
TCCR2A |= _BV(WGM21);
Switches timer 2 to fast PWM mode (mode from 1 to 3).In addition to the links above, here I found the default settings: http://playground.arduino.cc/Main/TimerPWMCheatsheet
Suggested Topics
-
Day 1 - Status report
Announcements • 23 Mar 2014, 22:45 • hek 24 Mar 2014, 20:12 -
Compiling Sensor code using BME280 and ESP8266
Troubleshooting • 26 Feb 2025, 00:32 • dpcons 26 Feb 2025, 06:22 -
Can not compile MySensors on esp8266
Troubleshooting • 24 Aug 2024, 15:35 • TheoL 29 Aug 2024, 20:47 -
NODs stop responding, but ping works.
Troubleshooting • 20 days ago • Marcin 20 days ago -
Ghost Child
Troubleshooting • 13 days ago • FcNanoLed 10 days ago -
Forum Search not working?
Troubleshooting • 4 Oct 2023, 23:33 • Gibber 2 Sept 2024, 20:28