SK6812 RGBW LEDs flickering - RMT Driver

TheSub6
Posts: 7
Joined: Thu Mar 15, 2018 1:24 pm

SK6812 RGBW LEDs flickering - RMT Driver

Postby TheSub6 » Mon Mar 19, 2018 1:06 pm

Hi,

using the RMT Driver I am trying to generate a signal for the SK6812 RGBW LEDs. My issue is that the LEDs are flickering in the desired color and almost unnoticeable changing colors, rather than staying at the same value. I started by manually programming the timings. The code is attached. Can anyone give me a hint what am I doing wrong? The Waveform looks rather good, but is shifting in time.

Thanks for any help.

TheSub6

PS: Am I right that the RMT DATA MODE is obsolete?

Code: Select all


/* RMT transmit example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/rmt.h"

static const char *RMT_TX_TAG = "RMT Tx";

#define RMT_TX_CHANNEL RMT_CHANNEL_0
#define RMT_TX_GPIO 18

rmt_item32_t pixels[] = {

	// 8 Bit G
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	//8 Bit R
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	// 8 Bit B
	{{{6, 1, 6, 0}}},
	{{{6, 1, 6, 0}}},
	{{{6, 1, 6, 0}}},
	{{{6, 1, 6, 0}}},
	{{{6, 1, 6, 0}}},
	{{{6, 1, 6, 0}}},
	{{{6, 1, 6, 0}}},
	{{{6, 1, 6, 0}}},
	// 8 Bit W
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},
	{{{3, 1, 9, 0}}},

	{{{0, 0, 800, 0}}},

    // RMT end marker
    {{{ 0, 0, 0, 0 }}}
};


/*
 * Initialize the RMT Tx channel
 */
static void rmt_tx_int()
{
    rmt_config_t config;
    config.rmt_mode = RMT_MODE_TX;
    config.channel = RMT_TX_CHANNEL;
    config.gpio_num = RMT_TX_GPIO;
    config.mem_block_num = 1;
    config.tx_config.loop_en = 0;
    config.tx_config.carrier_en = 1;
    config.tx_config.idle_output_en = 1;
    config.tx_config.idle_level = (rmt_idle_level_t)0;
    config.tx_config.carrier_duty_percent = 50;
    config.tx_config.carrier_freq_hz = 10000;
    config.tx_config.carrier_level = (rmt_carrier_level_t)0;
    // set the maximum clock divider to be able to output
    // RMT pulses in range of about one hundred nanoseconds
    // a divider of 8 will give us 80 MHz / 8 = 10 MHz -> 0.1 us
    config.clk_div = 8;

    ESP_ERROR_CHECK(rmt_config(&config));
    ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
}


void app_main(void *ignore)
{
    ESP_LOGI(RMT_TX_TAG, "Configuring transmitter");
    rmt_tx_int();
    int number_of_items = sizeof(pixels) / sizeof(pixels[0]);

    while (1) {
        ESP_ERROR_CHECK(rmt_write_items(RMT_TX_CHANNEL, pixels, number_of_items, 1));
        ESP_LOGI(RMT_TX_TAG, "Transmission complete");
        //vTaskDelay(6000 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}

Image

User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby Vader_Mester » Tue Mar 20, 2018 10:39 am

Where did you measure the waveform? At the DIN of the LED?

The waveform looks correct (maybe try to increase the high part of bit 1 a bit longer).
The thing I'm not sure if can cause problems, is the high amount of overshoot, like 200-300mV.
I read somewhere (maybe on Adafruit), that these LEDs don not like overvoltages of any kind.

Do you use level shifters, and if yes, which kind?

Do you have a capacitors between the Vdd and Vss pins of the LED? Unstable supply at the LED, can cause flicker. If you have a second scope channel, you should attach it to the VIN pin of the LED, and see what happens when the data is latched in.

Also, if you only set 1 color on the LED, if other components light up, then it is a data transfer problem. If you increase the high part of the 1bit, look for changes. It's actually what the high part matters, however your rampup is a bit slow, so increasing the high part makes sure that parts are detected as 1.
You can also try what happens if you put a a couple of LEDs in a chain, with different colors.

Where did you measure the waveform? At the DIN of the LED?
If I receive my new level shifters I can see how the code works (dunno when it arrives, but I have 20LEDs available... waiting stuff arrive from china is veeeery irritating).

Vader[BEN]

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

TheSub6
Posts: 7
Joined: Thu Mar 15, 2018 1:24 pm

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby TheSub6 » Wed Mar 21, 2018 1:54 pm

Thanks for your reply.

Waveform is measured at DIN. I altered the timings, without effect (T0H -> 400 ns and T1H -> 700 ns)

The overshoot is a bit high. I increased the inline resistor from 100 Ohm to 1.2 kOhm to get rid of the over voltage. Now I am always at less than 5 Volts. I am using a 74HCT245 levelshifter, which should work like a charm. A also added a 470 uF capacitor parallel to the supply voltage from the 5V out pin of the ESP-Wrover-Kit. And changed from USB Power to external power. But noting changed.

The waveform does not look as clean as on the picture. I made a short movie, to show you what i mean. The LED starts flickering very fast and during runtime slows down. The video is from a later point during runtime, but after a while it will start flickering faster again. To me it seems the signal is shifting, as if the Buffer is not read correctly. Any ideas? And is their still an option to change the memory access mode?

http://nwks.de/VID1.mp4
http://nwks.de/VID2.mp4

TheSub6
Posts: 7
Joined: Thu Mar 15, 2018 1:24 pm

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby TheSub6 » Wed Mar 21, 2018 3:20 pm

I had the carrier enabled :roll: . Now with

Code: Select all

    config.tx_config.carrier_en = 0;
It seems to work stable. BUT...

The colors are not as expected. Every bit seems to be at the right position. But i can't get the white LED to light up standalone. It lights up (not full brightness) when all the blue bits are set high. I fiddled around with the timings, but no effect. With the code below I am tight within the spec. (T0H 306 ns + T0L 906 ns and T1H 600 ns + T1H 586 ns) Does anyone have approved values?

Code: Select all


rmt_item32_t pixels[] = {

   // 8 Bit G
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},

   // 8 Bit R
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},

   // 8 Bit B
   {{{6, 1, 6, 0}}},
   {{{6, 1, 6, 0}}},
   {{{6, 1, 6, 0}}},
   {{{6, 1, 6, 0}}},
   {{{6, 1, 6, 0}}},
   {{{6, 1, 6, 0}}},
   {{{6, 1, 6, 0}}},
   {{{6, 1, 6, 0}}},

   // 8 Bit W
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},
   {{{3, 1, 9, 0}}},

   {{{0, 0, 800, 0}}},

   // RMT end marker
   {{{ 0, 0, 0, 0 }}}
};


User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby Vader_Mester » Thu Mar 22, 2018 1:30 pm

Strange... I wish I could test this right now... unfortunatelly I can't yet, but I'll do it as soon as I can.

By the way is your color order correct? It should be RGBW, yours is a bit different.

Also, try to use a 2nd LEDs, and see if they work in a chain with your setup. See if that works better.

Vader[BEN]

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby fly135 » Thu Mar 22, 2018 6:50 pm

What's your debug logging level? I had issues with neopixel leds not working right when I had RMT logging printing on the terminal.

John A

TheSub6
Posts: 7
Joined: Thu Mar 15, 2018 1:24 pm

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby TheSub6 » Wed Mar 28, 2018 12:27 pm

Now it works. :D It was a defective LED :roll: RGB is working great but the white LED was broken. Now with a new LED everything works...

@Vader_Mester: The color order is GRBW.

But the next issue is the white glow when the blue LED is on. I guess the phosphor in the white LED is UV/blue sensitive and the blue LED spectrum is to close and energizes the phosphor. Maybe it varies from batch to batch, but in my case the blue becomes a bit unsaturated, which is kind of a bummer. I can post my working code if you like.

Do you have any idea how to do 8 parallel RMT Outputs? Does the RMT Driver handle any parallel output? So for example using more than once the rmt_write_items function. Is it useful to do it in tasks?

Code: Select all

rmt_write_items(RMT_CHANNEL_0, pixels, number_of_items, 1)
rmt_write_items(RMT_CHANNEL_1, pixels, number_of_items, 1)
rmt_write_items(RMT_CHANNEL_2, pixels, number_of_items, 1)
.
.
.

User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby Vader_Mester » Wed Mar 28, 2018 1:27 pm

TheSub6 wrote:Now it works. :D It was a defective LED :roll: RGB is working great but the white LED was broken. Now with a new LED everything works...

@Vader_Mester: The color order is GRBW.
Well, in my datasheet this is not the color order... but manufacturers are you know... make stuff differently I guess :D
TheSub6 wrote: I can post my working code if you like.
Yes! I need that code. I'm struggling with bitbang stuff to get this right. I'm working on a smart light bulb, using these LEDs, so I could use your code to work on.
Still I'm waiting for my level converters to arrive from china it seems forever, so I'm stuck with my logic analyser and some borrowed time in my university lab :D
TheSub6 wrote: Do you have any idea how to do 8 parallel RMT Outputs? Does the RMT Driver handle any parallel output? So for example using more than once the rmt_write_items function. Is it useful to do it in tasks?
According to the technical manual, only 1ch can be active at once.

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

TheSub6
Posts: 7
Joined: Thu Mar 15, 2018 1:24 pm

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby TheSub6 » Wed Mar 28, 2018 2:59 pm

Here is the code. Should light up the first LED full brightness on all channels. I would love to update all channel simultaneously, I have to dig deeper on that topic. Maybe I can postpone the SK6812 terminator in some way.

Code: Select all

/*

// Std. C
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

//FreeRTOS
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

//ESP Specific
#include "esp_log.h"
#include "driver/rmt.h"
#include <driver/gpio.h>
#include "sdkconfig.h"

#define RMT_TX_CHANNEL1 RMT_CHANNEL_0

#define RMT_TX_GPIO 13

#define DIVIDER 8; 	/*set the maximum clock divider to be able to output
					  RMT pulses in range of about one hundred nanoseconds
					  a divider of 8 will give us 80 MHz / 8 = 10 MHz -> 0.1 us*/

#define striplen 1

/*******************
 *SK6812 Timings
********************/
#define T0H	3// T0H for SK6812 -> 0.3 us
#define T0L	9 // T0L for SK6812 -> 0.9 us
#define T1H	6 // T1H for SK6812 -> 0.6 us
#define T1L	6 // T1L for SK6812 -> 0.6 us
#define TRS	800 // TRES for SK6812 -> 80 us


rmt_item32_t pixels[] = {

	// 8 Bit G
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},

	// 8 Bit R
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},

	// 8 Bit B
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},

	// 8 Bit W
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},
	{{{T1H, 1, T1L, 0}}},

   {{{1, 1, TRS, 0}}}, // <- When the 1 is set to 0 ticks, it stops working

   // RMT end marker
   {{{ 0, 0, 0, 0 }}}

};


/*
 * @brief Initialize each RMT_Channel
 * @param [in] number of Channels to be used. GPIO starting at pin 12
 */

static bool initPixels(uint8_t numChan)
{
	rmt_config_t config[numChan];
	for(uint8_t i=0; i<numChan; i++){

	    config[i].rmt_mode = RMT_MODE_TX;
	    config[i].channel = i; // Could be defined via the enumeration: rmt_channel_t
	    config[i].gpio_num = (12+i);
	    config[i].mem_block_num = 1;
	    config[i].tx_config.loop_en = 0;
	    config[i].tx_config.carrier_en = 0; // disable carrier
	    config[i].tx_config.idle_output_en = 1; // activate output while idle
	    config[i].tx_config.idle_level = (rmt_idle_level_t)0; // output level to 0 when idle
	    config[i].tx_config.carrier_duty_percent = 50; // must be set to prevent errors - not used
	    config[i].tx_config.carrier_freq_hz = 10000; // must be set to prevent errors - not used
	    config[i].tx_config.carrier_level = (rmt_carrier_level_t)0; // must be set to prevent errors - not used
	    config[i].clk_div = DIVIDER;

		esp_err_t config_ok = rmt_config(&config[i]);
		if (config_ok != ESP_OK) {
			return 0;
		}

		esp_err_t install_ok = rmt_driver_install(config[i].channel, 0, 0);
		if (install_ok != ESP_OK) {
			return 0;
		}

	} // end for

	return 1;
}

void app_main(void *ignore)
{
    if(initPixels(4)){
    while (1) {
    	rmt_write_items(RMT_TX_CHANNEL1, pixels, (striplen*32+2), 1);
    	//vTaskDelay(50 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
    }

}


User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: SK6812 RGBW LEDs flickering - RMT Driver

Postby Vader_Mester » Wed Mar 28, 2018 6:33 pm

Maaaaaan!

Your code works perfectly!

Check out this video I made of it (sorry for the terrible quality upload).
https://www.youtube.com/watch?v=0v79on9xgug

It goes from RGBW first and lights up each component individually. I added a 500ms delay between the outputing functions.
(I had to put that transparent bulb on the LED, 'cause my eyes were bleeding :) ).

Note: I connected the LED directly to the ESP dev board, no level converter what so ever and works just like that.

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

Who is online

Users browsing this forum: No registered users and 128 guests