e-Bay seller kbellenterprises has a Wiznet 5100 ethernet shield for the Arduino for just $11.49 with free shipping. And, it ships from Missouri (fast). I have not used this shield, but it’s a great price if it works:
I have two 1m 60 LED WS2811 strips, and expect to receive several more in coming weeks from Chinese suppliers. Once I have seven of them, I plan to use them as a scrolling message sign.
However, with two 1m strips (120 LEDs total), you can spiral them loosely (not tight enough to break the strip) and end up with six rows… Sorta. And, with a quick Arduino sketch (making use of some TVout fonts)… You can create a mini-circular scrolling message sign.
Last year, I was involved with a large Halloween project that involved upgrading the lighting in a haunted house attraction to DMX controlled RGB LEDs. We spent many, many late hours running 12V power through the entire attraction to power all the lights, and Ethernet cable to carry the DMX (RS485) control signal. The end result was the ability to set the lights to any color without having to change bulbs.
Changing the bulbs would have been much easier.
A year before this project, the manager there had introduced me to HolidayCoro.com. This site resells LED lighting mostly for Christmas light displays. (The manager had one of those synchronized Christmas light displays at his house and he was in the process of converting the entire setup to RGB LEDs as well, which he did in 2013.)
Like many things here, one thing seems to lead to another, and I want to share some information in “addressable RGB LED lights.”
Adafruit.com sells a number of RGB LEDs, including their Neo Pixels which allow each light to be individually controlled. I first learned of this type of technology in 2010 when some GE Color Effect G-35 Christmas lights were introduced and quickly hacked so they could be controlled by an external computer. In 2010, this was cutting edge, but today, there are several off-the-shelf ways to do this.
An Arduino controls a strip of 32 LPD8806 RGB LEDs.
There are two main LED chipsets I see being used:
WS2811 – Adafruit calls these Neo Pixels, and the lights run in series and are addressed over a one wire connection (power, ground, data) using a special protocol. The library for Arduino to do this is very clever and involves specific assembly language timing to toggle the data line at the proper frequency to send the data.
LPD8806 – this version uses a two-wire interface (SPI protocol) to talk to the lights (power, ground, clock and data). These lights are far easier to address and less timing sensitive.
At Adafruit, a string of 60 Neo Pixels (1 meter) runs $24.95. You can find similar strips (same chipset, same number of lights) on e-Bay shipped from China for around $18, or bid on auctions and get them for less than $10 each.
At Adafruit, the LPD8806 strips of 32 LEDs (1 meter) run $29.95. A coworker at my day job just bought one of these, which is where I first saw them in person. On e-Bay, you can find these for $20 on e-Bay with free shipping from China. To find versions with 52 lights per meter (to get light density similar to the WS2811 version), the cost is around $30.
If you want to experiment with the LPD8806 lights without spending a ton of money or waiting weeks for a shipment from China, check out this seller on e-Bay. kbellenterprises is located in Missouri and will sell a 1-foot strip of LPD8806 lights for $12.99 (with free shipping). They also sell Arduino clones, power supplies and other items at near-China prices (you can get an UNO clone for around $10). You can get one of their strips and hook it up to an Arduino with four wires and safely power the 32 LEDs. (They say you should be able to power up to 2 feet off an Arduino’s 5V 500ma output. More lights than that requires an external power supply.)
As you can see, the LPD8806 lights are about 3 times the cost of the WS2811. The LPD8806 lights are “smarter” (in a way) and easier to work with, without needing specific timing code like the WS2811 require.
For casual play, both work the same way — in fact, Adafruit has posted libraries for each type of light and they both use the same API. You simply set some pixel colors (RGB) and then display them:
strip.begin();
// Set the first 10 LEDs...
for (i=0; i<10; i++)
{
strip.setPixelColor(i, strip.Color(127,0,0));
}
strip.show();
There are some limitations to using these lights on an Arduino. First, the libraries require a buffer of 3-bytes for each LED on the strip (one byte for red, green and blue). An Arduino with only 2K of RAM can only handle 500 or so lights (more or less, depending on how much RAM your sketch uses, and any libraries you use). This severely limits how useful this is for anything other than just blinking a small strip of lights. My old 1990s BetaBrite LED sign, for instance, is made up of 80×7 LEDs (560) so I couldn’t replicate that using an Arduino and these types of lights using the standard library. More on this later…
There are dedicated controllers (Look for the T1000S, around $43 with free USA shipping, or less from China) that can display light sequences on up 2048 LEDs from an SD memory card. You don’t get any computer control this way (all sequences are made ahead of time using special Windows software), but this would be a much better way to drive a large amount of lights than trying to do it with an Arduino.
But what if one really wanted to use a 2K Arduino? Could you actually make a scrolling LED sign similar to a BetaBrite?
Perhaps.
In coming weeks, I will be sharing some embedded programming tricks that might allow controlling far more than 500 or so LEDs from an Arduino.
In 1994, I published a Space Invaders style game for the Radio Shack Color Computer 3. Although there had been many such games for the CoCo since the first model was released in 1980, mine may have been the only version ever released to run on the OS-9 operating system.
Years later, Jamie Cho ported my game from 6809 assembly code to PowerPC Macintosh… Unfortunately, that old app won’t run on modern Intel Macs.
As luck would have it, I saw the name Jamie Cho pop up on the CoCo mailing list the other day and sure enough, it was the same one! Now I have an updated version of the app that runs on modern Intel Macs.
I have been sent a few things I will be using to make a prototype for the Halloween project. The main features will be playing audio on demand, and switching lights (or other 120V items) on and off in time to the audio. Here are the items I will be evaluating:
MP3 Shield ($19.99) from CutiDigi.com. This shield has its own flash storage and lets you load MP3 files over from SD memory cards or USB thumb drives. In addition to control buttons on the shield itself (vol+/-, pref, next, play), it also has buttons to start up the copy operation and put the unit to sleep. There is a 1/8″ headphone style jack for getting audio out. It is controlled via serial (tx/rx) and can be made to play a specific track number off the memory.
Relay Shield ($7.59) from e-Bay seller happyvalley009. This shield has four relays that can handle 120V up to 3amps, which is a small amount but enough for our needs. It is dangerous to run 120V in to a shield like this, as a short could really cause some problems. A better solution might be to use a separate relay board ($8.49 with Amazon Prime shipping) that is controlled without being attached to the Arduino itself. That would let it be physically separate and still be controlled the same way (and, this one can handle more amperage).
As soon as my funding source returns from vacation, we will order more items and begin working on a prototype.
For those who wish to follow along with my Pac-Man project without having to copy/paste source code from these articles, I have posted my current work-in-progress source (which includes many changes I have not discussed, yet).
https://github.com/allenhuffman/PacMan
I have broken the program up in to multiple files, but since this makes quite a mess in the IDE, I am probably going to combine all the bitmaps in to one file instead of separate ones.
If you want to play with it, you can modify the Joystick code to read whatever you have for input (buttons, analog joystick, whatever) and at least move the Pac-Man around the screen. There is no ghost collision detection, no scoring, and no dot handling yet… But it’s a fun demo.
If this $10 shield works the same, it is a very cheap way to get internet connectivity out of an Arduino. If you get one, let me know how it works for you.
The shield I used for my Ethernet experiments was made by Sainsmart and it runs about $20:
I am finally getting around to posting some of my Arduino sources to GitHub. It may be awhile before I get everything updated, but I will at least try to get most of my work-in-progress versions out there for folks to look at.
For some time, my 4+ year old MacBook (late 2009 model) has had an issue with the fan spinning up and being really noisy. For awhile, I thought it was just newer software (like the current GarageBand) being more CPU intensive, but Activity Monitor seldom showed anything agressing going on.
I used things like smcFanControl to show the temperature and RMPs of the fan, and only last night did I do some further searching and realize my fan was running much faster, and the temperature was much higher, than it should be.
I did some searching and found various people reporting the same issue, and also some claims that Apple started using smarter hard drive firmware that the Macs could talk to and detect temperature. I had swapped out my hard drive twice, and wondered if I was just running an incompatible hard drive that was confusing the MacBook…
…turn out, it was far simpler. I ran across this post:
…and he suggested just cleaning the fan. I took my MacBook apart (eight screws on the bottom, then one micro tiny fan plug and another larger plug – be careful with the small one – VERY careful, tiny pins), and then took three screws out to release the fan and one more tiny screw to open it up. I used a can of compressed air from Radio Shack (which I bet I’ve had for 15 years) and cleaned it all out. The rear air vent (inside) was also clogged.
After reassembly, the MacBook is quiet like it used to be.
So far, there have been nine installments to this rambling series on creating a Pac-Man style game for an Arduino using the TVout video library. During the course of this discussion, many small things have changed so I thought it might be a good time to reboot the series. Here is a brief updated overview of the process so far.
0. Inspiration and Evolution
One night, two weekends ago, I decided to try the TVout video library for Arduino. I cut up an old A/V RCA cable and used two resistors to connect it to my UNO and soon was running the TVout demo. I next created a small program to draw a line, square, and circle. Then I decided to make the circle bounce around the screen like a ball, followed by bouncing multiple balls. I soon replaced the circle with a bitmap graphic so I could bounce a different shape, and ended up making that shape a Pac-Man which I could steer around the screen, avoiding the balls. Somehow this led me to decide to create a full-on Pac-Man style game.
1. Creating the Maze
Pac-Man
I would be using the default TVout video resolution of 120×96. The original Pac-Man resolution is 224×288 and uses a monitor that is turned sideways (portrait mode) so it is taller than it is wide. If I just scaled that screen size down proportionally, it would become 75×96 and make for a very small maze.
I decided to take the approach used by most home versions that would be played on traditional monitors (landscape) and crop off the top and bottom area (score, lives left, level) so only the maze would be left. The maze alone was 224×248.
I began the process of drawing out the maze, pixel by pixel, on top of this scaled down graphic. As I did this, I had to adjust my maze size a bit so everything would line up. Some later research revealed that the original Pac-Man screen was divided up in to 8×8 tiles of 28 across and 36 down. (Or, when the top and bottom where cropped, 28×31.) In order to get 31 tiles vertically out of the TVout’s 96 pixel tall resolution, I did some simple math and divided the height of the TVout screen (96 pixels) by the number of tiles I wanted to display (31). 96/31=3.096. It seemed I would need to round to 3×3 tiles.
Pac-Man Arduino screen.
Going across the screen (28 tiles) at three pixels each was 84 (3*28=84). Going down the screen (31 tiles) at three pixels each was 93 (3*31=93). My scaled down Arduino maze would be 84×93, and that would allow it to be the same number of tiles as the original, just using smaller tiles.
I used a 3×3 grid to draw out the full maze, and took the liberty of making the side walls a bit wider than they really should be to make them look better. (If you look at the thick walls around the ghost house in the center, that is how the entire outer wall should be for the scaled down lines to be the same dimensions. That is the only thing about this maze recreation that isn’t dimensionally accurate.)
I used a website to convert my graphic file in to C data statements that could be displayed by the TVout bitmap library function.
2. Sprites
Pac-Man Arduino sprites.
I next created the ghost and Pac-Man character sprites to use in the game. The original arcade sprites were just under two 8×8 tiles wide and tall (less than 16×16 pixels) and would fit in the maze corridors. Since my corridors were now 5 pixels tall or wide (just under two 3×3 tiles) it seemed to work out perfectly to make my game characters 5×5. I designed Pac-Man with three frames (mouth closed, partially open and fully open) just like the arcade, and created versions for all four directions. For the ghosts, they had two frames of animation, and a version for all four directions (with the eyes facing that way). I drew these in a graphics program first, then hand entered them as data in the C source code.
2. Moving – some new stuff here!
Moving through the maze was a challenge. Originally I tried to detect walls by looking for set pixels, but I kept running in to places where the characters would get stuck at the rounded corners. After I learned about how Pac-Man used the tile system, that provided a nice and simple solution: I created a binary map that represented all of the tiles on the screen (28×31) and put a 1 where a wall would be and a 0 where a hall/path would be.
Once I had this, I worked out a system which would track which tile a sprite was in, and check for tiles around it to see if it could go in that direction. This is the part of the project that has evolved the most over the past week as I learned that tiles were also used for how the ghosts knew where to move (they head towards a specific tile), and how collisions between ghosts and Pac-Man were done.
Ghost sprite moving right.
Pac-Man considered a sprite to be in whatever tile the center of the sprite was in. Because of this, I would be tracking the X/Y coordinate of each object based on its center. In a 5×5 sprite, the center would be at (3,3) if we used base-1 and started with the top left pixel at (1,1) and the bottom right pixel at (5,5). In order to allow sprites to move smoothly, I would also track an X/Y offset within pixel. In the diagram to the right, the top ghost appears at the center of, for example, tile (10,10) with an X offset of 0. As it moves to the right (second ghost), it would still be in tile (10,10) but would have an X offset of 1. As it moves to the right again (third ghost), its center would now have it be in tile (11,10) with an X offset of -1 from that tile. Lastly (four ghost), it would be in tile (11,10) with an offset of 0.
I would need, at the very least, for each sprite to contain something like:
uint8_t x,y;
int8_t xOffset, yOffset;
To figure out where on the screen to draw the sprite, I would take the tile coordinate, and multiple it by the size (3 pixels tall or wide), and then add the offset. In the above example, tile (10,10) with an X offset of 0 (in the center) would correspond to screen pixel (30,30). As the ghost moved to the right, it would be at (31,30) and (32,30). I also needed to add a few pixels to X and Y to compensate for the maze bitmap being a bit wider than the tiles under it. (NOTE: This is simplified. In the actual code, I also add half the width of the tile to keep the X/Y positions representing the center.)
To keep from having to do this kind of math (MAZEX+x*3+xOffset) every time an object was displayed, I thought I might also track the screen position separately:
uint8_t xScreen, yScreen;
I would need to do some testing and see if the overhead of the formula to calculate screen position every time was better than tracking two separate X/Y coordinates (one for tile, one for screen). Therefore, this approach is still something that could change. It would make the code seem simpler, but perhaps at a cost of extra CPU cycles needed (versus just having a variable around).
Objects also need to know what direction they were headed in. Initially, since I had started with a bouncing ball demo, I gave each object a directional offset variable that could either be +1, -1 or 0 depending on if the object was moving right/up, left/down or stopped. I was calling them “mx” and “my” (movement X, movement Y) and to move, I would just do something like:
x = x + mx;
y = y + my;
As I got further in to development, I decided that since no object ever moved diagonally (thus, no mx=1 at the same time my=1), using two variables was not needed. Instead, I could just track the current direction with one, that would be set to UP, LEFT, DOWN or RIGHT:
uint8_t direction;
And, because ghosts look one tile ahead to decide where they will turn when they get there, and because Pac-Man allows the player to push the joystick in a different direction as he is moving and instantly be ready to turn there, I added:
uint8_t nextDirection;
When I share the updated code, this will make more sense, and the new code should also be much simpler.
3. Ghost A.I.
With the basics of a maze and ability to move around it figured out, I then moved on to the logic of the ghosts. Pac-Man ghosts basically just try to move towards a target tile. That tile either causes them to scatter to a corner, or to try to track down Pac-Man, based on the mode the game is in.
To achieve this, I created some functions that let the ghost determine what it’s next direction should be at every intersection. It does this by comparing the tiles it could turn to and seeing which one is the closest to the target tile. Once I had targeting working, the only thing left to do would be add code to change the tiles as the game modes changed (from scattering to the corner, to chasing Pac-Man, to running away frightened after an energizer pellet was eaten).
There are also some special rules that needed to be taken care of, like the four passageways that ghosts are never allowed to turn up, and handling the side tunnels.
4. Dealing with Dots
A big portion of the project, currently left untouched, is figuring out how to handle all the dots on the screen. I have previously shared my idea on how this will be done, but I have yet to write any code to test this idea (this will be next). Once this is done, there will be very little left to do for the “engine” of this game to function.
5. Miscellaneous TO DO
The final part of this project will include coding some specific routines to handle things like:
Scoring as Pac-Man eats dots.
Collision detection between Pac-Man and Ghosts.
Changing mode to FRIGHTENED when Pac-Man eats an energizer pellet.
Displaying bonus fruit at appropriate times and scoring if eaten.
Altering speed of Ghosts and Pac-Man based on levels and mode. Also, ghosts slow down in the tunnels, Pac-Man is slower while eating dots, and Pac-Man can slightly cut corners when turning.
Intro screen, intermissions and high scores.
Sound.
…and probably many other things I haven’t even thought about yet. For instance, just yesterday, I saw a “cut scene” between levels that I had never seen before. I will have to find videos of all of them to try to recreate them.
And with that out of the way, it’s time to resume this project reboot, and share the current state of the code.