Bigger is better: Build an Arduino-powered monster scrolling LED sign for about $15 a foot


Would you do with a massive full color animated LED display? How about…

  • Read your Tweets in giant 140 char gulps from a block away
  • Add English sub-titles to the Eiffel Tower
  • Display a live-updating, 45 digit long countdown of the number of atoms left in the known universe

What if you could build the display however long you needed it, for only about $15/foot?

What if it was really easy to build and used everyone’s favorite low cost micro-controller so you could easily change the software to do whatever you wanted?

Well you can! Read on for details and perfunctory video!

Perfunctory video….

Build One

My sign is 12 feet long with 2,688 RGB pixels. It can display scrolling text at 80 frames per second. You can make your sign as long or short as you like.



(Click on pics to zoom)

The build is so simple, that you should be able to figure it out from looking at the pictures. Stick the strips to something, add some power, connect the Arduino data out pins to the strips’ data in pins.

The secret sauce is in the software. You can read about the parallel processing technique used here.

Code Drop

Simple text scroller


Here is a very short and simple Arduino Sketch to get you started….

It will scroll Jabberwocky across any WS2812B Neopixel strips attached to digital pins 1-7.  The code is clean and should be easy to understand and modify.

Full blown multi-effect demo


Once you get bored of Lewis Carroll, try the full demo to get some ideas on how to do fancy effects like…

  • Multi-color
  • Custom fonts
  • Gamma correction
  • Sprite graphics with animation

So much is possible, and it is super fun to find a use for all your old-school demo scene hacks!


Q: Wait, how are you driving this huge display from an Arduino? How do you fit a 8,064 byte buffer into only 1k of RAM?

Do not try to fit all the pixels into a buffer. That would be impossible. Instead, generate the pixels (and, in fact, the individual bits of the bytes of the pixels) on the fly the moment they are transmitted to the LEDs.

That’s kinda the whole point of the project.

You can read more about it here. Now you can drive an infinite length of pixels with a finite (and and extremely small) amount of RAM.

Q: Why do you keep whining about how bright it is? We get it!

Seriously, dude, you do not understand how bright this monster is until you see it in person. The “All Your Base” display has given every member of my family a migraine at least once when they accidentally glanced at it. Get yourself a pair of gas welding googles and some SPF45 sunscreen if you plan on building one of these. Once it is built, you can always crank down the brightness and/or mount it far away from humans.

Q: What is your sign made of?

I used a few a strips of plywood with a couple of aluminum angles glued to the top and bottom to make it more rigid and look nicer…

2016-05-03 16.10.512016-05-03 17.14.172016-05-03 17.21.492016-05-11 13.27.382016-05-11 16.22.38

(click to zoom)

But you can use anything that you can stick LED strips to. If you are going for cheap and easy, 7 strips fit almost perfectly onto a 2×4…

2016-05-11 15.16.39

Walls, I-beams, Airstream trailers, suspension bridges… would all work great too!

Q: Where does the $15/foot come from?

The majority of the cost for a big sign comes from the LED strips. The 60 LED/meter strips regularly sell for $5/meter. The display is 7 strips high, so the strip cost comes out to about $11/foot.

The other variable costs are power and structure.

300 Watt supply can drive a 15 feet of display, for a cost of about $1.70/foot.

A top-of-the-line 2×4 costs about $1/foot – or you can stick the strips to an existing structure for free.

Finally, you will need one Arduino per sign, and the Pro Mini goes for $3-$15 a pop depending on how long you are willing to wait for it to arrive.

Q: Couldn’t you just connect all the strips end-to-end and drive them with a single pin?

Yes, but it would more than 7x slower. That is a huge difference visually.

The code for driving the serpentine pattern bit-by-bit would also be much hairier and less efficient.

Q: Couldn’t you just use a BeagleBone and drive the strips in parallel using ledSCAPE on the PRU? 

This works great, but a BeagleBone costs at least $40 (more often $55), runs complicated and vindictive Linux, outputs 3.3 volts, and it not as widely known and loved as the humble Arduino.

You can get a Arduino Pro Mini for about $5, connect the led strips directly to the 5 volt pins, and have a running sign as quickly as you can download the sketch (2 seconds)!

Q: Will this run on on other boards besides Arduino Uno?

It should work on any board that…

  1. Uses any 8-bit AVR
  2. Has at least 7 pins connected to a single port
  3. Runs at 16Mhz

This includes the Arduino Pro Micro, which is particularly well suited and super cheap.

Q: How big a power supply do I need?

That depends on how long a sign you want to build and what brightness/color/content you want to display.

In the worst case, if you are turning on every pixel with full brightness white, you need about 0.25 watts per pixel. But you would never want to do that because it would incinerate all nearby life.

Normal text only has about 20% of the pixels on at any given moment, and 50% bright white is looks almost nearly as bright as 100% but uses half the power.

Switching from white to colors can drop power by 2/3rds, and a dim red text display can use so little power that a 10′ long sign can run off a USB port.

Q: What is the longest sign I can make?

The limiting factors are…

  1. Power. You need a big enough supply.
  2. Voltage drop. You need to be able to get enough voltage to the pixels that are farthest away from the power supply connections. These will typically be to ones on the middle of the display if the power connections are on the ends.
  3. Refresh rate. It takes about 25us per column to refresh the display, so the longer it gets, the slower your frame rate will be.
  4. Physical constraints. Can you get it down your stairs? Can you find something that long that wont break when you pick it up?

I made my sign only 12′ long because is the longest thing that can make it down my stairs. 400 pixels long also gives 80 frames per second refresh rate, which is just fast enough for nice animations.

I’d love to make a 100 foot long sign if you can find me a long enough surface to mount it on, and tell me what it should say!

Q: Why did you use 96 Pixel/Meter strips rather than 60 Pixel/Meter?

Because I had a bunch left over from another project, and they happen to look very nice. But 60 Pixel/meter strips also look nice and are much cheaper.

Q: Where can I get really, really long strips?

The longest strips I’ve seen for sale are only 5 meters long and the cheapest are typically 1 meter long, so I splice them together.

Q: How do you splice them?

I made a simple jig to keep everything perfectly aligned and at the correct pitch while I solder away…

2016-05-11 13.17.41

Q: Why did you only use 7 of the bits? Why not make the sign a full 8 rows tall?

  1. I had a nice 7 pixel font sitting on my desk from a recent project and didn’t want to waste time making/finding/converting an 8 pixel high font.
  2. I wanted to keep the RX pin (Digital Pin #0 on the UNO) free so that the sign could be driven by sending serial data from a laptop connected to the Uno.
  3. I cut the plywood infill just ever so slightly too narrow to fit 8 strips. That’s why there is a blue margin above and below the strips.

Q: Can I get the schematic and gerbers for the custom PCB?

That’s just a crappy Radio Shack perf board to hold the wires together and make something that I could plug and unplug. It has no parts. If you were using an Arduino Pro Mini, you could solder the data wires directly into the board and then twist the power wires together with a wire nut.

2016-05-13 22.30.262016-05-13 22.30.35

Q: How can I slow down the scrolling speed?

Like this…

Higher numbers, slower scrolling.

Q: I want to build a sign that is 14 pixels high, can I just wire the inputs for each set of two strings to one output pin?

Sure thing! Or groups of three for a 21 pixel tell display!

But your display is going to look blocky because you have not increased the vertical resolution.  It would be possible to drive a taller display using more pins and higher resolution, it would take a little work – mostly making a taller font.



  1. Giuseppe Cusmai

    Thanks! That’s a good idea. I’ll use the cheaper 60/meter and space the strips to get a square grid. I didn’t know of the 96/meter variant.

    • Tom Hammond

      Hi Giuseppe,

      I noticed in your Q&A section that it is possible to support taller displays (more than 7 rows). I would like to build a display 12 rows tall. I assume that requires 12 data pins on the Arduino. Can you provide a quick overview of how the code needs changed to support 12 rows?


      • bigjosh2

        To support more than 8 rows would significant software changes. Probably the easiest way would be to break the pins into two sets of less than 8 pins each, each on it own PORT. Then duplicate the existing code and modify the second copy to access the second PORT. Then update the two sets of pins in sequence for each new frame. This will obviously slow down frame rate, but not necessarily by 50% since you can update one set while the other is in the reset delay.

        • Tom Hammond

          Thanks for the advice about using more than 7 rows, either duplicating the code and using two PORTs or using two Arduinos. If I get around to trying this out, I will let you know how it turns out!

  2. abera

    Thanks for sharing,for me worked perfect at first try.i connected 2 ws2812b 60 rgb leds per meter to 1 Arduino pin,so it is 14 rows by 60 colomuns.And to slow down the speed of scolling i increased the #define pixels 964 to 1988 for i do not know how to set the speed in the program and it works question is how to send data from serial monitor to the rgb pixels?can any one help me.Thanks a lot.

  3. Ali

    Hi Josh- just wanted to say thanks so much for posting this awesome guide and developing the code that makes it work. I used your guide to make an LED sign which I am putting inside a replica Mouse Droid from Star Wars, which I am designing and building. I am making a video series on this and can post the link if you want to see it in action.

    Thanks again!

          • Ali

            Thanks! Adding the bluetooth wasn’t so bad. The two bumps in the road were: – Figuring out about using a common ground for the LED strips and the Arduino, which I found out about in these comments.
            – With an HC-05 bluetooth module, you can’t use serial output (e.g. for debugging) or Pin1 of the LEDs won’t work.

          • Chris Eaton

            Hi Ali/Josh,

            I would be very interested in seeing the code for the Bluetooth.
            I would also be very interested in finding out if anyone else has any code to allow me to upload a single line of message from a Webpage.

            I am very new to Arduino programming and I am finding it a bit of an uphill struggle.
            Perhaps deciding to create a message display as my first real project (apart from driving 3 ordinary LEDs to create a traffic light sequence!) was probably a step too far. However, I have created a 0.7 meter display using 60LEDs/m strip and i have found that i can drive my messages straight from the Arduino just powered from a small USB Phone power supply.

            The first issue I encountered was setting the length of my display (0.7) and the number of LED’s/m (60) and changing this in your MacroMarquee code caused the display to become a complete blur. Clearly it was too fast. I couldn’t work out from your code/comments where i should go to vary the speed of the text for a small display. At first i tried to increase the “length of display” setting to something ridiculous like 30m and this DID slow it down.

            Then I looked further down and put a Delay in the for Loop at the bottom after the sei() command. This works, but i wonder if this is the correct place to do it.
            Josh, i cannot find a variable anywhere in your comments that mentions Scroll speed. The only mention of a Delay seems to be here:

            delayMicroseconds( (RES / 1000UL) + 1);
            I played with it a little, but the display went a bit “funny” so i put it back again.

            Is there anywhere where i SHOULD set the scroll speed?

            I am also looking to be able to set the color of a line of text as a variable too.
            Perhaps i should do this in the bottom sendString command, replacing the three Hex numbers with variables?
            sendString( m , step , 0x00, 0x00 , 0x40 ); // Nice and not-too-bright blue hue

            Any help would be appreciated.

            Chris Eaton

  4. Ralph Richardson

    Josh, I built a 1 meter version of your sign with a different scrolling text.
    I would like to change the color of the scrolling text while it is scrolling.
    How would I do that ?
    Thanks , Ralph

    • bigjosh2

      If you look at the code, the sendRowRGB() function sends a row of pixels out the LEDs with any pixel that is on in the font set to the specified RGB color. You can Send any color you want here, so you can change colors for the whole display or even just one row at any time. Do yuo want the whole display to change to different colors, or just parts of the scrolling message?

      • Ralph Richardson

        I would like a set of words to change color like( Merry Christmas) as a set then have that change to a different color the next time it scrolls by, doing that several times.

  5. I SADEK

    very nice work their i am trying to do something like this it work fine with 7 or 8 rows
    but i am tying to do 11 row
    i discovered their is group for the arduino pins B C D
    wold you please give me any hint how to use multi group in you code
    i would be very grateful

    • bigjosh2

      You could potentially use the 6 pins of PORTC or PORTB…

      (PORTB is nicer I think because the pins are right above the PORTD pins on an Arduino Uno).

      To do this, you’d need to copy all my code that uses PORTD and make a new copy that uses PORTB. Then you would have to make a font that uses all these rows but you would lay it out as two fonts – one for the bottom of the letters on PORTD and the other for the top on PORTB. Then for each time you send data to the LED strings, you’d actually send twice – one font to PORTB and one to PORTD. That’s it! Conceptually easy, but a bit of footwork to get it working (hardest part making the font, the rest is glorified copy/paste with search/replace).

        • bigjosh2

          Look at how the existing code does the single font of 7 rows. Now just imagine that you had two arduinos, each connected ti 7 strings of LEDs and those 14 strings are visually placed so the second 7 are placed above the first 7. Now imagine the font you’d make for the bottom arduino – it would be the bottom 7 rows of 14 row high letters. The top arduino’s font would similarly be the top 7 rows.

          Now imagine that instead of two ardunos, you only have one arduino, but the top strings are connected to one PORT and the bottom strings connected to the other PORT. See how that font might look?

  6. I SADEK

    good day to you sir i am very sorry but i have on question
    i finally managed to use all 11 row of my matrix but the i cant separate the top last 3 row from the first bottom rows
    it send exactly first 3 bit of first PORTD to PORTB
    can you tell me whats wrong with the code

  7. Nomis

    Noob question; if I wanted my sign to have a larger font (ie, be readable from farther away), I could simply use 60 pixel/meter strips instead of the 96, right? If I adjusted the vertical spacing accordingly, the result would still be a 7 row font, but it would just be a larger sign, correct?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.