Not on an AVR, i think on an ESP32 using RMT it could be done, but the speed is just way beyond what can be reliably received.
as an example, swSerial is reliable for reception up to about 57600 bps. WS281x signal is transmitted at 800KHz, being 800000 bps, but it is not in a format that is like Serial, but rather in a self-clocking SPI, where every bit is sent as a pulse, but the value of the bit depends on the length of the pulse.
Sending and receiving are just 2 completely different things a MCU can do.
It might be possible to receive it over the UART while it is running at 5MHz, but the speed fluctuations are allowed to be significant according to the specification. If you know what and how the signal you are trying to decipher, is created, you may be able to receive it in the same way, but in that case there are better ways to transfer the data.
It's hard to find any discussion of the neopixel protocol that does not use the word "critical" when describing the timing, but it is not nearly s unforgiving as you might think.
I can't find the article I read some years ago, but what I took away from it matches well with this AI generated response:
The timing is in fact quite loose, but still just really fast.
Libraries that i have seen that use the UART to generate it come in 3 types. 5 step, 4 step and 3 step.
5 Step uses 8N1 at 4MHz. 1 byte represents 2 bits
4 Step uses 6N1 at 3.2MHz 1 byte represents 2 bits (
3 Step uses 7N1 at 2.4MHz 1 byte represents 3 bits.
The loose timing allows for shapes to of the duty cycle to be quite different, and also the overall frequency has a fair bit of width. This is all fantastic for transmission, as a lot of different methods will actually work and it doesn't matter to much if it isn't perfect.
But now here's the thing. Because of exactly this, reception will also have to tolerate all of those possibilities and that actually makes it even harder. And seriously, 800KHz is pretty quick for a 16MHz processor. That is 20 clock-cycles per receiving bit. Think of all the processing required.
Using a UART in 5-step is an option but it would need to run at 4MHz. RMT is intended for something like this (IR but most MCUs with RMT can handle it.
These are hardware peripherals that can manage. One could create a very specific peripheral for the purpose, but let's not exagerate.
On a 16MHz processor without these options, the best one can hope for is counting and switching, but reception is out of the question.
It doesn't have to. Witness the fact that an Uno can generate the signals with many cycles to spare
1.25us is 20 cycles. A 0 is high for less than 10 cycles and low for the rest. A 1 is high for more than 10 cycles and low for the rest.
If I synch with the RISING pulse, a read 10 cycles after gives me 0 or 1 and I have a few cycles to "do something" like output echo to different pins. Yup, Tight but not impossible. Still, I'd rather a faster chip.
This could only run on a small internal loop, not void loop IMO.
I'm more wondering about wiring WS28xx nodes to a matrix that uses 2 pins to select and pass data to single nodes. An 8x8 seems natural.
Instead of making these wild statements, i suggest you show us how you actually intend to do the reception and transmission. I know that even just for counting the pulses without reception and parsing and re-transmitting, you need to depend on a hardware counter and it's hardware switching. 20 clock cycles sounds like a lot, but it isn't.
You're right about that, interrupts are too slow to synch 20 cycles and the fastest polling I've done was with a 12us void loop() that watched contact bounce, an order of magnitude too slow.
from a pure technical point of view, given there a very few pixels, yes you could and if updates are not frequent, it can work (assuming you don't use dedicated hardware and "advanced" features like DMA then it has a drawback as you will loose the next "frame" if you are in the middle of sending what you buffered when it arrives).
I wonder if SPI could capture the stream, IIRC default is CLK/4 good for 512KB/s, 4MHz compared to WS at 800KHz. It'd be interesting to read real world data as clocked SPI bits.
Standard Arduino SPI hardware does not support passive sniffing because it requires the clock and chip-select relationship of an addressed slave - I’m sure this can be worked around as logic analyzer do but it probably isn’t straightforward.
So - why do you want to treat your multiple LED things as one long strip, instead of using one of those boards or controllers that can simultaneously drive multiple strips? For instance, Adafruit has a library that will drive 8 strips from a SAMD chip (possibly also requiring an inexpensive level shifter to get the SAMD's 3V signals to WS2811 compatible 5V signals.)
Parallel driving is not even required. using multiple outputs would also suffice, but i think adding a return data line is anyway the best approach, providing more flexibility.
I thought anyway that the controller was done already.
Does there need to be such? The master provides CLK and CS as it reads 0 or 1 from MISO... the slave is assumed to be there.
I thought about trying to synch SPI frames with the WS but... does it really have to? It has to know and count pulses to switch output pins but 20 cycles per WS bit is 160 cycles per WS byte, 10us is 100KB/s where SPI default is 512.
A good state machine should run faster than that and be interesting work to make. Lining up SPI with WS could be unnecessary --- we want to know how many bits wide the HIGH pulses are even across SPI bytes, switch-case on 2 or 4 bytes of 'history' to get a slightly delayed output from the input.
Well first of all there needs to be break detection. Although WS2811 specifies 50us, WS2812b specifies 300us and most other chips use something bigger than 200us, so for compatibility reasons, something like that.
Since the Master provides the clock and the incoming signal has quite a lot of variance or drift so to say, the Arduino should act as a slave, not as a master.
If you can delay the pulse of the signal for the duration of the specified duty cycle of the 0 bit (and a tiny bit more), you can use that as a clock.
I am looking at how to read asynch pulses in data with a state machine and yes it would have to do with breaks and never lining up pretty as the effort to do that would kill the effort.
Well the simple solution is using an ESP32 and RMT.
It has an idle detection which calls a callback in which the parsing of the pulse lengths can quite easily be done.
Thank you all for your input to this. I feel somewhat over whelmed with the number of inputs and comments made in just a number of days so again, thank you.
I hadn't fully taken into account the complexity of the task in hand.
There have been a number of posts which make me realise that a simple piece of wire saves so much complexity and that I am somewhat out of my depth in coding and maybe more to the point, exactly how the data stream is setup and manipulated.
It would appear that the Arduino maybe not the way forward however as something faster is required.
As I have recently purchased a ESP32 and not had it out of the box, I will start to have a look at this and the opportunities that it brings.