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 -
JSN-SR04T-V3.0 Coax cable extended
Troubleshooting • 13 days ago • bocalexandru 11 days ago -
Forum Search not working?
Troubleshooting • 4 Oct 2023, 23:33 • Gibber 2 Sept 2024, 20:28 -
Compiling Sensor code using BME280 and ESP8266
Troubleshooting • 26 Feb 2025, 00:32 • dpcons 26 Feb 2025, 06:22 -
NODs stop responding, but ping works.
Troubleshooting • 24 days ago • Marcin 24 days ago -
Getting system time from the controller
Troubleshooting • 27 Feb 2025, 01:39 • dpcons 30 days ago