WS2812 light controller with ENC28J60 ethernet
EE351
Posts: 81
Hello all!
I have been able to coble together an Ethernet based ws2812 light controller using code found on this forum. The Ethernet driver was written by Harrison Pham, the UDP code was written by localroger, and the ws2812 driver was written by Jon McPhalen. Using xLights pc software, I can output E1.31 data to control 480 ws2812 leds across 6 output pins (80 leds per pin) at a refresh rate of 20 hz. I hope to double the number of leds with the same refresh rate, but I am not sure how to speed up the code I wrote to combine the hardware. I think the bottleneck is where the udp packet is analyzed and the ws2812 code is called. Hopefully someone here can tell me if there is a better way to handle this.
UDP_enc28j60_ws2812_demo.zip
I have been able to coble together an Ethernet based ws2812 light controller using code found on this forum. The Ethernet driver was written by Harrison Pham, the UDP code was written by localroger, and the ws2812 driver was written by Jon McPhalen. Using xLights pc software, I can output E1.31 data to control 480 ws2812 leds across 6 output pins (80 leds per pin) at a refresh rate of 20 hz. I hope to double the number of leds with the same refresh rate, but I am not sure how to speed up the code I wrote to combine the hardware. I think the bottleneck is where the udp packet is analyzed and the ws2812 code is called. Hopefully someone here can tell me if there is a better way to handle this.
UDP_enc28j60_ws2812_demo.zip
PRI handle_udp | udplen, i, templong ' ' other_mac_known~~ udplen := packet[udp_len]<<8 + packet[udp_len+1] if udplen > eth_pkt_max - 34 udplen := eth_pkt_max - 34 'i := udp_data ' repeat while i < udplen+constant(udp_data-8) and ser.txcheck 'ser.tx(packet[i++]) if (packet[156] == 10) 'check the universe # repeat i from 0 to 79 templong.byte[1] := packet[3*i+168] templong.byte[2] := packet[3*i+169] templong.byte[0] := packet[3*i+170] strip.set(i,templong) if (packet[156] == 11) 'check the universe # repeat i from 0 to 79 templong.byte[1] := packet[3*i+168] templong.byte[2] := packet[3*i+169] templong.byte[0] := packet[3*i+170] strip2.set(i,templong) if (packet[156] == 12) 'check the universe # repeat i from 0 to 79 templong.byte[1] := packet[3*i+168] templong.byte[2] := packet[3*i+169] templong.byte[0] := packet[3*i+170] strip3.set(i,templong) if (packet[156] == 13) 'check the universe # repeat i from 0 to 79 templong.byte[1] := packet[3*i+168] templong.byte[2] := packet[3*i+169] templong.byte[0] := packet[3*i+170] strip4.set(i,templong) if (packet[156] == 14) 'check the universe # repeat i from 0 to 79 templong.byte[1] := packet[3*i+168] templong.byte[2] := packet[3*i+169] templong.byte[0] := packet[3*i+170] strip5.set(i,templong) if (packet[156] == 15) 'check the universe # repeat i from 0 to 79 templong.byte[1] := packet[3*i+168] templong.byte[2] := packet[3*i+169] templong.byte[0] := packet[3*i+170] strip6.set(i,templong)
Comments
Perhaps you could have each of the 6 cogs analyze the packet input for two of the cases and control two of the pins going to the leds. Not sure if that is possible without looking at all the code you are using now.
UDP_enc28j60_ws2812_demo2.zip
UDP_enc28j60_ws2812_demo3.zip
UDP_enc28j60_ws2812_demo4.zip
I've been working on a pasm based ws2812 driver that might help your case. Its designed to drive 5 strips at full pelt from a single cog running at 100 MHz.
But, there is one last challenge to solve that is proving elusive, and I should probably throw it over to the forum. Worst case is I will have to drop to 4 strips per cog (which is OK since there are 28 free pins, so 7 cog drivers + 1 master cog), or accept a bit rate slower than 800 kbps. Its just I was hoping to have some more cogs free
This should be able to use all the hub ram, if desired, so you're looking at up to ~7,000 leds managed by a single prop. Divide by 28 outputs, 250 leds per output, at around a 130 Hertz refresh rate. Not bad for a $8 micro, still available in DIP