Inverse phase, a chiptune artist is actually one of my room mates.
And, uuh he wanted to up his stage presence.
So instead of trying to figure out instead of trying to put lights on the outside and
stuff like that, he bought these two panels for about $80 a piece off ebay.
They're a set of 16x16 WS2812's.
For a total of 512 lights stuck to the back of his laptop.
So he can bring his own lights anywhere that he's playing.
One of the problems with this though, not only are you going to have to figure out what
to put on these (Which he's going to have to figure out) but you also have to figure
out how to control them.
So, rather than using any USB bridges and something like that and doing some research,
trying to buy it and what not.
I wanted a solution in an hour, and it wasn't that hard.
I had this extra board right here that has an AVR on it.
It has an ATMega32u2 which means it only has a kilobyte of RAM.
1.5 kB of LEDs, 3 bytes for each LED.
1 kB of ram.
And, the timing on these are very stringent.
You can't just stop sending for a while, you need to keep sending.
So, in order to get the data from the laptop to this continuously, we gotta do something
a little bit tricky.
When you're dealing with WS2812's, the easiest way to get the data out is to use just some
sort of really quick macro.
And, here, all we're really doing is turning PORTD Pin 3 on and off at the right times
to match the spec.
There's a really neet website that I have in the description that goes into great detail
how to choose these times, but it's pretty straight forward.
At the end of this, you get one function that you send an 8-bit value to and it outputs
the value to the next 8-bit value to the 2812's.
You need three of these per LED.
When you're dealing with USB I end up using this thing I got off of a different site,
I think the teensy site, and I've been modding that for a very long time now.
I don't use LUFA normally unless I have an overwhleming reason to do so.
That way this whole project here is 2kB instead of much larger.
Additionally, I use control messages because they are very easy to deal with and you get
better performance on most systems.
So, one of the first things you do (and this is all inside of the USB COM Interrupt vector)
and you can see here you have different requests and different request types.
A3, A4, A6, and the one we care about A5.
A5 here has that WS2812 code in it.
It then computes the number of messages that will be received each with length 64, and
if there are any remaining bytes after that.
So, we go and we loop through all the messages so if we have say 256 bytes we're sending
out, it'll loop through this four times.
So, the first thing we do if we ever want to read data off of the USB part of the AVR,
is read from UEDATX.
This is a lot better than trying to write some function and read that function then
copy the stuff to the buffer, because this instruction right here takes only about two
cycles to execute, which is really convenient.
We can read that into the buffer and we can send out to the 2812's that first byte.
Then byte after byte after byte after byte, we can keep reading the data in from the USB
then we can send out the next WS2812.
By doing this we can actually front load our work or back load our work in order to read
all the data from the USB while sending to the WS2812's.
You might as well why not send UEDATX?
That's because when you're sending all of this data, you can only do so in groups of
64 before you send an ack_out.
This ack out here takes a little bit of time before you can actually go keep reading more
data, so we send the ack_out, and then we keep reading a bunch of ws2812's.
In fact we have to send the remainder of the WS2812's.
Then, this takes a fairly long period of time, and we can call this function right here "wait
receive out."
This generally does not block because we are still sending WS2812 data while the data is
being streamed to the AVR.
So, by doing this sort of funny dance with pipelining which you can do in code in all
sorts of applications, you're able to do things that may otherwise seem impossible.
So, I hope this is a useful tool you guys to be able to go use and apply to different
interesting projects.