So I am reading the documentation of WS2812B and see that sometimes they list different timing values f.ex.
T0H - 4us and 0.35us in othes docs T0L/T1H - 0.8/0.85us and 0.9us.
I am not sure what's going on and how those leds are properly controlled with what timings?
Are there some min/max values or discrepancy error? Maybe it all depends on manufacturer?
How accurate those times must be?
Can somebody maybe explain and help?
Thanks
WS2812B - timings and accuracy
Re: WS2812B - timings and accuracy
Not sure but there are several drivers on GitHub that use RMT or i2s to achieve high performance and accurate timing
Re: WS2812B - timings and accuracy
So I just investigated all those timings a little and I am able to use a simple SPI to fully control WS2812B 32*8 led matrix.
It is very simple and it seems like those timings are based on 1:4 ratio to 'lowest 0 high' )
Therefore 1 rgb bit of led is half a byte so one full rgb pixel is 12bytes - still good performance at 2.86Mhz.
1,000,000 / 0.35us (per specs) = 2,857,142.8571428571428571428571429 ~ 2.86Mhz
I will investigate more but code is so short and much more convenient that RMT which takes more memory too.
It is very simple and it seems like those timings are based on 1:4 ratio to 'lowest 0 high' )
Therefore 1 rgb bit of led is half a byte so one full rgb pixel is 12bytes - still good performance at 2.86Mhz.
1,000,000 / 0.35us (per specs) = 2,857,142.8571428571428571428571429 ~ 2.86Mhz
I will investigate more but code is so short and much more convenient that RMT which takes more memory too.
Re: WS2812B - timings and accuracy
I managed to display RGB full color bitmap from PC - actually a 8x32pixels chunk.
However the picture looks very very bright - seems like colors need calibration - I think it is contrast and saturation.
I must check that later
Here is the code that may help to experiment with SPI and WS281B matrix:
Transmission code:
This is for zigzag 8*32 led matrix (going from 8-down to next 8-up left to right pixels)
It works good but maybe there is some catch with colors. It uses 2 color bits per 1 byte so 12bytes gives a 24bit RGB (GRB) pixel
If anyone experiments - please share the results
However the picture looks very very bright - seems like colors need calibration - I think it is contrast and saturation.
I must check that later
Here is the code that may help to experiment with SPI and WS281B matrix:
- spi_bus_config_t buscfg={
- .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_SCLK,
- .miso_io_num = -1,
- .mosi_io_num = PIN_NUM_MOSI,
- .sclk_io_num = PIN_NUM_CLK, // - not used !
- .quadwp_io_num = -1,
- .quadhd_io_num = -1,
- .max_transfer_sz = 0
- };
- spi_device_interface_config_t devcfg={
- .clock_speed_hz = 2.86*1000*1000, // 1,000,000 / 0.35us ( 2,857,142.857142... ~ 2.86Mhz)
- .mode = 0,
- .spics_io_num = -1,
- .duty_cycle_pos = 255,
- .queue_size = 1,
- .pre_cb = 0,
- .flags = 0
- };
- ESP_ERROR_CHECK( spi_bus_initialize(HSPI_HOST, &buscfg, 1) );
- ESP_ERROR_CHECK( spi_bus_add_device(HSPI_HOST, &devcfg, &spi) );
- const int stride=DISPLAY_WIDTH*3;
- const int n_block_size = DISPLAY_WIDTH*DISPLAY_HEIGHT*3;
- static uint8_t* data = NULL;
- static uint8_t* pixels = NULL;
- static spi_transaction_t t =
- {
- .addr = 0,
- .cmd = 0,
- .flags = 0,
- .length = 0,
- .rxlength = 0,
- .user = NULL,
- .rx_buffer = NULL,
- .tx_buffer = NULL
- };
- if(data==NULL) data = (uint8_t*)malloc(n_block_size);
- if(pixels==NULL) pixels = (uint8_t*)malloc(n_block_size*12);
- // HERE LOADYOUR RGB BITMAP TO *data BUFFER
- t.length=32*8 * 12*8;
- t.tx_buffer=pixels;
- int x=0;
- for(int offset=0; offset<stride;)
- {
- for(int row=7; row>=0; row--)
- {
- int n = (row*stride) + offset;
- uint32_t pixel = (((uint32_t)data[n+1])<<16) | (((uint32_t)data[n+2])<<8) | ((uint32_t)data[n]);
- // 210 - byte order in data
- // RGB
- // GRB
- for(int k=23; k>0; k-=2)
- pixels[x++] = (((pixel>>(k-1))&1) ? 0x0E : 0x08) | (((pixel>>k)&1) ? 0xE0 : 0x80 );
- //pixels[x++] = (((pixel>>(k-1))&1) ? 0b1110 : 0b1000) | (((pixel>>k)&1) ? 0b11100000 : 0b10000000 );
- }
- offset+=3;
- for(int row=0; row<8; row++)
- {
- int n = (row*stride) + offset;
- uint32_t pixel = (((uint32_t)data[n+1])<<16) | (((uint32_t)data[n+2])<<8) | ((uint32_t)data[n]);
- for(int k=23; k>0; k-=2)
- pixels[x++] = (((pixel>>(k-1))&1) ? 0x0E : 0x08) | (((pixel>>k)&1) ? 0xE0 : 0x80 );
- }
- offset+=3;
- }
This is for zigzag 8*32 led matrix (going from 8-down to next 8-up left to right pixels)
It works good but maybe there is some catch with colors. It uses 2 color bits per 1 byte so 12bytes gives a 24bit RGB (GRB) pixel
If anyone experiments - please share the results
Who is online
Users browsing this forum: No registered users and 102 guests