Nothing new, but still a neat idea and a good way to get a very sharp pencil.
Nothing new, but still a neat idea and a good way to get a very sharp pencil.
Here’s a video of a Christmas light show myself and another guy did as part of an undergraduate course. The actual hardware was already created for us, so we didn’t have to worry about the high voltage switching and all that. Our job was to write a program in MASM to write out through a parallel port to control the switches.
This video is a little overboard for what the lab required, but we thought why not do something really neat with this since we have it in front of us. See the video below, or read some more details about how it works below the video.
Like I said, the program was written in MASM. That’s the Microsoft Assembly Language. This worked OK, but MASM isn’t ideal for this sort of project. Since we ran this program on a Windows machine, there are a lot of timing issues. If you watch the video a couple times you’ll pick up on some of them. Windows is an interrupt-based operating system, so our program wasn’t guaranteed to run like we wanted it. In the end we had to run it with realtime priority in Windows XP to get any sort of reasonable result.
The program was written as one giant data table. Here’s an example of that code:
BYTE 01110111b, 01110111b, 11100111b, MAIN_EIGHTH ; Da, da, da, da, da, da, daaa (second time) (start in center and go out to bottom bars then back in) [Q] BYTE 01110111b, 01110111b, 11100111b, MAIN_EIGHTH + MAIN_ADJUST_A ; | BYTE 11111111b, 11111111b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11111111b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11111111b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11111111b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11111111b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11111111b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11101110b, 11101111b, MAIN_EIGHTH ; | [QLP] BYTE 11111111b, 11101110b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11101110b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11101110b, 11101111b, MAIN_EIGHTH ; | BYTE 01110111b, 01100110b, 11100111b, MAIN_EIGHTH ; | Dum dum BYTE 01110111b, 01100110b, 11100111b, MAIN_EIGHTH ; | BYTE 11111111b, 11101110b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11101110b, 11101111b, MAIN_EIGHTH ; | BYTE 01110111b, 01000100b, 11100111b, MAIN_EIGHTH ; | [QLPKO] BYTE 01110111b, 01000100b, 11100111b, MAIN_EIGHTH ; | BYTE 11111111b, 11001100b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11001100b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11001100b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11001100b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11001100b, 11101111b, MAIN_EIGHTH ; | BYTE 11111111b, 11001100b, 11101111b, MAIN_EIGHTH ; |
The three bytes at the beginning are data bytes that control the lights. The most significant three bits of the third byte are unused. The last byte, seen as MAIN_EIGHTH above, is a delay. We have several constants defined that define delay in milliseconds. MAIN_EIGHTH represents 1/8 of a beat in the primary portion of the song. We used quarter notes and sixteenth notes here and there too. The MAIN_ADJUST_A is a small adjust to help synchronize things. This segment is fairly clean, but other segments have tons of adjustments made to them. Ideally, this program should have been written on an embedded system, but that wasn’t part of the project.
To execute the program, there is a while loop that shifts the first three bytes out serially, then calls a delay routine. In the end, you get pretty good results.
Hoist up the John B sails, because we got two times the John B that you bargained for. Is the song about Nam? Is it about a musician who turned a poem into a song? Is it about a terrible trip on a boat? I don’t really know…it just sounds good.
So, for your entertainment, both versions. As much of a Beach Boys fan I am, I prefer Relient K’s rendition. It’s a bit faster and sounds great.
Beach Boys:
Relient K:
Learn how to clean up your Email inbox and be more productive with one hour talk. I tried it out with my work Email. If I need to keep an Email, it goes into a single Archive folder. I can search for it later. If it’s a task, I create a new task and delete the Email. The inbox remains as empty as possible.