So a while back I've started helping my friend Doug with some of his projects, and sort of took over one that was above of his current capabilities (I'm more of a C/C++ guy, he's more into Python, so it worked out).
Doug wanted to make his journalist friend a news ticker - something that will read RSS feeds from across the great plains of the internet and scroll them on an LED matrix - like the Times Square, or the 80s. So We dived in.
First the LED strips. We used had 3 matrices daisy chained, each on is 64x16 single color LED matrix. You can find them on the cheap here. We found some code to run a single matrix and scroll text here, but it had a few problems:
* Scrolling was kind of ugly - the new characters just appeared at the end of the text instead of scrolling in. Looked a bit weird.
* It had no means of communications with the outside world to get the text, and with all of that time spent in interrupts I hardly believe it would have worked.
* Biggest problem, and honestly the only one I tried to solve on the original codebase - It didn't support more than a single panel, and wouldn't easily as well.
So I went to work on taking just some useful bits and rewriting the thing. I fixed a few things there:
1. The frame buffer was sort of confusing to me, so I redid the memory organization. Now it's just a bit per pixel, organized in rows. Also, looks like the original code came from a library that supports a 32 lines matrix with two scans line, which aren't needed here. That reduced the frame buffer memory footprint by half, which is meaningful for multiple panels.
2. Scrolling - The original code moved all the memory one bit to the left every time it wanted to scroll the text one bit. I keep the buffer stationary and keep a bit offset of the first pixel. That way scrolling the buffer is just adding a value to the offset.
3. Communication - In order to provide smooth scrolling of long strings I've went with a buffered implementation. The Arduino has a 128 characters buffer for the next cahrs to display. It scrolls about 6-7 chars per second, so that's about 14 seconds of time for the world to catch up. Every second it will send out how much free space it has in the buffer. Whenever it gets text it will put it in the buffer. The shell script in the host plays nice with that using very few lines of code.
4. Choppy scrolling - Remember when I said there's a bit per pixel? Well, I lied. I've made the buffer wider by 8 columns, which is the width of the font I'm using. Every time the scroll offset aligns with 8, it means we just finished showing a characters, and that memory is currently not being displayed on the LED matrix. So we quickly replace it with the next character in the input buffer, giving us smooth scrolling of the letters into existence. Also, when the text buffer is empty we jut stop scrolling and wait for more data to arrive. It looks great.
On the Raspberry Pi side there is a 13 lines shell script that uses the rsstail utility to get the titles of the desired feeds, formats them all into a one big string, and then waits for a number to come from the serial port of the Arduino with the amount of free space, and sends out the corresponding amount of bytes.
If you want to check the code out (Sorry I didn't include any in the post, but it's late) , it's available in my GitHub.
Happy Newsing! also, here's a video of the thing in action.