Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Reading WS2812b leftover data through I2S

Hello there,

I am currently trying to read the leftover WS2812b LED strip data which was sent using a single channel I2S. The data sent from the board (through I2S) looks like this:

with around 34 mV for high and around 2~6 mV on low. I decided not to send FFF, but 888 instead.

I am aiming to calculate the length of the LED strip. Each LED chip will read the first 24 bits of the data, cascade (discard) it, then pass it to the next one. Therefore, the strategy is to get the data after being cascaded by the last chip and calculate the length of it (which later will be divided by 24 to see how many are left).

The question is: How will I be able to read those data? I tried reading as usual (set a buffer for the i2s, start it, listen for it (delay), stop it, then check its buffer), but I got my buffer filled with all FFF instead. and a thing is that... when I tried to read anything from the pin, although I am not sending any data (the LED strip is not powered on, but connected to other's ground), there will be data, which should not happen. I assigned pin 22, 23, 24, 25 to be the i2s input pin (which will be assigned and unassigned when used or unused), and they are configured as follows:

nrf_gpio_cfg_sense_input(DIN1_PIN, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);

Thank you in advance.

  • Yes, that is right. Now that you mentioned about it, I checked and confirmed: you're right, it is not anywhere above 3 V. so... I suppose I am stuck with 5V and level converters.. okay..

    That being said, do I need to regulate the signal down back to 3 V (step down) using level converter before connecting it to other board?

  • You need level shifters on signals going both ways in order to respect the limitations of both devices. It is described in the blog you are using as far as I can see.

  • Alright, I get that.

    Okay, I connected board A -> level shifter A -> LED's Data in. Then, LED Data Out (the same strip, uncut) -> Level Shifter B (Hi) -> Level Shifter B (Low) -> Board B. I used oscilloscope and found out that the data is all the same, but with a lower voltage: (max) 214.84 mV. Is this the expected behavior?

    The yellow probe is connected exactly after the DOUT of WS2812 and green probe is connected at Level Shifter B's LOW Output (please refer to the diagram below).

    No matter if I use 1 nor 2 level shifters, they will result the same. output at this voltage.

    I connected the level shifters this way:

    Notes:

    * Those are NRF52DK, PCA10040, not Arduinos.

    * The extra blue cables from the LEDs means they are connected to ground

    * The left board (Board A)'s output is set at P0.11 ~ P 0.14 (I need 4 of them)

    * The right board (Board B)'s input is set at P 0.22 ~ P 0.25 (I need 4 of them)

  • Oh, sorry, I didn' realize this until last night, before I go to sleep

    I set the oscilloscope probe wrong. This is the correct data:

    and yes, i still receive ff's on the i2s input

  • Hi,

    I am just summing up the basics here:

    • Logic '0' for the WS2812 is transmitted from nRF SPI peripheral as 0b0001 = 0x1
    • Logic '1' for the WS2812 is transmitted from the nRF SPI peripheral as 0b1110 = 0xE
    • And the other way around for receiving.

    Are you sending a string of 0x1 and 0xE's from the I2S peripheral as you should, and this works properly so that the (color and intensity is set as expected)? If no, then you should look at how you write data first. I am having a bit of problems reading the oscilloscope plots, but it does seem like the bit sequence in the last plot is 00010000 00000000 00010000 (a short high level after the rising edge is '1' and a long high level is '0'). Which data did you shift in? Is it the same? If it is, then so far so good, and the problem is only with reading the data back from the nRF.

    Reading the data from the nRF using the I2S peripheral will be more difficult (if possible). I2S assumes the data to be synchronous, but there is no relationship between the I2S clock and the data out of the WS2812 in this case. And even if we are lucky, how steep are the rising and falling edges? If the nRF samples at a bad time, it might read data which is in the undefined regions. I think the conclusion is that it is difficult to achieve this in practice using the I2S peripheral.

    A better approach could be to oversample the signal using another approach. I think the only viable approach on the nRF is to oversample the signal by reading the GPIO pin at a high frequency, and then analyzing it, doing edge detection to decode the signal. Unfortunately, the nRF does not have a generic way to sample GPIO pins and storing it using DMA, so you have to do it in SW. That might be OK though, as long as the speed is not too high and the nRF does not do much else.

Related