Digital Window Sticker (Arduino Controlled)




Introduction: Digital Window Sticker (Arduino Controlled)

About: I've been writing software since I was in the 6th grade, and working with mostly-digital electronics since High School. These days my career consists of software development and architecture that is focused o…

A bumper-sticker sized L.E.D. matrix that displays images in sequence from an SD card, to produce an animated sign or "window sticker." Arduino controlled! Also includes Windows, Mac, and Linux code for converting .xbm image files into Digital Window Sticker files. Perfect for a shop or home window, or a fun desktop sign!

Step 1: Parts List

Digital Window Sticker Parts List

Arduino Compatible Bare Bones Board KIT (BBBKit)
Ask for the LM7805 regulator!
Optional, see below…
See PCB note below
See Header Receptacle note below.
See SD-MMC Card note below.
Low Capacity SD Card (e.g. 512 MB)
9-volt power source
Solder and 22-gauge wire of various colors

The BBB Kit is an Arduino clone produced by  At $15.00 for a complete Arduino kit, it is one of the least expensive options.  I could have cut a few dollars off of the cost by using an alternate Arduino board and a separate supply list for each Arduino component, but the convenience of a single supplier for the Arduino portion of this project was worth the $3 to $5 I may have saved.  You should be able to make this project with any Arduino.  It can be prototyped on a breadboard as shown below, with a Boarduino, a Bare Bones Board, or other breadboard adaptable Arduino clones.  You can also purchase the BBB fully assembled for an additional $10.  The owner of is very helpful and will work with you if you run into problems.  Download the BBB assembly instructions and follow them carefully.  MAKE SURE to request the LM7805 voltage regulator for the board, or purchase one separately and use it in place of the smaller regulator that he ships by default.

The USB BUB Board plugs into the BBB (Arduino).  It has the FTDI USB to serial converter needed to program your BBB Arduino.  If you have already have an ICSP programmer, or an Arduino with a ZIF socket for programming the Atmega 328p, it is not necessary to purchase the USB BUB, though it is useful if debugging the microcontroller code, through the Arduino IDE's Serial Port Monitor.

IMPORTANT NOTE regarding the 2416 Dot Matrix Displays.  As you view my construction photos you will notice that my 2416 Dot Matrix Display boards don't match.  One has white (when not powered) L.E.D.s, the other has transparent ones.  The transparent set is slightly dimmer than the diffused set.  When I contacted Sure Electronics about the problem they agreed to send a replacement board.  It arrived just in time to complete this article, and the final photos and introduction video show the matching set.  Unfortunately, the new board they sent me uses the dimmer, transparent L.E.D.s.  Be sure to let Sure Electronics know that you need a matching set!  You may want to order 3 boards just to be safe.  Also, the green boards came out recently.  I don't have experience with them, but had they been available when I made my purchase I would have used the green.  Finally, remember that Sure Electronics is based in China.  Plan on waiting a while for your product to arrive, and arrange for someone to sign for the package.  The folks there are easy to work with.

PCBs:  If you wish to follow the step-by-step instructions I am providing you will need the Radio Shack printed circuit board, and you will need to trim the ends of it to fit properly in the enclosure.  This also means you need a right-angle connector on the 2x8 Shrouded Box Header (that the ribbon cable from the displays plugs into).  The right-angle connector is required so that the pins can be bent to bridge the breadboard gap on the Radio Shack PCB.  If I were to start from scratch, I'd try using one of the following prototype PCBs, which would also allow you to wire-up a straight 2x8 shrouded box header: If there is enough interest, I will design a circuit board and have them manufactured.Enclosure: The project enclosure is an almost perfect fit.  You'll see in the steps and photos that follow, that my strength is not in cutting plastic enclosures.  You will hopefully do much better and provide feedback on better methods.  Mine works great, but isn't great looking.  As you will see, the enclosure was something of an after-thought for me.  I had an entirely different enclosure planned, but this worked out much better.  (More information in following steps.) 

Jameco*: Each of the items listed above with an asterisk(*) can be purchased from Jameco, but require a minimum order of 10, so if calculating the cost keep this in mind.  (It is always good to have extra parts!)

Header Receptacle: The BBB has 18-pins for the power-supply and Arduino pins to plug into a breadboard.  Use the 20-pin header receptacle to plug the BBB into your printed circuit board as shown in the following instructions, with the following variations:
  • I did not have a 20-pin header receptacle, but I did have 2 8-pin receptacles.  This will work fine.  It is a tight fight to get them to align properly, but it works.  Just make sure to follow the pictures provided.  You'll notice that 2 of the BBB pins are left unconnected.
  • If you use the 20-pin header receptacle, 2-pins will remain unconnected.  Mark your board so that when you plug-in the BBB you know where it goes.
  • You could also forgo the breadboard pins on the BBB, and the socket on the secondary PCB, and simply run wires directly to the needed locations.  This may provide some flexibility with enclosures.
The 2x8 Shrouded header box is for plugging in the ribbon cable from the display matrices.  As mentioned above under PCBs, the right-angle version is needed if you have a gap like that on the Radio Shack PCB.  You could possible use the same board and cut copper traces to make a straight header box work properly.  I purchased my header box from a local supplier (M.C. Howards Electronics in Austin, TX), but they only had a few and I've not seen any more in subsequent trips.  The link provided above was the first one I found that had a matching part, but I don't have experience with the company.

SD-MMC Card: Wow, this is an over-priced component if there ever was one.  It works great!  In fact, don't bother with any of the Arduino SD card Shields.  They all seem to use a resistor network to drop the signal voltage to the 3.3 volts required by the SD card.  This will not work with all SD cards.  In fact, my card worked for only a few minutes this way, and when I put it back in the PC I had to format it, and then it never worked again with the Arduino until I used the 74HC4050 for the signal level conversion.  I had other cards that didn't work at all without this as well.  If you decide to use a different circuit board, and could plan out the fitting in the enclosure better, I would try to solder a much less expensive SD card socket to the board directly, instead of using the costly breakout board.  Incidentally, NKC Electronics has the same breakout board listed for much less, but it was unavailable when I last checked.  I don't remember if the breakout board includes header pins.  You will need 11.  A spare set can be ordered from Jameco:, for $0.75.

SD Card Addendum: I've commented at length in the comments (below) about alternatives to the relatively expensive SD Card breakout board.  In short, the photos below show experiments I've done with spare parts on a breadboard, using the alternatives for the SD Card socket.  Please read the comments and related Instructables for more information.

As for the SD card itself, smaller is better!  The Arduino code provided works only with a FAT16 filesystem, and only reads files from the root directory.  That means you have a limit of 512 image files on the card, and the files are only 100 bytes.  A very small card will work fine, and a card larger than 2GB probably will not work at all.  There are FAT32 libraries for the ATMega328, but in the time I had, it was more work than it was worth to get it working with the Arduino.  (More later.)

Finally, use a variety of wires when wiring the PCB.  It will make it easier to trace connections.  As you will see, I used red, black, green, yellow, and white.  I wish I had more colors.

Regarding the 9-volt power supply:  A 9 volt battery will work, but you will have strange problems when it begins to diminish.  Once the battery voltage (when tested on a meter) drops below 7 volts your display may light up fine, but there will be insufficient current to power the Arduino and the behavior is somewhat unpredictable.  A 9 volt wall-wart works great, and the LM7805 on the BBB should be able to handle a 12-volt input, like that from an auto-adapter.  (Please use caution though if you put this in a moving vehicle!  You alone are responsible for what happens if you distract other drivers!  You might even want to consider wiring up an accelerometer and disable the displays when the unit is in motion.  The circuit is yours as is the responsibility.  I recommend it for a home Window or Desktop, or shop Window, not a moving vehicle!  I love the idea of it as a bumper sticker, but not at the risk of anyone's life or health!  In general however this should be much less distracting than most roadside digital signs, and many printed bumper stickers with hard to read text.)

I used the following tools to complete this project:
  • A quality, variable wattage soldering iron
  • Wire cutters
  • Wire strippers
  • A multimeter (helpful for testing)
  • A large solder-less breadboard, for testing - you may not need this
  • A Dremel, with cutting wheels and drill bits (for making openings in the enclosure case)
  • A variable speed drill and various drill bits
  • Arduino IDE 0017
  • My micro controller code (see Step 3)
  • GIMP image editor, or another editor capable of producing .xbm files
  • My xbmtodws code, to create image files for the SD card from .xbm files

Step 2: Assemble the BBB Arduino and USB BUB...

Follow the instructions provided by Modern Device to assemble the BBB Arduino.

When assembling the BBB, remember to use an LM7805 voltage regulator in place of the L4931CZ50LDO.  The smaller voltage regulator might work just fine, but we are pulling quite a bit of current to power up to 768 L.E.D.s.  The optional inductor is not needed for this project. You can follow the instructions on creating a solder bridge if you'd prefer to save the inductor, or if you'd rather not deal with the surface mount component. Nevertheless, it is not difficult to solder and I used it on my board.

If you also purchased the USB-BUB follow the assembly instructions to complete it.

When assembling the USB-BUB, I selected Configuration 2, though in practice I only ever use Configuration 1 (no jumper).

Step 3: Program Your Arduino...

BBB Jumpers:
Set the USB|EXT jumper on your BBB to the USB side so that we can program it using the USB-BUB without supplying an external power-supply.  (Or, supply a 9 volt power supply on the D.C. input jack and keep the jumper on the EXT side.)  When this step is completed you want to move the jumper back to the EXT side!

The other jumper with +5v|EXT|+V should be on the +5v side always.

FAT16 Library Installation:
Next, download the FAT16 library and the DigitalWindowSticker.pde file below.  The FAT16 library needs to be unzipped/untared into the hardware/libraries directory where your Arduino IDE is located.  On my Windows system, I keep the current version of the Arduino IDE in c:\temp\arduino-0017\.  Once the FAT16 library is in place there should be a set of files in [c:\temp\arduino-0017\\hardware\libraries\Fat16\.  The FAT16 library is also available here:  It is written by Bill Grieman.  A copy of this library that is known to work with the Digital Window Sticker is available in the files below (Fat16.tar.gz or

Arduino IDE:
Start the Arduino IDE.

Open the DigitalWindowSticker.pde file using the IDE.  There are two ways you can do this:

1) Download and open the file in a text editor, copy the contents to the clipboard, paste the contents into a new sketch in the Arduino IDE, and then save the sketch as DigitalWindowSticker.

2) Download the or DigitalWindowSticker.tar.gz file and extract the files to the directory containing your sketches.  Then open the DigitalWindowSticker sketch in the Arduino IDE.

Next, compile the sketch.  If there are any errors, make sure you are using version 0017 of the Arduino IDE, with the Atmega328 board selected (Arduino Duemilanove or Nano w/Atmega328).  Also make sure you've properly unpacked the FAT16 library, into the hardware/libraries directory, where other Arduino libraries reside.

Program the Arduino:
Plug-in the USB-BUB, and wait for for the drivers to be installed, or coach your system into loading the drivers. In the Arduino IDE, a new COM port should show up under Tools|Serial Port.  Select the new port for the USB-BUB.

Plug the USB-BUB into the BBB as shown in the photo in Step 2, and Upload the compiled code from the Arduino IDE.

Prepare for External Power Source:
Now that the Arduino is programmed, move the BBB jumper back to the EXT side (not the USB side) so that it will be powered by the external 9 volt source.

Step 4: Assemble the SD-MMC Card Breakout Board

Simply solder a set of header pins to the SD-MMC card breakout board.

  • Uses wires to connect the SD-MMC card breakout board directly to the printed circuit board in the next step.  Doing so will give you flexibility with where the SD card socket is located in your enclosure.
  • Solder a bare SD card socket to your selected printed circuit board as part of the next step.
Only the following pins are used:
  • CS (for SPI access to the SD Card)
  • DI (data input for SPI access to the SD Card)
  • VCC is the 3.3v power source for the card
  • GND is the common ground
  • DO is the data output, which can be connected directly to pin 12 of the Arduino
  • WP is used to detect a missing card.  This will be connected to pin 2 of the Arduino
  • COM needs to be connected to GND

Step 5: Build the Circuit

Use the schematic below as a reference as you build the circuit.  An Eagle schematic file is attached as well as a the image file Schematic.png. Use the photos below for hints. Remember that if you find it more convenient, you can use any of the gates on the 74HC4050. Just reference the datasheet.

About the Circuit:
The 74HC4050 is used to convert 5-volt signals sent from the Arduino to the 3.3 volts required by the SD card.  There are 6 buffers on the 74HC4050, only three are used by this circuit.  All inputs come from the Arduino, and the outputs go to the SD card.  The forth SPI connection runs directly from DO on the SD card to Arduino digital pin 12.  (The Arduino can read the lower voltage signals just fine.)

Some Arduino projects that use SD cards use a resistor network to drop the 5-volt signal to 3.3 volts. For me this didn't work well.  I found one SD card that worked and several that did not.  As soon as I hooked up the 74HC4050 all of my SD cards worked.

The SD card has an SPI mode.  We connect it to the Arduino SPI pins 10, 11, 12, and 13 through the 74HC4050.

The LM3940IT is a "1A Low Dropout Regulator for 5v to 3.3v Conversion".  It takes the 5-volt input from the BBB Arduino board and produces a steady 3.3v that powers both the 74HC4050 and the SD card.  Before starting I recommend marking the input pin on the LM3940 to distinguish it from the output pin while building the circuit.  The ground pin is in the middle.

The other "component" on the board is the shrouded box header used to connect the LED Display Matrices to the Arduino.  The 5-volt power from the BBB Arduino needs to be connected to the displays and to the input on the LM3940.  As you will see below, we use the power rail on the circuit board to carry ground on one side, and 3.3 volts on the other.  We will directly connect the BBB's 5 volt pin to the LM3940 and the shrouded box header for the LED displays.

Start by laying out the components on the circuit board.  If you intend to use the enclosure I've used, in the way I've used it, try to follow the layout in the photos below.  It doesn't have to be exact as long as all of the right connections are made, and nothing is connected that shouldn't be.  Be careful in planning where the DC jack and the header pins for the USB-BUB on the BBB, as well as the SD card socket will be physically located.  This will be important when you place it in the case.  If you use the same holes in the PCB that I used, you can get the same match, but beware that it took a fair amount of grinding and cutting to get it to work with the plastic enclosure.  Again, it works great, but clearly demonstrates that I am new to the Dremel.

After placing the parts on the printed circuit board, use a thin point Sharpie to mark the pin numbers/labels for the BBB connection and the pin numbers for the shrouded box header.  If you don't know where pin 1 is on the box header, attach a ribbon cable into the box header and a solid wire into the other end of the ribbon cable where the red wire lines up and use your meter to test for continuity.  You may also want to plug the ribbon cable into the LED display and check continuity between what you think is pin 1 on the box header, and what you think is pin 2, pin 15, and pin 16.  Then mark it on the PCB.  On top of the LED display are the pins from the shrouded box header soldered to it, one on each side.  This makes it very easy to match up your box header pins to those on the display.

One important note:  The shrouded box header I used has right angle connectors.  The printed circuit board doesn't have a way of allowing connections to each pin, because on each side of the board the pads are connected like they would be on a breadboard.  To solve I bent the pins of the right-angle box header so that one row pins would fit on each side of the breadboard gap on the board.  A photo below shows the bent pins.  The header sits on the board at angle, but it works great.  Be careful not to use too much force inserting it into the PCB -- don't use insertion force to get a better fit, or you run the risk of snapping the PCB in half (voice of experience).

Solder the Components:
Once you have things laid out on the board and have marked pin numbers it is time to solder each of the main components.  I recommend the following order:
  • The 16-pin DIP socket for the 74HC4050
  • The LM3940IT
  • The capacitors need for the 3.3 volt regulator (see next section below)
  • The SD card breakout board
  • The shrouded box header
  • The header pin receptacles for connecting the BBB
3.3 Volt Regulator Capacitors:
I elected to keep the capacitors for the 3.3 volt regulator as near as possible to the LM3940.  I use two 33µF capacitors between the ground pin and the output pin.  One is tantalum capacitor, the other is electrolytic.  To save cost, the tantalum capacitor does not require a high voltage rating.  6-volts is just under twice what should ever come out of the regulator and should suffice.  REMEMBER that both the electrolytic and the tantalum capacitors are polarized!  The long pin needs go into a pad connected to the output of the LM3940, and the short pin into a pad connected to the ground (middle pin) of the LM3940.  The leads are small enough that you can fit both in a single hole for each pin.

A .47µF tantalum capacitor goes between the ground pin (middle pin) on the LM3940 and its input pin.  This capacitor is also polarized.  Be sure the short pin goes into a pad connected to ground and the long pin into a pad connected to the +5v input pin.

The voltage regulator part of the circuit is now ready to be tied to power rails.

Placing the Wires:
Now comes the tedious part: running all of the wires.  The more colors of wire you have the easier this will be.  Try to keep the wires as direct and short as possible, and flat against the board to avoid clutter and enhance visual traceability.

Power rails:
Start by wiring all of the power connections.  I selected the rail behind the LM3940 for the 3.3-volt power line, and the rail on the other side of the board as ground.  Run one wire from the output pin of the LM3940 to the rail behind it.  Run another wire from the ground pin (middle pin) to the rail on the opposite side of the board.

Next connect the +5v input of the LM3940 to a pad connected to pin 12, 14, or 16 of the box header, and from another pad connected to that line of the box header, run a wire to the +5v line that will come from the BBB Arduino.  Pin 16 on the box header is used for +5v in the photos below. This will complete the voltage regulator portion of the circuit.

Now connect a black wire from pin 11, 13, or 15 of the box header to the ground rail.  Also connect the ground pin from the BBB to the ground rail.  Pin 15 of the box header is used for GND in the photos below.  This will complete the power connections for the LED displays and the sources from the BBB circuit.

Connect pin 15 of the box header to the COM pin on the SD-MMC card breakout board, and then connect the COM pin of the breakout board to pin 8 on the 16-pin DIP socket.  Also connect the GND pin of the SD-MMC card breakout board to the COM pin of the breakout board.  All connections to ground should now be complete.

To complete the power rails, connect pin 1 of the 16-pin DIP for the 74HC4050 to the 3.3 volt power rail.  Also connect the Vcc pin of the SD-MMC breakout board to the 3.3 volt power rail.

Wire-up the LED Displays to the Arduino:
Connect the following box header pins to Arduino (BBB) pins:
  • Pin 2 of the box header (CS2) to Digital Pin 5 on the Arduino BBB receptacle
  • Pin 1 of the box header (CS1) to Digital Pin 4 on the Arduino BBB receptacle
  • Pin 5 of the box header (WR) to Digital Pin 6 on the Arduino BBB receptacle
  • Pin 7 of the box header (DATA) to Digital Pin 7 on the Arduino BBB receptacle
The photos below show each connection.

Wire-up the SD-MMC card to the 74HC4050 and the Arduino:
First the easy one...  Connect the DO pin of the SD-MMC breakout board to Digital Pin 12 on the Arduino.

Next connect Pin 7 of the 16-pin DIP for the 74HC4050 (3A) to Digital Pin 13 on the Arduino BBB receptacle.  Then connect pin 6 of the 74HC4050 (3Y) to the CLK pin on the SD-MMC card.

Now connect Pin 9 of the 16-pin DIP for the 74HC4050 (4A) to Digital Pin 11 on the Arduino BBB receptacle.  Then connect pin 10 of the 74HC4050 (4Y) to the DI pin on the SD-MMC card.

Finally, connect Pin 11 of the 16-pin DIP for the 74HC4050 (5A) to Digital Pin 10 on the Arduino BBB receptacle.  Then connect pin 12 of the 74HC4050 (5Y) to the CS pin on the SD-MMC card.

Don't forget to insert the 74HC4050 into the DIP socket as shown in the photo below.

This completes the wiring needed to read files from the SD Card.

Hookup the Card Detect:
In order to be able to tell if a card is present in the SD socket, connect the CD pin on the SD-MMC breakout board to Arduino Digital Pin 2.

Connect the BBB to the header receptacle:
To finish the circuit connect the BBB to the header receptacle.  Be sure to align the pins so that they match the labels on our circuit board!  After the enclosure is properly prepared we will connect the ribbon cable from the LED displays, completing the circuit!

Step 6: The Enclosure

As mentioned previously, I am not overly talented with a Dremel.  I urge you to post suggestions on better ways of modifying the enclosure to hold the circuit.  Nevertheless, this is what I did:

Hack the Board:
Start by scoring each end of the Radio Shack Printed Circuit Board (well away from any copper traces), and use a pair of pliers to break away the unneeded side.  When you are done, the board should fit lengthwise against the 6-inch side of the enclosure.

Preping the LED Matrix Displays:
Each of the Display boards has a DIP-switch that controls whether or not the board responds to CS1, CS2, CS3, or CS4.  Make sure the board on the left side of the display (when it is facing outwards) has CS1 turned on, and all other switches off.  Make sure the right-board has CS2 turned on, with all other switches turned off.

Hack the Enclosure - Lid:
The lid of the enclosure is used to hold the LED displays together.  To do this, you need to cut a whole in the lid exactly the length and width of the two displays together.  I cut up a cardboard box exactly the size of the two LED displays, not counting the circuit board they are mounted to, or the other components on the board -- just the size of the LED cubes.  I then placed this on the inside of the lid and taped it in place with masking tape.  I used a box knife to repeatedly score the lid along the sides of the cardboard until the cutout was complete.  I little bit of follow-up shaving with the box knife provided a nice firm fit for the LED displays, with the rest of the board behind the plastic.

Next I put the LED displays in place and used a drill with a tiny bit (3/64) to drill holes through each of the screw holes on the display boards.  (4 per board, 8 total.)

I placed a 4-40 3/4" machine screw in each hole from the top of the lid.  On the inside I secured each screw with a 4-40 nut.  On the top screws I placed a second nut to provide a buffer equivalent in height to the transistors on the boards.

With this in place, each display was back into the lid, with the screws going through the screw holes, and another nut added to hold the boards in place.

Hack the Enclosure - Inside:
Now use some ingenious method (I used masking tape to mark approximate areas) to make slots on the side of the enclosure where the following items can be accessed:
  • The SD card socket
  • The DC power jack on the BBB
  • The USB-BUB pins for connecting the serial monitor to the BBB (for debugging, reprogramming, and simply because they need to protrude if the SD card is going to be accessible, due to my lack of engineering that part in advance. ;)
To do this, I used a Dremel with a cutting wheel.  The resulting slots are much larger than necessary, and not super straight.  I polished it a bit.  I also used a grinding wheel to remove some of the plastic inside the box so that the DC jack on the BBB board is flush against the outside edge of the enclosure.  I found that my DC input jack wouldn't go in far enough otherwise.  NOTE: The cutting wheel on the Dremel cuts, but it also melts the plastic.

I then placed the boards inside the bottom of the enclosure, aligned the DC jack and the SD card socket just where I thought they'd be suffciently accessible, and then used a hot glue gun to glue the board to the bottom of the enclosure.  I also added some hot glue around the DC jack to keep pressure off of the header receptacle when inserting the jack.  I placed a small amount of hot glue on the bottom of the PCB before placing it in the enclosure and quickly set it in place.  I then lined the entire edge of the PCB with hot glue, again, to keep it firmly in place when plugging in the DC jack or SD cards.

Attach the Cable and Lid:
We can now finally attach the ribbon cables that came with the display board.  The short cable should connect the two display boards to each other.  The longer cable can go into the other header box on either board.  (The bus is shared!)  The other end of the longer cable should be plugged into the header box on our printed circuit board.  Make sure you orient the cable correctly so the notch aligns.

Attach the lid to the enclosure and tighten the 4 corner screws.  The Digital Window Sticker is now complete.  If you remove the SD card and power the unit with a 9-volt DC supply through the BBB's DC jack, you should see a message on the display telling you to insert an SD card.

If you don't see the message it is time to pull out your multimeter and verify there are no shorts and that each connection is wired correctly according to the schematic.

Congratulations on your new Digital Window Sticker.  In the next step you'll see how to place images on the SD card.

Step 7: Creating and Displaying Images

This circuit reads files from the SD card and displays them on the LED display.  In order to accomplish this the following must be understood:
  • Your SD card must be formatted with a FAT16 file system.  This is the default for most older cards, and cards less than 2 GB.
  • FAT16 limits the number of files in the root directory to 512.  The micro controller is only programmed to read files from the root directory.
  • Files are read from 0.dws to 511.dws, sequentially.
  • When the micro controller reaches a file it can't read (say 10.dws after reading 9.dws) it will restart at 0.dws.
  • .dws files are bitmap files with the bits ordered in rows.  The first eight bits fills the first row of LEDs on the left-hand side of the display.  16-bits are required for one full row, and there are 48 rows.  (24-per display board.)
  • To create a .dws file, start with an XBM (x-bitmap) file and use my command-line program xbmtodws to convert the file.
The best cross-platform tool I've found for creating .xbm files in GIMP.  .xbm files are bitmap files that run from left to right.  Each byte represents eight black or white pixels.  The images below show how to create a Digital Window Sticker template in GIMP, and how to save files as .xbm files.

After creating the .xbm files you want to display, run them through xbmtodws.  Full source code is attached for xbmtodws.  It compiles on Windows with Visual Studio 2005, on Mac OS X with g++, and on Linux with g++.  There is a for examples of how to compile on linux, and a that shows how to build on Mac.

xbmtodws requires Boost 1.40.0 header files.  It uses Boost Spirit to parse the .xbm files, and Boost dynamic_bitset to simplify changing the bits from left-to-right, to top-to-bottom.

Pre-compiled versions of xbmtodws are included in the attached files ( and xbmtodws-1.0.tar.gz).  The Linux version is in xbmtodws\xbmtodws\linux.  The Mac version is in xbmtodws\xbmtodws\macosx.  The Windows (32-bit) version is in xbmtodws\release.

xbmtodws creates a 100-byte .dws file from each 16-by-48 pixel .xbm file.  96-bytes are pixel data, and 4 bytes contain time to display the image in milliseconds.

Converting a file called fred.xbm:

Windows: xbmtodws.exe fred.xbm
Linux/Mac: xbmtodws fred.xbm

By default the image will be displayed for 1 second (1000 milliseconds) .  To change the display time use the -delay nnnMilliseconds command-line argument.  For example, to show the image for 10 seconds use:
xbmtodws.exe fred.xbm -delay 10000

xbmtodws will create a new file called fred.dws.  To display this file, copy it to the root directory of the SD card and give it a numeric name with the .dws suffix (e.g. 0.dws).  Remember that if you leave a gap in the numbers, say you have files 0.dws, 1.dws, and 3.dws, only files 0 and 1 will display.  An error will be detected reading 2.dws and the microcontroller will start again at 0.dws.

Another option is to invert the image.  Use the -inverse flag to invert the image when the .dws file is created.

It is possible to create animations like those shows in the video on the Intro screen, by creating a sequence of images with small movements between frames and a short delay.

You now have complete instructions to create your own Digital Window Sticker.  Please post feedback showing how you use your Digital Window Sticker!
Arduino Contest

Second Prize in the
Arduino Contest

Be the First to Share


    • Stone Concrete Cement Contest

      Stone Concrete Cement Contest
    • Build a Tool Contest

      Build a Tool Contest
    • Digital Fabrication Student Design Challenge

      Digital Fabrication Student Design Challenge



    6 years ago

    can you please help with code to get this effect using DE-DP016?


    indeed great project;

    Tell me please: did you try using the 2416 in these apps:

    1- LED bar audio frequency analyzer

    2- LED oscilloscope

    3- 3D floating cube

    Any hints to do it?


    10 years ago on Introduction

    Great job , I really like the idea.
    It's fantastic.


    10 years ago on Step 7

    is it possible me building my own led display? is yes please post the schematics


    10 years ago on Introduction

    I truly like your instructable here. Unfortunately, I don't have as much time as I once did oh, these many decades ago, and I have an issue which may not belong here, but it seems related. And, my quest even has to do with a MAKE instructable that takes a Mattel "Radar Gun" and enhances it for use with real auto traffic down your street rather than it's intended "toy" aspect. I have that around here somewhere and when I was pondering that circuit, I had an issue about trying to make an output display, which would be readable like the ones towns and various jurisdictions have where they put a solar powered RADAR gun in "trouble spots (I live on a very major cut-through street many hundreds of cars use to avoid the more congested highway intersection a few blocks away and the City Counsel mad the oh-so-BOLD move some years back and dared the evil mongers by placing 25 MPH signs up on my street when what I was asking for was for them to drop a handful of the rubber mats to slow the traffic down, sigh. They may have as well put up a 2 MPH sign on my street as waste the $ on the signs and I'll wager the bumpers would have cost less, but such is city life.

    Well, I've thought of various things like getting the various colors of 'spray-down' parking lot marker paint all over my street to at least confuse those driving my into thinking there's something official going on and maybe they better slow down.

    My main problem is I don't want to make a halfway decent instructable and just have someone walking down the street give it a kick and rip off all my parts!!! With that, I've considered trying to come up with something which would work in conjunction with solar cells and separate batteries than my car battery and have signs/flashers, etc. inside my car. Of course, I'm sure I would get the occasional nut that thinks someone who would dare tell him/her what to do only deserves broken head/tail lights, windows, can opener down the length of my car, etc.

    I am a utiliti systems electrical engineer and our neighborhood is fed underground (dang in!), but if I just wanted to borrow a few pennies of the City's 208 V (or whatever they use - maybe 277) and power whatever I want with that AND keep it far enough off the ground to keep only the paint ball gunners and real zealots from getting to it.

    But, with that beside, There's the 'ol visibar cop cars have and when those come on, speeders suddenly become model citizens instantly.

    I don't know if you have ever seen that artist who, with sidewalk chalk makes the most amazing 3-D looking images when the viewer stands in one particular place. He can make a flat sidewalk look like he's crawling into a deep dark cave or whatever. But, even if I could afford him and put permanent pigments on both ends of my street, people would figure that out also pretty quickly, but filming their faces would be priceless.

    In keeping with my desire that I keep things inside some kind of enclosure, or out of reach, I could go with something like the IR critter-cam setups that sense motion and snap a photo of something. But, if I put that near the ground, Gone it will be.

    So, anyone have inexpensive ideas for a citizen to try to slow the traffic down on his street all by himself. It's not that my neighbors don't agree with me, it's just more they have other things to do, so I'm a committee of ONE. I do have an over-riding neighborhood association, but I think I would rather go to the City Counsel than deal with them sometimes. Of course none of you have ever been part of a small group and had ANY kind of disagreements on anything, have you? *grin*

    All ideas are welcome short of breaking the law. Which does remind me of the two Austin late Teens who pretty much shut down the City of Boston, in the Commonwealth of Massachusetts several years ago with their little magnetic gadgets that were supposed to look like The Cartoon Network critter and planted them all over the country. If I had known they were going to put those things up, I would have tried to join them in order to get one of those!! God, I loved that.

    Some years later, it was obvious the same programmer got hold of one of our TXDOT temp signs and re-programmed it, instead of something like "EXPECT ROAD DELAYS" TO "WARNING, ZOMBIES AHEAD."

    i THINHK THE Cartoon Network, part of Ted Turner's "Empire along with Time Warner just wrote Boston a check for the alleged $0.333 million it supposedly cost Boston to react to their little LED gizmos designed to be put up into metal bridge pieces, so they would be hard to get down, yet advertise for "Adult Swim"

    I don't want to go quite that far, and I've read physiological studies that something as simple perpendicular white stripes on a road slow people down because they are trying to figure out why the lines are there, so, with the possible threat of DPS, local cops, etc., they will drop below the speed limit to try to figure out what's going on.

    But, that's far too blase' for me. I don't want to get a 1 kW pulsed laser and shoot them in the face (well, maybe sometimes after they've almost run over my kind), or make them swerve into several cars parked on the street, I just want to get their attention long enough to get them to slow down a bit.

    If this is the wrong place for this, I would greatly appreciate anyone putting my quest in the proper forum


    ElctroKV in Austin, TX


    First of all great project als_liahona. Unfortunately it looks like SURE ELECTRONICS rev'd the display board and changed the write progression. Your code appears to assume that the first byte written is in the first column in the upper left corner of the display and works its way right. This seems like the logical progression. Now the first byte starts in the 8th column and works its way to the 1st then jumps to the 16th column works left to 9th then to the 24th, etc, etc. I have attached two photos. One using your code and a second where I flipped the bytes to the new progression. 

    I can not believe SURE changed the display to this write progression. I looked at the PDF manual for the RED and GREEN LED displays and they both seem to have this progression now.   I'm trying to decide if I should include the code to rearrange the bits in the Arduino, or externally rearrange the bits before writing to the SD card. If I fix the code in the Arduino, I'll send you a copy to post.


    Reply 11 years ago on Introduction

    hai this is goo d idea just know how can get i like to buy just mail the deatails to


    Reply 11 years ago on Introduction

    I think the autor of this instructable did a good job of explaining where to purchase the items necessary as well as documenting the process. You should read the instructable if you want to make your own.


    Reply 12 years ago on Introduction


    Here is code you can use to fix the bit swapping on the SURE 16x24 LED display boards (My board is REV 1.1 of the green LED board). To fix for the bit swapping issue simply replace the DisplayBuffer() function of the Digital Window Sticker code with the following:

      void DisplayBuffer(const unsigned char *pucData192, bool bReverse=false)
      // pucData192 must by 192 bytes!
        unsigned char sucData192[192];  // Register for swapped data
        for(int j = 0; j < 8; j++)
           for(int i = 0; i < 8; i++)
              *(sucData192+((j*16)+(2*i))) = *(pucData192+((j*16)+14-(2*i)));
              *(sucData192+((j*16)+(2*i)+1)) = *(pucData192+((j*16)+15-(2*i)));
        // Data swapped, display swapped data
        DisplayBufferOnSide(sucData192, m_iCS1Pin, bReverse);
        DisplayBufferOnSide(sucData192+48, m_iCS2Pin, bReverse);   


    Reply 12 years ago on Introduction

    dirty_valentine:  Thanks much for posting this for those with the newer displays from Sure Electronics.  While this isn't much code, it is a lot of moves (or more likely mov's).  If anyone wants to avoid this, or is worried about the display speed (probably not an issue in reality), you can change the image conversion tool (xbmtodws) to do this instead of changing the Arduino code.  We could even add a command-line flag to support the older displays.  In fact, if Sure Electronics wants to send me a new set of displays, I'll make the change and post the code changes for xbmtodws.  I'm not going to buy a new set though, since I think they screwed this one up!

    Thanks again for posting your fix dirty_valentine.


    Reply 12 years ago on Introduction

    No problem. I have other Arduino software manipulation I want to do to the pictures. Conseptually it is easier to do with your version of the data rather than the swapped version. For example, scrolling your data across the board is straight forward, but scrolling the swapped data is not. It was a real brain tease just to figure how to perform the swap. Admitedly it is a number of swaps and an additional register, but I think I have the space and time to let the Arduino do the work.


    Reply 12 years ago on Introduction

    The more I look at your diagram/image, the more I think SURE must have messed up.  It is not intuitive at all.  I'd challenge them on it, but communication was a problem last time around.  Thanks again for pointing this out.


    Reply 12 years ago on Introduction

    I might ping SURE on this but I'm not sure it will do any good. I think SURE screwed up and swapped column bits on the display when they rev'd the board, though it's possible that SURE bought a different 8x8 LED display that has the column pins swapped. As a person who designs ICs I can not imaging making a mistake like this and not fixing it. At $12 a board the margins have to be thin so if SURE made a bunch of PCBs before finding this mistake they probably fixed the problem with toner and changed their datasheet rather than throwing out the boards. The question is will they change it back on the next rev or is this screwed up writing pattern permanent.


    Reply 12 years ago on Introduction

    Wow, that is amazingly messed up.  Thank you for pointing this out to readers!  Did you end up changing the xbmtodws code, or the Arduino code?  If you don't mind, please post the diff.  When I feel like I can afford another shopping trip at SURE I'll consider getting a new set.  The green looks nice.  I am sorry though to hear they changed the interface.  If a software guy does that we never hear the end of it!


    Reply 12 years ago on Introduction

    I just laboriously swapped the actual matrix bits for displaying NoCard. I have not actually edited the Class function or changed the xbmtodws code to do the swap for me yet. Thinking about it last night I think I'm going to edit the Class code for Arduino. It will make the program a little bigger but the display data will be more intuitive. I will post the new DWS Arduino code when I get around to fixing it. It might take a little while because I'm new to Arduino and I have not done a lot of programming in C. I've been working with PICs in assembly mostly. I finally decided to bite the bullet and learn to program micros in C because assembly is incredibly laborious.

    12 years ago on Introduction

     So, got a few questions for you, als_liahona. I really haven't gotten around to pulling apart the sketch yet, so I hope I'm not missing anything too obvious.  Can more then two 2416 matrices be used in tandem?  Such as a 2*4 array?  Also, I've noticed you have a message for "Insert SD Card".  Is that image stored on the Arduino itself?  Does the code support standard text that can be linked directly to the output? eg: matrixWrite("I'm sample text")  One more –– Would it be possible to use image sprites? (one physical image consisting of two or more sections that can be broken up by positioning)  Ok, I lied, another one:  if text is not supported, is there a better way to provide a countdown timer?

    Thanks in advance!!!


    Reply 12 years ago on Introduction

    Yes, I believe you can chain up to 4 24x16 displays.  You would have to change the Arduino code to support this, but it shouldn't be difficult.  You can see in the class I created that it handles each display separately.

    I elected to only draw images to the DWS, but there is plenty of code out there on the Internet showing how to write characters to a 2416 display.  The easiest thing is to create inline bitmaps for each character and then write a simple function for outputting them.  I like using images, because I can use different fonts and effects.  It is a lot of work making scrolling text one image at a time, but there is a lot more flexibility.  I've done it several times.

    A countdown timer should be fairly easy, especially if all you need is numbers.  You can use images, or you can write code to produce the digits.  Changing code to do a countdown would be very easy.

    The "Insert SD Card" image is stored in the arduino as part of the code.  It is a static global used when needed.  The code is sufficiently small that you can get several of these images compiled in and still fit easily on an ATMega 328.

    I hope that helps.


    12 years ago on Step 1

    Another suggestion...  If anyone is looking to save money on this, the SD Card breakout board is way too expensive.  Here are some alternatives that I will try for future products:

    1) Build your own socket following this instructable:  This is a great idea from Kroden.

    2) Use an Floppy drive cable as shown in this instuctable -- you could use another DIP socket like that shown above for the other end of the cable:

    3) Use a variation on 1 or 2 where you actually solder the pins directly to an Micro or Mini SD Card Adapter, and mount the Adapter in your enclosure.  At roughly $2 a piece, it is much less expensive than the socket for something like this where you aren't going to be inserting and removing the card all that often.

    Again, I hope that helps...  It would be nice if the Arduino SD card shields out there were affordable AND didn't use resistor networks (that produce lacking results) to convert the 5v signals to 3.3v.  Maybe I'll put a board together that includes the 74HC4050 and a 3.3v regulator...  Any potential buyers to make it worth the effort?