ECE497 Project Programmable Light Show

From eLinux.org
Revision as of 04:36, 18 November 2013 by Tpurviance (talk | contribs) (Installation Instructions)
Jump to: navigation, search


Team members: Taylor Purviance

Executive Summary

The idea of this project is to have a Beaglebone controlling a strand of LEDs and drive the LEDs to flash different colors and patterns. The patterns and colors being displayed will be programmed via a simple web interface, allowing anyone to program the lights.

The system works pretty well with a single user, allowing them to program the lights via web interface and have the lights update. Most issues of the light update speed have been rectified and now updates fast enough.

Somewhere, the first light on the chain isn't always getting set properly for some reason (which I suspect is kernel driver related). Also, there's no support yet for remembering your Blockly program if you accidentally close the tab which you were working in, and every programmer knows irreversibly losing code can be infuriating.

The project is actually in a really good position right now, though it isn't ready yet for public / multi-user access. With a few exceptions, it does what it does well and is enjoyable to use and see used, so the focus of future development can be on any of a plethora of possible new features.

Installation Instructions

Required Hardware

In addition to a BeagleBone Black, this project requires 5 meters of Adafruit's LPD8806 LED Strip.

Required Software

You'll find everything you need in this projects github repo: https://github.com/tpurviance/programmable-light-show

Installation

Connect the LED light strip

The LED light strip should be plugged in to 3.3V (should be hooked to the white dot on the LED plug), P9_22, P9_18, and ground. Be especially careful, as the LED light strip can be critically damaged through improper wiring or voltages.

User Instructions

1. Run the setup script

Run the included setup.sh file.

2. Start the boneserver

Start the included boneserver.js file.

3. Navigate a the page via web browser

With the boneserver now running, point your web browser to your bone's IP address on port 8080.

4. Drag and drop blocks

Although there are a plethora of blocks available in blockly, you will likely be interested in the blocks under the "lights" category. One of the blocks if for setting a light at a position to a color. The position value should be between 0 and 159, while the red, green, and blue values should be between 0 and 127. However, this is just queuing up the changes locally. To display the changes you've made, use the send lights block. If you want more than one light to change at the same time, use the set lights block multiple times before using the send lights block. If you're doing some animation, you'll likely want to give it a number of milliseconds to delay after the lights are changed before they will be set again.

5. Click the "run" button

Once you are ready to see your code run, click the "run" button near the top of the web page. If you get a message saying something about "bad code" make sure that your blockly blocks have all of their input spots filled or simplify your design and try again.

Highlights

The thing about this project is that it's really just an enabler; it enables anyone that connects to the server to come up with their own ideas about what they want to have the LED string display, and it lets them do it. That being said, here's a video to demonstrate some of the things you can have it do.

Demo Video

In the video there are 3 things demo'd:

  • A red sine wave and a shorter-wavelengthed red sine wave
  • A single red light the races to the end of the strand and races back blue, then does the same thing but as a group of 10 lights.
  • A simplified no-controls version of pacman, which spawns some random white pellets and has a yellow group of pacman lights go down the strand until he's eaten them all, at which point he blinks a few times to show that he's won.

These are just some of the things someone could make. Creativity and time were my limiting factors for this demo, but I hope to see others make more interesting displays with this tool.

Theory of Operation

LightShowDiagram.png

This diagram gives a good macro-scale view of the design. The Blockly code, both my custom blocks and the default ones, produce and run javascript code in the browser. The blocks that I added also send messages via socket.io to the boneserver. Each message contains a list of the lights that need changed, what they need changed to, and how long the boneserver should wait before processing the next message. The boneserver maintains a queue of the received messages which it process in the order they are received. The contents of the message are read and the bonescript writeToTextFile() method writes the appropriate batch of light changing data to the kernel driver, which then parses those messages and shifts the appropriate data down the light chain.

Work Breakdown

Here are some of the big accomplishments of the project to date:

  • Integrated Blockly (hosted externally) into a web page hosted from the bone
  • Added custom blocks to Blockly to 1) track the state of the lights being changed 2) sends the lights that are being changed via the program to the bone via socket.io
  • Added an html5 canvas / javascript powered display of the state of the lights to the top of the web display, though it doesn't yet know how to handle the recently added delay function, so it only shows the end result of running the program.
  • Added some new socket.io message handling to the server.
  • Added message queuing to the server code, allowing it to do things like delays in an intelligent way. This is queuing behavior also lays the groundwork for multi-user handling, as well as "recording" and "playing" back light shows, all of which require something other than "just display the lights when we're told".

Future Work

There's a wealth of possible future features to add, as well as a few bugs to fix:

  • Multi-user handling
There's a number of ways one could go about doing this, but the simplest would be to have the server maintain not one queue of light messages, but to have a mapping of connections to queues so that each users interactions with the bone can be stored in a separate queue so their messages don't interleave and mess up the display for both of them. Deciding when to play animations from which queue is also an interesting problem. One solution is to just play some amount of each user's animation on the bone, measured in number of frames and the amount of delay they use.
  • Video sending instead of frame sending
It may be beneficial performance-wise to send an entire video of animation instead of a single frame, as it currently does. This would allow for entire animations to easily be sent, stored, and played, as well as saving on socket.io overhead. It would also help to protect the server from bad code. If the user made in infinite loop that continually sends frames to the server, the server has to off the messages itself. The server currently has a maximum frame buffer size and maximum allowable delay for this purpose. If the entire message has to be sent at once, the user would just have to deal with his non-terminating loop, as the message would never be sent at the end because their code would never finish, saving the server that much work.
  • Add input controls
This one could be very tricky, but opens a whole new world of functionality for the project. Adding some physical buttons / dials / whatever near the lights to allow people to interact with them would be very interesting. The pacman "game" demo'd above would be one such example that would be vastly improved by some user input. However, doing this would likely force the project to move away from the current setup of making frames on the front end and sending them to the back end to be displayed, and instead force the Blockly-produced lightshow programs (not frames) to be sent to the bone to be run so they could handle real-time user data. Allowing execution of arbitrary user-generated javascript code on the bone certainly strikes me as being a big security problem, though I'm not hugely knowledgeable on the subject. Perhaps there is some other way to allow input to be handled without executing arbitrary code on the bone.
  • Add idle playing behavior
While this project is cool, if the lights are up and running all the time then one can't expect someone to always be sending light displays to it. Thus, it might be a good idea to store up some light shows to display when no one else is trying to display something. After some amount of time or after all users have disconnected, have the boneserver start to play back a recording of the light setting commands someone had sent it. Perhaps a static batch of them loaded in from text files on startup, or perhaps just a rotation of the last X frames or videos that users have sent to it.
  • Updating localized light visualization
If users won't be able to be next to the lights all the time, or the lights might not currently be performing for them but rather performing some other user's code (if multi-user capabilities are added), it could be beneficial to the user experience to allow them to locally view the lightshow with the html canvas I had working before. It wouldn't be hard to do. You could copy exactly what the server does with the socket.io signals it receives from users, and execute it locally, including the queuing and the delays.
  • Add more lights
Pretty self explanatory. A longer or more densely packed light strand would look better and give the users more to work with, though the strands don't come cheaply. However, adding more lights could slow down the light refresh rate of the strand.
  • Fixing the first light
For some (I'm feeling driver-related) reason, the first light in the strand is not changing to be the correct color all the time.

Conclusions

Bringing the project this far has been lots of fun because it is so visual. Although there's still that rogue LED in the chain, for the most part it's all behaving fairly well. As one of the goals is to make this project usable to decorate the ECE department tree, I would suggest that adding the video sending and idle playing features from above be added next, as both of them are fairly easy to implement and can be up and running in time for the lights to be on the tree when it arrives.