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

DSC_1381

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.

DSC_1404_052016_115931_AM

DSC_1403_052016_120359_PM

(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

ezgif-122169061

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

https://github.com/bigjosh/MacroMarquee/blob/master/Arduino/SimpleScroll/SimpleScroll.ino

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

DSC_1365

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

https://github.com/bigjosh/MacroMarquee

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

FAQ

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…

https://github.com/bigjosh/MacroMarquee/blob/slower/Arduino/SimpleScroll/SimpleScroll.ino#L395

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.

###

322 comments

  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?

      Thanks!
      Tom

      • 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 perfect.my 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

          • 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.

              Regards
              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.
        Ralph

  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?

  8. People's driver

    Hi Josh,
    I have build two displays for testing, one 1m long 8 rows nano pro mini board with 60/m ws2812b leds and one 5m long 7 rows with 30/m ws2811 leds.For the second one I had to modify the code to work, but everything works perfect.
    Now I’m trying to change the font for the first one to work with all 8 rows and for the second one to change the font to look better, because of the 3 leds per pixel of the stip.
    Please advice me on this as I’m new to Arduino programming and If you could give me an example of code for the Twitter Feed to be displayed would pe amazing.
    I can post some pics and videos of my testings.
    Thank you

  9. Dat-Data

    Greetings! I’m looking to build a sign myself with a different board:
    https://docs.particle.io/datasheets/wi-fi/photon-datasheet/

    Since this is my first project like this and I’m having a little difficulty wrapping my head around the pin/port setup and how it’s used in your SimpleScroll.ino. What is the best way to determine if the board I’m attempting to use has “Has at least 7 pins connected to a single port” and how adaptable is the SimpleScroll.ino to other boards?

    Thanks in advanced!

    • bigjosh2

      Sorry, the particle uses an ARM chip so it is totally different than the AVR chip I use here.

      You may be able to drive neopixel with this ARM chip, but not using anything like my code. You’d have to find something that works specifically for that chip (or at least that kind of chip).

      Note that the TEENSY boards use ARM chips and have very nice libraries for driving lots of neopixels!

      • Dat-Data

        Thanks for the reply, much appreciated!

        I went with the Ardunio Uno Wifi Rev2 as my project relies on communicating with an API. In attempting to compile the the SimpleScroll.ino it keeps failing due to an “impossible constraint in ‘asm'” error. Is there a library I’m missing or could this be due to the board itself?

        • bigjosh2

          Unfortunately despite the promising very similar sounding name, a Ardunio Uno Wifi Rev2 is a totally different beast than an Arduino Uno. They have different chips with different pins and different capabilities. While I bet you could get this code to work on the chip inside the Ardunio Uno Wifi Rev2, it wouuld take some work. If you want to use this code then I could get a real trusty normal boring Uno. If you need to communicate with things on the internet, probably the best strategy would be to plug the Uno into the USB power of somethign like a computer or a Raspberry pi and have that do the internetting for you.

          • Dat-Data

            Just wanted to provide an update, the Arduino ultimately did not fulfill my needs so I took a chance on a Particle Photon board and I’m happy with the results.

            The Particle photon is scrolling text across 8 strips @ 141 LEDs each using the Adafruit_NeoMatrix library, all running off of one pin. The LED board itself is about 7ft long and currently has three different messages scrolling across:

            Message of the day – This text can be updated via our team’s slack channel, I added a function on the Photon to handle new text entries
            Systems Check – There is a nodejs server I have running that performs a check on multiple systems to determine whether something is down and call the Photon with the “All good” if everything is running or a list of systems that are down if any
            Forecast – The Photon board will call a hourly weather api every 30 minutes to get the current temperature and forecast

            We already have request from other teams to be able to post messages to the board on a regular basis so I might need to add some more slack commands but that’s a good problem to have in my book. Thanks again for the article, without it my team would not have made what we have now!

  10. Dylan L Coiro

    Hi Josh,

    I’m also working on this for a school project, I’m trying to display information that would be displayed parallel to a moving conveyor belt. I’m fairly inexperienced with arduino and was wondering if you could provide and more detailed pictures/instructions on the wiring?

    Once I have it wired up, I also want to modify the speed…I saw that another commenter wanted to do the same thing and was simply changing the definePixels value. Is there a more direct way to change the speed to (through trial and error) have it match up with a constant known speed of a conveyor belt?

    Thank you

    Dylan Coiro

    • bigjosh2

      If the speed of the belt is constant, then you could an Arduino hardware timer to have the message advance one pixel forward each time the belt moves the equivalent distance. Is the belt speed constant and predicable?

      • Dylan Coiro

        Thank you for getting back to me. Yes the belt speed is constant (10 inches/second).

        Also we have it displaying the text of Jaberwocky, but the letters are mirrored, do you know why this might be?

        • bigjosh2

          the letters are mirrored, do you know why this might be?

          Something is both backwards and upside down. You can fix this by switching any two directions in hardware and/or software. For a hardware-only fix you could, say, reverse the order that strips are connected and then flip the sign upside down. Or you could turn the side upside down and reverse the order of the scrolling columns. Any combination of two flips will fix it! See why?

        • bigjosh2

          Yes the belt speed is constant (10 inches/second).

          If you want a quick and easy hack, you could just experiment with changing the delay() between steps in the loop() function (that is, after the sednString() until you get close enough (high numbers=slower scrolling). If you want to get fancy, you could put some kind of sensor to read the movement of the belt and connect that to the Arduino and have it automatically adjust to whatever the belt speed is.

  11. dave

    Hi Josh
    Awsome project, I have got simple scroll working and added sd card into void setup which compiled/uploaded and gave the output on the serial monitor of a sample.txt residing on the connected sd card, I could not get it to output onto the leds, I couldnt seem to get the void loop right possibly but I,m no expert on coding, any suggestions ? Thanks Dave

    • bigjosh2

      This project is specifically only for WS2813B/Neopixel LED strips. There is no way to individually control 5050 SMD LEDs on most strips. Sorry!

  12. Kirk M

    So, how did you get the audio coordinated with scrolling letters? This part is particularly of interest for my son…

    • bigjosh2

      You could use something like this microphone connected to unused pin on the Arduino to “hear” the sound. Depending on what the sound actually sounds like, it can be difficult to actually figure out where the beats are – but it it is something simple like a clapping hand with silence in between then should be no problem.

  13. Gijs

    Hi Josh,
    Was just testing the simpe setup (which I love btw) with GS8208 led strips. That does not really work very well. The jabberwocky text gets scrambled. Seems like a timing issue. GS8208 should be the same timing etc as WS2813.
    Also tested MacroMarquee, The big texts were holding up better/good but the scrolling text is garbled beyond recognition.
    Any ideas?
    Thanks,
    Gijs

    • bigjosh2

      Looking at the datasheets, I think the timing for the GS8208 might be different enough that you would need need to adjust this code. Maybe try increasing the reset time length or fiddling with the high and low bit times and report back if you get it working!

  14. Bart Vandersarren

    Hi,
    I love this setup!
    I’m new to arduino, but i will get me some electronics to get started on this project,

    Can you make this multiple lines as well? To make the kind of display you often see in cities, to display information.
    Like say, 5 lines, and 20 chars per line.

    Thanks!

    • bigjosh2

      The easiest way to make multiple lines is to make multiple signs! The additional cost is just an extra Arduino per sign, which can be <$5 if you use a full board or <$1 if you just use the chip directly. THis way you will be able to keep up high frame update rates no matter how many lines you have.

      • Bart Vandersarren

        still waiting on my hardware to arrive, getting impatient to start :-)

        but if i were to chop up the big line (120 pixels) , and put 5 segments on top of each other , I would get almost the same thing?
        or will the voltage drop be an issue over an extension cord?

        also in this setup, would I be able to have some basic animations spread over this new 35×120 “matrix”?

        another idea was to place “flipped” lines between the character lines, in order to avoid long connecting cables and create a better matrix (63×120), but then you would have the first 7 lines going left, the next 7 going right, and so on

        I hope I described this well, being not native english :-)

        • bigjosh2

          If you only need 120 pixels long than you could “fold” the display into 5 short 24 pixel lines. If you want to save wire you could “double back” where every other line is backwards, but then you would need to update the code to correctly generate the alternating forwards and backwards lines. Not hard, but you would have to do it.

  15. Robin

    Hi, I’m a teacher from The Netherlands and I’m using this project in my lessons where 1 team of students is making this board in a 1.2 meter version. But we want to also be able to print the Euro symbol: €. This is not possible in the code yet, but how can we create a euro symbol?

    Thanks!

  16. Jon Beverley

    Hi Josh. Great project! I’m wondering if you have any suggestions on how to update the text that the sign says over usb rather than having it hard coded. Does the fact that we are using pin 1 (Tx) make this impossible?

  17. abera

    Hi Josh,
    I tried displaying other signs with the 57 font and i succeeded .But the signs i want to display require more places so i changed the font to 77 and made minor changes in the code such as font_width to 7 and uint8_Font to 77 but did not work.What do i have to change in the code to make it work with 77 font?
    Best regards.

  18. Paul G

    Hi Josh,
    I was able to complete your project and even have two of them running in my lab. My next focus is trying to create “mini” versions of your boards that run vertically and have characters only 4 LEDs in width. You mentioned earlier that it was possible to run the LEDs using an Arduino pro micro but I was wondering what you would need to change for it to work. Port outputs? Font?

    Thank you and awesome project!
    -Paul

  19. Jonnnas

    Hi Josh Awesome project!
    I will conduct the same type of project using Arduino Due and Neopixel SK6812RGBW 60/m LED strips.

    Have anyone got it working with above mentioned LED strips?

    I know http://dntruong.wordpress.com/ have worked on building FAB_LED library compatible with SK6812.
    Reading the comments on your earlier blog post about Neopixel stips https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/ I realize the timing is same for WS2812 and SK6812, so that’s why i wonder if this code works with SK6812?

    • bigjosh2

      The code in this article will not work directly with the SK6812 because that chip needs an extra byte for each pixel to indicate the white value. That said, they are very similar to the WS2812B protocol so it would not be hard to make the changes so support them.

  20. littlehole

    Hi Josh! I’m a student from Italy and I have to create a led scrolling text. I’m pretty new to Arduino, so I need a bit of help. I would buy 7 pieces of ws2812b led panels 8×32, to create a 1792 pixel ledboard (so less than yours). The question is: which Arduino I would need? The UNO rev 3 it could be okay? because from the pics it seems that you used the UNO, but then you suggested to use the PRO MINI. So which could be better for me? And about the power supply, is 240 enough? And how can I calculate how many watt I will need? thank you in advance

    • bigjosh2

      You will likely run into some headaches trying to use 8×32 panels with this code since it is very specifically written to stream out the data one column at a time, whist the panels are typically laid out in a snake pattern. While it might be possible to change the code to generate the data in this pattern, it would be complicated.

  21. Afik Cohen

    This thread just showed up in my email again, and I remembered that I want to give some love and share my project that I built with the help of this article, josh, and other commenters here <3

    View at Medium.com

    It’s since grown to a festival art piece that I’ve taken to two EDCs, Dreamstate, The Gorge, and Burning Man twice. I also have other pics here: https://www.instagram.com/aphexcx/

    And I keep improving it every time the next festival comes around. The current iteration has:
    – Multiple messages that anyone can add to, via bluetooth (and also, this year at burning man, I added a wireless keyboard that people can type on)
    – A portable stand so I can set it down on the ground and have our group dance around it
    – A beat detector that runs on a separate arduino nano with an adafruit electret microphone, that makes the sign flash to whatever beat is playing around it (the nano raises a pin interrupt on the uno when it detects a beat)
    – Much more hahah

    And again, the original build would not have been possible (or probably would have been 10x harder and looked 10x shittier) if josh hadn’t posted this article. I appreciate you and the little community here forever for this page!

  22. Dalton

    The only problem I am having with this build is that the letters where mirrored but I figured out if I wrote what I wanted it to say backwards then it worked but it scrolls from right to left instead of the opposite. What can I do to make the text not mirrored and have it scroll left to right?

    • bigjosh2

      Rotate the display 180 degrees, then swap the order of the pins that the strips are connected to. You can you can also change it in the software.

  23. Adam

    Josh,

    Trying to build a 1 meter long sign as part of a senior design project. Soldered all of the connections and attempted to test the sign, but none of the LED’s turned on. We didn’t supply power from both ends of the LED’s to make the soldering job a little easier.

    The power supply we used was variable voltage / current put at 5V, and we slowly increased the current until it maxed out at 5.1 A. Could the cause of this be current limited?

    • bigjosh2

      Always start from the simplest working thing and then work your way up until you either find the issue, or you have the full thing you wanted working.

      So, for example, you might want to…

        1. Start with a single 1m strip using the Arduino 5V output for power and connected to pin 6 with the Adafruit strandtest program. If that does not work, then you either made a mistake or have a broken strip or a broken Arduino.
        2. Next try running same hardware set up above, but using the SimpleScroll software above. If this does not work, then there is something about SimpleScroll that is not compatible with your strand. LMK and we will figure it out!
        3. Next try connecting the single stand to the external power supply rather than the Arduino 5V output. If this does not work, then either you connected something wrong or have a bad wire, or a power supply problem.
        4. Next try connecting the rest of the strands, one at a time, to the Arduino and the power supply. If this does not work, then maybe you are overloading the power supply. How it fails will tell you what is wrong.
        5. Next… well.. if you get to here then you have all strands working with the power supply so you are done! :)
      • Adam

        Thanks for the quick response!

        Turned out to be the power rail we soldered. Bad connection. Followed some of your troubleshooting device and ended up working.

        Much appreciated!

    • bigjosh2

      BTW, if you are pumping 5A at 5V and not seeing any light, then either (1) the power supply is not really working or (2) there is a short someplace that is getting hot!

  24. Jeff

    Hi Josh, I posted a month or so ago but I’m not sure if it got through to you or not. Here’s the post again just in case you never got it:

    Hi Josh – I posted a few years back and am finally getting around to this project again. You can find my original post above dated March 11, 2018 – 12:47 PM (by Jeff).

    Basically I was asking about hooking up an ESP8266 to the UNO to use the ESP’s wifi abilities to get data dynamically from a server, then pass that along to the UNO. In theory this sounded great but I’m running into issues with the data transmission garbling the data here and there.

    Then I came across this: https://store.arduino.cc/usa/arduino-uno-wifi-rev2

    It looks like an UNO with added wifi capabilities built in. Do you know if the scrolling LED code you wrote would work on this board? If so, I could get rid of the ESP and replace my UNO with the UNO wifi, which would significantly simplify my workflow and eliminate a lot of code used for data transmission. Much cleaner and easier to maintain too. Thoughts?

    • bigjosh2

      I think a much better solution is use a Raspberry Pi and plug the Uno into the USB port. Feed updates to the Uno by sending data to the serial port on the Pi. Significantly cheaper and much more flexible!

      • Jeff

        My project already has a 2nd board in the ESP, so would I really gain much by swapping that out with a raspberry pi, other than maybe the pi is a little more flexible? It’s still introducing the same data transfer hurdles to overcome, plus I also don’t really know what I’m doing with raspberry pis. I’d really love to eliminate a 2nd board altogether. Do you know of any reason why the scrolling text code stuff would not work on the UNO wifi board? I know it’s more expensive but maybe I’ll try that first and see what kind of results I get with that before going down the raspberry pi road, if you think it can handle your code…

        • bigjosh2

          IT does work on the UNO Wifi board and I actually have a friend who is running the news and weather with this setup. I just hate that board, it is not well designed and has deep problems – and it more expensive than a Raspberry Pi!

  25. Jhon Elarcosa

    Good day Sir!

    Just wanted to ask if the led strip that you’re using is possible for GSM Based Campus Display System. Same length and width but the characters or text displayed on the led Strips should be through text sms, like for example if you want to text ” Attention! All CEIS officers will have a meeting this afternoon at exactly 4pm.” , is it possible? I saw the same study but the researcher using only LCD which is small, no bigger available in the market so I’m planning to use led strips for scrolling message. Thanks for the response Josh, Have a great day!

    • bigjosh2

      This would not be hard. You would need something like this to get the SMS messages, and then just send them to the pixels. Note that you do need a SIM and cell account to get the texts, and depending on where you live that could be expensive.

  26. Maxwell

    Hey Josh,

    I was able to get my 60pixel/M * 1 M sign running, and it prints your jabberText array just fine. However, I want to print a (continuously changing) message from my raspberry pi. I am having an issue with the Serial port though.

    My Arduino is able to properly receive the message I send through serial. But I found that the bottom strip, which is connected to the TX port, lights up entirely white and doesn’t scroll any text.

    If I close the port before printing the message, then the LED strip operates normally, but data from my python program is being sent continuously. If I try to open and close the port repeatedly in the loop function, I end up getting an error like stk500_recv() is not responding.

    Unfortunately, my pi is scraping some data off the internet so I can’t get rid of it. How do you recommend I go about fixing this? I would appreciate any help. Thanks.

    • bigjosh2

      Yes, this is expected. On the Uno, pin D0 and D1 are connected to the serial port that is used to talk to the host. When you enable the serial port in the Arduino code, it switches these pins to serial mode and so D1 (which is connected to the LEDs) is no longer sending LED data.

      Luckily there is a way to disable just the TX pin so that it can again be used to drive LED pins, while still leaving the RX pin as the serial port (so you can get data from the Pi). Add this line in your `setup()` after you `begin()` the serial port…

      “`
      UCSR0B &= ~_BV(TXEN0); // Disable USART TX, return pin D1 to normal digital mode
      “`

      Once you do that, the bottom LED string connected to pin D1 should start working normally again.

      You will also need to be careful to keep your baud rate low enough that it takes less time to update the strings than it does for a single serial byte to come in. Otherwise you can have overrun where the 2nd byte is received before the first one is read, and then the 1st one is lost. Try starting with a very low buad (like 300 maybe?) and make sure everything works. If so, then you can always increase the baud rate if you need to, but you can even Really read text faster than 300bd so that should be ok.

      Report back with how you make out!

  27. Jeff

    I’m trying to run your code on an Arduino Uno Wifi Rev2, but I’m getting the following error:

    ‘DDRD’ was not declared in this scope

    It sounds as if the ports are a little different from a standard UNO to the WIFI Uno?

    • bigjosh2

      Yea, even though they say this board is “basically an Arduino Uno Rev3 with more kick”, it actually has a ATMEGA4809 which is a completely different processor than an Uno. It is a very nice processor, but it is totally different so would require completely different code to drive the WS2812Bs.

  28. Sean

    Hey Josh, this is great code, appreciate that you figured out the timing and documented it for all to enjoy.

    I’m wondering if you have experienced unintended pixels being lit? I’ve modified some of your code to run a sign in a little different way than you do, using just two pins. Anyway I’m getting what looks like spikes of color randomly. For instance If I send a certain string of bits, maybe the 10th LED has a small spike in the red or blue or green, a different anomaly will appear further down the line, with a different color spiking, The spike matches in the same color and location on both strips.

    I’m not really looking for troubleshooting here, just wondering if its something you’ve seen before. Like “yeah, you’re using cheap WS2812Bs and the timing isn’t the same”. I’ve been tinkering with the NOPs and seeing the anomolies move around but they persist.

    Any thoughts off the top of your head?

    Thanks!

    • bigjosh2

      My #1 guess: Sounds like a timing problem. Different factories make WS2812B strips with slightly different timing requirements, and the above code is iffy.

      First step to track this down would be to try Adafruit’s strandtest code. This is the gold standard and works with all the strips I’ve ever seen.

      If strandtest works, then if you only need a single strip then consider switching to the much simpler code here. If the color problems come back then you can try playing with the timing values until you find ones that work reliably with your strip. Report back with your findings!

      • Sean

        Thanks! I’m working through the updated code you sent, integrating it with my code. Basic tests show no anomalies though, so far so good.

  29. daniplayerone

    Hello Josh!

    I love this project and I will be attempting to build it soon. I have one question for a potential addition, since I have never done anything like this.

    I want to be able to add a button to dismiss messages displayed. For example, display a message to “Feed the cats!” that will stay there until you press the button to go away. Is this something that could be easily achieved with the arduino pro mini?

    Thanks a lot in advance for your time and for the inspiration!
    Daniel

    • bigjosh2

      Yes, this should be as easy as…

      1. Connect a button to any free digital IO pin and ground.
      2. Enable the pull-up resistor on this pin.
      3. Anytime you see the pin go `LOW`, show a blank message on the sign.

      Of course there are details here, but I bet you can figure them out! Report back with any questions, or with triumphant stories of success!

  30. ASHISH BAWA

    hi josh
    i am trying hard to run 14 strips(rows) of 400pixel each, but could not run FULL PORTB and PORTD together. i have a bigger font that will consume11 strips, but last four strips/rows are not responding to the text(DATA pin 10,11,12,13).
    Please give some input.

    • bigjosh2

      While it is likely possible to drive 14 strips at the same time with code like that presented here, it would take significant effort and lots of cycle counting to make sure you are sending the right signals at the right times on each of the two `PORT`s.

      It might be simpler to make 2 copies of this code and edit one to address the 2nd `PORT` and then call them sequentially, although this would take twice as long as interleaving the updates.

  31. sjovoll

    Hi Josh, and thanx for an excellent tutorial and inspiration. I currently have a 5 meter display installed – and it works just perfect with an UNO controlling it. To get more dynamic content, I was planning to replace the UNO with an Arduino Yun – but from my first attempts it looks like the text output becomes pretty scrambled. Any experience or thoughts on using the Arduino Yun for this project?

    • bigjosh2

      The led code turns off interrupts, so if data is coming into the serial port too quickly then some will be lost. Try lowering the baud rate between the two halves of the Yun. Start really low like 300bd and work your way up until you start to get corruption. The maximum speed will depend on how long your strings are (longer strings take longer to update so interrupts are off for longer time so serial data must go slower).

  32. dave

    could your code run on raspberry pi ? 40 pins is a big sign, I,m looking at this arduino running on rpi …

    • bigjosh2

      No, this code is specific to AVR processors like the one in the Arduino UNO. 40 pins is a lot of pins, more than a raspberry pi has. If you really need that many pins probably the only non-hardware solution would be to use a BeagleBone with something like ledscape, which can directly drive up to 66 strings of effectively unlimited length. Luckily for you , I just fixed one of the biggest problems with using ledscape like this so it now works smoothly! :)

        • bigjosh2

          Today is your lucky day. Last night I released a new version of LEDscape that fixes the white flashing problem that had been blinding LED spectators around the world for the past 6 years. Man it was hard, mostly because of bad design and documentation on the BBB/AM35X platform. You can read about the fix here, and it is in place on my repo here. With this update, combined with the previous PHY fix, it is now possible to have a reliable BBB-based working neopixel setup with up to 48 strings per board out of the box and a theoretical max of 66 strings per board. That said, I still fricken hate this platform and would not wish it on my worst enemy. Have you considered the TEENSY OCTO platform? This is a thoughtfully designed and well documented hardware and software solution for driving lots a pixels and probably ends up cheaper than the equivalent BBB setup. Certainly less pain and anguish.

          • dave

            you say “BBB-based working neopixel setup with up to 48 strings per board out of the box and a theoretical max of 66 strings per board” how many pixels in total could I get ? i need a matrix ws28ixx 360 pixels wide by 180 pixels high (360×180=64,800 ws2812b pixels) can this be done by the bb ? I want to feed data via usb cable from a rpi runing xlights or resolume

            • bigjosh2

              My largest installation is 708 x 180 pixels running on 72 BBBs (6 strings of 295 pixels each per BBB), which can easily run 25 FPS. You could probably drive your 180 rows as 90 strings of 720 pixels each at 28FPS. This would take 2 BBBs, each driving 45 strings. I’d use ethernet rather than USB for less jitter and more bandwidth. But I would really urge you to look into the TEENSY solution. These BBBs are no fun. Also know that you are likely going to be replacing pixels frequently, they do fail and with this many they fail a lot! I’d say do a small test with each system to see what you are getting yourself into!

  33. Nick n

    Hey josh,
    I’m new to all of this but is there a way to modify this project so that it would be able to run up to date sports scores and whatnot through it?

  34. Lanre Johnsona

    please,I have ws2811, will it work, sir?
    if it can work, kindly show me how to do it sir.
    I have 4*5meter length of 60/meter.

    am a noob to coding, can’t modify except I get help.

    Thanks

  35. Zoltan Kovacs

    Hi I’m totally beginner using arduino I copy and paste your code but the program stop with lot warning, what am I doing wrong? I have to change something in the code? or I needed some library? pls tell me help me. thank you

  36. Ruud van der Meer

    Hello Josh,
    I have made one, with 48 leds. (iwth a NANO)
    The Simpletickertape program works good but when i compiled the Simplescroll i get an error that the ‘sendChar’ was not declared in this scope.
    Do i something wrong? I see nothing of it on your site? Am i the onlyone?
    Greetings Ruud from the Netherlands

  37. Ruud van der Meer

    Hello Josh,
    From Roelofarendsveen In the Netherlands.
    That is what i have done, and i get the same error.

    This is the complete error message:

    C:\Arduino_Progs\__WS2812\WS2812_Tekstdisplay\sketch_nov02a\sketch_nov02a.ino: In function ‘void scrollString(const char*)’:
    sketch_nov02a:1093:5: error: ‘sendString’ was not declared in this scope
    sendString( s , step ); // Nice and not-too-bright blue hue
    ^~~~~~~~~~
    C:\Arduino_Progs\__WS2812\WS2812_Tekstdisplay\sketch_nov02a\sketch_nov02a.ino:1093:5: note: suggested alternative: ‘drawString’
    sendString( s , step ); // Nice and not-too-bright blue hue
    ^~~~~~~~~~
    drawString
    C:\Arduino_Progs\__WS2812\WS2812_Tekstdisplay\sketch_nov02a\sketch_nov02a.ino: In function ‘void loop()’:
    sketch_nov02a:1163:5: error: ‘sendString’ was not declared in this scope
    sendString( “1234567890.” , x );
    ^~~~~~~~~~
    C:\Arduino_Progs\__WS2812\WS2812_Tekstdisplay\sketch_nov02a\sketch_nov02a.ino:1163:5: note: suggested alternative: ‘drawString’
    sendString( “1234567890.” , x );
    ^~~~~~~~~~
    drawString
    exit status 1
    ‘sendString’ was not declared in this scope

    Thanks.

  38. Ruud van der Meer

    Hello Josh,
    YES! It is working with the new source. Only it goes so quickly it is hardly to read.
    I must look where i can setup the speed. Maybe you can advice….
    And what are you intent to do with the Jabbertext (at the and of the program.
    It looks that it will end in the last While(1). And when i place the
    scrollString( jabberText ); at the place of
    scrollString(“josh is #440000very#000040 nice and I like him.” );
    it wont work. the must be something easy to let it work again.

    • bigjosh2

      >Only it goes so quickly it is hardly to read.

      Easiest way to slow it down is to increase `PIXEL_COUNT` to a larger number.

      >scrollString( jabberText ); at the place of
      >scrollString(“josh is #440000very#000040 nice and I like him.” );
      >it wont work. the must be something easy to let it work again.

      I think it is supposed to work. What happens when you try? How does it fail?

  39. Ruud van der Meer

    Hi Josh,

    The problem was in the scrollString void, i have changed it and it works now much better. The pixel_count for me is 48.
    This is the new void:

    void scrollString(const char *s ) {
    const int pixel_len = strlen(s) * (FONT_WIDTH+INTERCHAR_SPACE);
    for(int step = 0 ; step < pixel_len-PIXEL_COUNT ; step++ ) {
    drawString(s , step – PIXEL_COUNT);
    delay(40); // scroll speed.
    }
    }

    Now it works nice also with the jabbertext.

    But, is there a simple function to control the brightness of the leds?
    Now i must use sunglasses ;)

  40. Ruud van der Meer

    Hello Josh,

    Some fine tuning about the working.
    When you change o lot of times the text color it wont work good.
    It looks how much there is a # and correct it in the display length.

    This works better:

    // RM changed 5 nov 2021
    void scrollString(const char *s ) {
    int pixel_len = strlen(s) * (FONT_WIDTH+INTERCHAR_SPACE);
    String sss = s;
    int lengte=sss.length();
    for(int x=0;x < lengte;x++) {if (sss.charAt(x)=='#') {pixel_len=pixel_len – ((FONT_WIDTH+INTERCHAR_SPACE)*7);}}

    for(int step = 0 ; step < pixel_len+PIXEL_COUNT ; step++ ) {
    drawString(s , step – PIXEL_COUNT);
    delay(40); // scroll speed.
    }
    }

  41. fibko

    Hello Josh,

    I have one problem, when I enter, for example, the color RGB FFFFFF on the oscilloscope, I only get the value 127. Or when I set 020202, the value is not 2 but 3. Could you help me with this?

  42. Desiree Vittorio

    Hi! I’m teacher that is trying to help a student put this project together. I purchased all of the pieces. My first question is on the LED strip wiring. There are 5 wires sticking out of each end, 3 of the wires are connected to a black piece and there are 2 other wires dangling free. The colors of the wires in the black piece are red, dark green and light green. The two free wires are red and white.
    I am assuming the red goes to power and the pale green is ground. Where does the third wire get soldered to? Do I do anything with the two free wires?

    Second, what pins is the solder board connected to on the Arduino? I can follow the ground and positive, I do not see the pin or pins the solder board connects to.

    Third, how do we get power to the Maxwell device?

    • bigjosh2

      There are 5 wires sticking out of each end, 3 of the wires are connected to a black piece and there are 2 other wires dangling free. The colors of the wires in the black piece are red, dark green and light green. The two free wires are red and white.

      The free red and white wires are the power connections. Red goes to +5 volts and white goes to ground (0 volts).

      The black connector has 3 connections. Usually the middle one is the “data” wire and the other two are the power wires (they are connected to the same place as the lose red and white wires above). If you look carefully at those three wires coming out of the black connector you should be able to follow each one and see where it goes so figure out which wire it is. The ground wire on the black connector goes to the ground pin on the Arduino. The data pin goes to one of the data out pins on the Arduino. Note that each pixel strip has two ends – one end is “data in” (usually labeled “DI”) and the other is “data out” (usually labeled “DO”). You want to use the “data in” side since the data is going to be coming OUT of the Arduino and INTO the strip.

      how do we get power to the Maxwell device

      You will need to connect an AC power cord to the power supply. This is easy (just 3 screws), but since this is 120 volts AC, you should try to find someone who is comfortable working with AC power. But note that you do not need the meanwell to get at least one strip up and running – you can power it from the Arduino. Before starting to build the full sign, I’d take some baby steps and get a single strip running with one of the many online tutorials like this one….

      https://learn.adafruit.com/neopixel-painter/test-neopixel-strip

      Also, this is a newer (better) version of this sign project that has more features…

      Build a giant live scrolling tickertape display from WS2812B Neopixels and an Arduino Uno

      Report back with your results or any questions!

      • devittorio

        Thank you so much! I did get one strip to power up and ran a few test light strands.
        I thought the meanwell came with a power cord. In the pictures it shows that it is 5v. Is there a 5v cord I can look up on amazon that works with this?

        • bigjosh2

          I thought the meanwell came with a power cord.

          Sometimes they do, sometimes not.

          Is there a 5v cord I can look up on amazon that works with this?

          Any will work, and I often just cut the cord off of a broken appliance and use that. But here is one for $8 on amazon…

          https://amzn.to/3xgfwxU

      • devittorio

        Hi! I got the sign to work! We actually wired it with a bread board and did not solder and the Arduino is the power source. I was looking online and am not sure how to power the meanwell because it is a 5v and the power plugs are 12v.
        I have an external power plug for the Arduino and am just running it off of that.

      • Desiree

        Hi! I had been writing you last year about this project and I wasn’t sure how to connect the large power source, and we have revisited the project with the current class this year and we figured it out and we have the large scrolling sign on the wall! Today is a snow day, but I will post a picture when we get back to school. Thank you for all of your help! The students are very happy and so proud! I am really proud of them!

  43. crux

    Hi josh, I changed the Uno board that works like a cream, with a 2560 because I need more memory for a longer text to display in sentences, but it load correctly the same script but don’t visualise on strips.
    Maybe it has different timing or clock?
    Thanks for your great job

    • bigjosh2

      Unfortunately the 2560 does not have all of the `PORTD` pins in a row on the Arduino headers like the UNO does, so you need to use a different PORT. Luckily all 8 pins of `PORTK` are available in order on the lower left edge of the board so you can use those, but you will need to edit the code to change the lines…


      #define PIXEL_PORT PORTD // Port of the pin the pixels are connected to
      #define PIXEL_DDR DDRD // Port of the pin the pixels are connected to

      …to…


      #define PIXEL_PORT PORTK // Port of the pin the pixels are connected to
      #define PIXEL_DDR DDRK // Port of the pin the pixels are connected to

  44. Sara

    Hi Josh, Thank you for the wonderful display and resourceful documentation. I learned a lot from making this project and reading through all the conversation here.

    What I did is to connect the display with google API , feeding text from google sheet to show up. My issue is that when the text is short, like a word long, it’s not start scrolling from the beginning of the LED but somewhere in the middle. any idea of what is the reason?

    • bigjosh2

      You can change this by editing the Arduino program to clear the buffer each time it receives, say, a new line. If you now put a new line in front of each message then it will be the only thing on the display.

  45. angel

    Hi Josh.
    I was able to complete the LED sign and it really is wonderful, thanks for that design.
    The question I have is how to make new characters, for example accented letters or new alphanumeric letters.
    Excuse my level of English.
    Greetings and thanks for attention

Leave a Reply to bigjosh2Cancel reply