- 2014/03/16 Update: The source code to this is now on GitHub. Check the Arduino link at the top of each page of this site.
Yesterday evening, I coded up a simple scrolling message sign that uses addressable LED strips like the Adafruit NeoPixels (WS2811) or LPN8806. The code I created is built for NeoPixels, since those were the ones I had access to, but it would be trivial to make it work with the Adafruit LPN8806 library. Future versions will make this simpler.
First, let’s talk about LED signs.
The BetaBrite is a commercially available scrolling message sign that’s been around for ages. I bought one at SAM’S CLUB back in the late 1990s. The BetaBrite that I have uses an 80×7 array of LEDs. This is what I will be trying to replicate.
If you shop around (ahem, e-Bay), you can find 1 meter long WS2811 LED strips with 60 RGB LEDs for around $8-$9. If you had seven of those, you could make a 60×7 LED sign. It wouldn’t be able to show as many characters at the same time as a BetaBrite does, but it would be good enough to experiment with. (There are strips with 144 pixels per meter, but they are very expensive. And, when you get past 500 or so LEDs, you start running out of memory on the Arduino. I plan to fix this with some updates to the LED library, eventually.)
Consider this wonderful drawing as I discuss a few possible ways to present a sign made out of LED strips:
A. At the top is an example of one of these LED strips with LED number 0 to “n”. One end hooks to the Arduino and power, and the other end can be used to daisy chain multiple strips together. The first LED will be 0, and they count up to the end of the last strip. If you have three 60 LED strips, you have LEDs 0 to 179. The green arrow shows the direction of the data (the LEDs count up in that direction).
B. Next is an example of how you might arrange multiple strips so they could make up an LED sign. Each strip is shown running left-to-right, so at the end of the first strip the cables go all the way back to the left to connect to the start of the next strip. Wiring them like this makes it real easy to do things with. Notice that the green arrow runs left-to-right on each row.
C. However, it would be much much easier to just connect them like this, without all the extra wires running around. But, this causes every other row to run in the opposite direction (again, see the green arrows). This means the software has to be smart enough to know how to reverse drawing the pixels for every other row.
ALSO, based on where you decide to make LED 0, that changes everything. In these drawings, we are hooking the Arduino up at the top left. But, if it was easier to hook up at the bottom right, the entire numbering system would be backwards.
I decided to write a simple LED message program that could handle all of this. It’s not pretty, but it (maybe) works. I configure it with the number of LEDs in use, and how many are in each row, then I set where the start pixel is (TOPLEFT, TOPRIGHT, BOTTOMLEFT or BOTTOMRIGHT). I support running the rows STRAIGHT (A) or ZIGZAG (B). It can even do something fun…
D. This is the only thing I have actually done. I had two 1 meter strips, so I decided to spiral them with 20 LEDs in each spiral before the next row starts. These 120 LEDs can be split up in my program as six rows of 20 LEDs each, and then (with a small enough font), a message can rotate around it.
If you’d like to try out my code, I have posted it to GitHub:
I have only tested it in the D configuration, but I have done some debug prints that make me think it should be handling all the other variations. Until I have access to more LED strips, I won’t know for sure.
Anyone want to try it out and let me know how it works for you?
Poor documentation, and the code could be cleaned up and optimized quite a bit. Perhaps I will have that done when I reach version 1.0.
Here’s a video of my first working version:
Hi friend! This code works with RGB LED strips WS2812(B) Thank you
What is different with the WS2812? I have not heard of that one yet.
Here: http://rgb-123.com/ws2812b-vs-ws2811/
Sorry I missed this reply… Yes, my code should work with anything where you can say “set LED X to color Y”. That’s all it needs. The Adafruit libraries I use are the same calls for several types of LEDs they make the library for, so the changes are very minor to support them. If these LEDs use a different library, it will just require changing a few lines to call the library functions instead of the Adafruit functions. I’d be glad to help.
Where to find “fontALL.h”
I got it from the TV Out library: https://code.google.com/archive/p/arduino-tvout/
i get an error message with the code saying ‘lineInput’ was not declared in this scope
That is LineInput.ino. You have to have all the files open in tabs so they compile together, if I recall.
my matrix is 5 high 16 wide and it didn’t work thanks though for responding quickly, I am going back to the drawing board
What did it do? It should be able to configure for just about anything, provided it works with one of the zig-zag/wiring patterns I described.
nothing didn’t even move I can send photo if needed
What type of lights?
If you aren’t using LEDs supported by the Neopixels library, you should be able to replace the light on/off code with whatever works with your panel, and configure it that way.
i have ws2811 i got them off ebay.
Do any of the Neopixel examples work on it?
And if you can send me a link to a seller, I’ll take a look at what they are.
sorry its ws2812B I miss read the fine print on the side I have been up spray painting my daftpunk helemets. https://www.amazon.com/ALITOVE-Individually-Addressable-Flexible-Waterproof/dp/B00VQ0D2TY
ive gotten other stuff to work on it just not this
Cool. As long as you have the library and it uses the same API as the WS2811, it should work as long as a few things are configured.v
#define PIN 6
That pin should match whatever the working demos use based on how you have it wired up.
#define LEDBRIGHTNESS 2
If this is too low, you might not see anything. I ran it very low because I was powering mine from the Arduino 5v directly so I was limited.
The rest is making sure the API library calls match. Look for places that start with “strip.” in the code (only a few places). Most important is probably the thing that defines what it is using:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDS, PIN, NEO_GRB + NEO_KHZ800);
Those parameters at the end may have to be changed to match what you have, so compare that with the example code you have that works.
Also:
strip.setPixelColor( xxxx , strip.Color(127,0,0) );
and
strip.show();
Are those used in the examples you have that work?
I have left the code as you had it and it lights up some lights in a weird pattern doesn’t move, I am clueless.
Ah… The pattern is probably a config thing, based on how many lights per row and such. The not moving could be because by default no ENTER is sent from the Arduino IDE when you type in the window so the input never gets processed. There is a toggle in the terminal/serial console that makes it send CR at the end. If you can’t find it, I will install it and take a quick look on the system I am using right now.
Found it. Bottom right of the COMx window has “No line ending” in a pull down. Change that to “Carriage return” and that should get the input coming in. It will print out on the screen what is going on. You can also uncomment:
//#define DEBUG
And it will print the banner to the screen sideways as characters, representing which LEDs would be turned on.
I have 5 rows and 16 leds per a row I needed something to scroll across all 16 leds to read DragonCon 2017 but no such luck
Can you show me a diagram of how you have them wired? Do they follow any of the patterns in my drawing on my article?
they follow the one you have on your diagram i believe they zigzag I can send you a photo if you want, its going into a crt helmet for a silver daftpunk cosplay.
That would be great! I’m glad to help. Dragoncon in Atlanta? Or are there more locations?
yes in atlanta My friend coded my helmet which is the gold one and he passed away before he could help me finish the silver one and I need all the help I can get
Contact me via my Facebook page if you prefer, or I can e-mail you.
Comment out:
Serial.print(“Enter message: “);
msgLen = lineInput(message, MAXMSGLEN);
And then add this (can be better, just for testing):
strncpy(message, “This is your message”, MAXMSGLEN);
msgLen = strlen(message);
…that will make it just fire up and do that message over and over without stopping for input.
aparently i am just a hand full of issues today lol making things so easy for you arent I sorry if I am a bother.
Arduino: 1.8.3 (Windows 10), Board: “Arduino/Genuino Uno”
LEDSign:197: error: stray ‘\342’ in program
strncpy(message, “This is your message�, MAXMSGLEN);
^
LEDSign:197: error: stray ‘\200’ in program
LEDSign:197: error: stray ‘\234’ in program
LEDSign:197: error: stray ‘\342’ in program
LEDSign:197: error: stray ‘\200’ in program
LEDSign:197: error: stray ‘\235’ in program
C:\Users\Herobattousai\Documents\Arduino\LEDSign-master\LEDSign\LEDSign.ino: In function ‘void loop()’:
LEDSign:197: error: ‘This’ was not declared in this scope
strncpy(message, “This is your message�, MAXMSGLEN);
^
C:\Users\Herobattousai\Documents\Arduino\LEDSign-master\LEDSign\LineInput.ino: At global scope:
LineInput:17: error: expected initializer before ‘byte’
byte lineInput(char *buffer, size_t bufsize)
^
exit status 1
stray ‘\342’ in program
This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences
HTML copy/paste got that one. Let me see if this helps. Basically, instead of calling LineInput to read Serial input in to a buffer, we use string copy to copy a hard-coded string there, then set the length. The rest is the same.
strncpy(message, “This is your message”, MAXMSGLEN);
msgLen = strlen(message);
You will have to retype the quotes — it put them in with open quote/end quote, which won’t work in the compiler…
evidently it doesn’t like me here and you have been very helpful I thank you for the help It just doesnt want me to post the code here it gives me an error message…..
I can e-mail you code when I get home in a bit.
that would be amazing in return I would love to repay you somehow in some form of fashion I do volunteer for a makerspace so if there is anything you need help with
HI,are the messages can be saved on arduino after use serial monitor arduino IDE. thanks
No. It would be easy to add. It could write the input to the eeprom Storage.
Hello Allen, Great job on the code. I made some mods to allow entering message, R,G,B, and scroll speed through serial. below is the code.
/*—————————————————————————*/
// CONFIGURATION
/*—————————————————————————*/
// Adafruit NeoPixel library configuration.
#define PIN 5
// LED strip configuration.
// Example: 7 1m 60-LED strips (similar to BetaBrite 80×7 display).
#define LEDSTRIPS 1
#define LEDSPERSTRIP 100
#define LEDSPERROW 20
// LED strip layout.
// Where is LED 0? TOPLEFT, TOPRIGHT, BOTTOMLEFT, or BOTTOMRIGHT
#define LAYOUTSTART TOPLEFT
// If the strips run one direction, then reverse for the next row,
// use ZIGZAG, else use STRAIGHT.
#define LAYOUTMODE STRAIGHT
int SCROLLSPEED = 100; // 100ms (1000=1 second)
/*—————————————————————————*/
// FUNCTIONS
/*—————————————————————————*/
String incomingByte;
int Red1;
int Grn1;
int Blu1;
char message[MAXMSGLEN];
uint8_t msgLen;
void setup()
{
#if defined(LEDBRIGHTNESS)
strip.setBrightness(LEDBRIGHTNESS);
#endif
Serial.begin(9600);
Serial.print(F(“LEDSign “));
Serial.print(VERSION);
Serial.println(F(” by Allen C. Huffman (alsplace@pobox.com)”));
DEBUG_PRINTLN(F(“DEBUG MODE”));
Serial.print(F(“Total LEDs : “));
Serial.println(LEDS);
Serial.print(F(“LEDs per row : “));
Serial.println(LEDSPERROW);
Serial.print(F(“Rows : “));
Serial.println(ROWS);
Serial.print(F(“Free memory : “));
Serial.println(freeRam());
Serial.println(“Enter message \”|\” Then colour R,G,B,(Scroll Speed in Milliseconds): “);
Serial.flush();
// Start up the LED strip
strip.begin();
// Update the strip, to start they are all ‘off’
strip.show();
} // end of setup()
void loop() {
// send data only when you receive data:
if (Serial.available() > 2) {
for( int i = 0; i 0)
{
uint8_t fontWidth, fontHeight, fontStartChar;
uint8_t letter, fontByte, fontBit;
uint8_t letterOffset;
uint8_t row, col;
uint8_t offset;
char ch;
uint8_t layoutStart, layoutMode;
uint8_t colDir, rowDir;
uint8_t colOffset, rowOffset;
layoutStart = LAYOUTSTART;
layoutMode = LAYOUTMODE;
// If LED 0 starts at the bottom, we need to invert the rows when we
// display the message.
if (layoutStart==TOPLEFT || layoutStart==TOPRIGHT)
{
rowDir = DOWN;
}
else
{
rowDir = UP;
}
// If we start from the right side, we will be going backwards.
if (layoutStart==TOPLEFT || layoutStart==BOTTOMLEFT)
{
colDir = RIGHT;
}
else
{
colDir = LEFT;
}
fontWidth = FONTWIDTH;
fontHeight = FONTHEIGHT;
fontStartChar = FONTSTARTCHAR;
//Serial.print(F(“Font size : “));
//Serial.print(fontWidth);
//Serial.print(F(“x”));
//Serial.println(fontHeight);
//Serial.flush();
// Loop through each letter in the message.
for (letter=0; letter<msgLen; letter++)
{
// Scroll fontWidth pixels for each letter.
for (offset=0; offset<fontWidth; offset++)
// If you comment out the above for loop, and then just set offset
// to 0, the sign will scroll a character at a time.
//offset = 0;
{
// Loop through each row…
for (row=0; row<ROWS && row<fontHeight ; row++)
{
letterOffset = 0;
fontBit = offset;
// If going down (starting at top), we will use the loop row,
// else we will calculate a row that goes backwards.
if (rowDir==DOWN)
{
rowOffset = row;
}
else
{
rowOffset = (fontHeight<ROWS ? fontHeight : ROWS)-1-row;
}
// Now loop through each pixel in the row (column).
for (col=0; col=msgLen)
{
ch = ‘ ‘;
}
else // Otherwise, get the actual letter.
{
ch = message[letter+letterOffset];
}
// Get the appropriate byte from the font data.
if (bitRead(pgm_read_byte_near(&font[FONTDATAOFFSET+
(ch-fontStartChar)*fontHeight+rowOffset]),
//(colDir==RIGHT ? 7-fontBit : 7-(fontWidth-1)+fontBit))==1)
//(colDir==LEFT ? 7-fontBit : 7-(fontWidth-1)+fontBit))==1)
7-fontBit)==1)
{
// 1 = set a pixel.
strip.setPixelColor((row*LEDSPERROW)+colOffset,
strip.Color(Red1,Grn1,Blu1));
DEBUG_PRINT(F(“#”));
}
else
{
// 0 = unset a pixel.
strip.setPixelColor((row*LEDSPERROW)+colOffset, 0);
DEBUG_PRINT(F(” “));
}
// Move to next bit in the character.
fontBit++;
// If we get to the width of the font, move to the next letter.
if (fontBit >= fontWidth)
{
fontBit = 0;
letterOffset++;
}
} // end of for (col=0; col<LEDSPERROW; col++)
DEBUG_PRINTLN();
// If the LED strips are zig zagged, at the end of each row we
// will reverse the direction.
if (layoutMode==ZIGZAG)
{
// Invert direction.
if (colDir==RIGHT)
{
colDir = LEFT;
}
else
{
colDir = RIGHT;
}
} // end of if (layoutMode==ZIGZAG)
} // end of for (row=0; row<ROWS && row<fontHeight ; row++)
strip.show();
#if defined(DEBUG)
for (uint8_t i=0; i<LEDSPERROW; i++) Serial.print(F("-"));
Serial.println();
#endif
delay(SCROLLSPEED);
} // end of for (offset=0; offset<fontWidth; offset++)
} // end of for (letter=0; letter0)
} // end of loop()
// Simple utility function to return the current free RAM.
unsigned int freeRam() {
extern int __heap_start, *__brkval;
int v;
return (int) &v – (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
} // end of freeRam()
/*—————————————————————————*/
// End of LEDSign
#define VERSION “0.03”
#include
#include “LEDSign.h”
// If using the TVout fonts, either include the individual header file for
// the font you wish to use, or include this one to access them all. The
// current version of this program has the font selected at compile time, so
// there is no reason to include more than just that font, but in the future
// I plan to update it so fonts can be selected.
#include “fontALL.h” // Use the TVout fonts for this test.
// If defined, this will print out the banner text to the Serial console.
//#define DEBUG
/*—————————————————————————*/
// CONFIGURATION
/*—————————————————————————*/
// Adafruit NeoPixel library configuration.
#define PIN 5
// LED strip configuration.
// Example: 7 1m 60-LED strips (similar to BetaBrite 80×7 display).
#define LEDSTRIPS 1
#define LEDSPERSTRIP 100
#define LEDSPERROW 20
// Example: 2 1m 60-LED strips, spiraled with 20 per row. (6 rows).
//#define LEDSTRIPS 2
//#define LEDSPERSTRIP 60
//#define LEDSPERROW 20
// LED strip layout.
// Where is LED 0? TOPLEFT, TOPRIGHT, BOTTOMLEFT, or BOTTOMRIGHT
#define LAYOUTSTART TOPLEFT
// If the strips run one direction, then reverse for the next row,
// use ZIGZAG, else use STRAIGHT.
#define LAYOUTMODE STRAIGHT
int SCROLLSPEED = 100; // 100ms (1000=1 second)
// If defined, a strip.setBrightness(x) will be done. I use this so more
// LEDs can be powered off an Arduino supply if they are all very dim/low
// power. You should be using a proper power supply, however!
#define LEDBRIGHTNESS 30
// Specify which font to use. (These examples are for the TVout fonts.)
const unsigned char *font = font4x6;
//const unsigned char *font = font6x8;
//const unsigned char *font = font8x8; // Blank row on top. Bad font.
//const unsigned char *font = font8x8ext;
// Set these defines to match the font data, or, if using the TVout
// fonts, these values can be read from the first three bytes of
// the file (and FONTDATAOFFSET is set to skip those first three
// bytes).
#define FONTWIDTH (pgm_read_byte_near(&font[0]))
#define FONTHEIGHT (pgm_read_byte_near(&font[1]))
#define FONTSTARTCHAR (pgm_read_byte_near(&font[2]))
#define FONTDATAOFFSET 3
/*—————————————————————————*/
// DEFINES
/*—————————————————————————*/
// These defines are calculated.
#define LEDS (LEDSPERSTRIP*LEDSTRIPS)
#define ROWS (LEDS/LEDSPERROW)
// Longest message we can display.
#define MAXMSGLEN 80
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDS, PIN, NEO_GRB + NEO_KHZ800);
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 – 500 Ohm resistor on first pixel’s data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit…if you must, connect GND first.
/*—————————————————————————*/
// For the Adafruit LPN8806/NeoPixel libraries, three bytes of RAM are
// used for each pixel. This crashes the Arduino, so we could easily do a
// simple sanity check before initializing things… To do this, we’d
// need to make the “strip” a global (which is is) and initialize it after
// the check (if the check was successful).
#if (LEDS*3>2000)
#error USING UP OVER 2000 BYTES OF RAM!
#endif
/*—————————————————————————*/
// A debug Serial.print()/Serial.println() macro.
#if defined(DEBUG)
#define DEBUG_PRINT(…) Serial.print(__VA_ARGS__)
#define DEBUG_PRINTLN(…) Serial.println(__VA_ARGS__)
#else // If not debugging, it will not be included.
#define DEBUG_PRINT(…)
#define DEBUG_PRINTLN(…)
#endif
/*—————————————————————————*/
// FUNCTIONS
/*—————————————————————————*/
String incomingByte;
int Red1;
int Grn1;
int Blu1;
char message[MAXMSGLEN];
uint8_t msgLen;
void setup()
{
#if defined(LEDBRIGHTNESS)
strip.setBrightness(LEDBRIGHTNESS);
#endif
Serial.begin(9600);
Serial.print(F(“LEDSign “));
Serial.print(VERSION);
Serial.println(F(” by Allen C. Huffman (alsplace@pobox.com)”));
DEBUG_PRINTLN(F(“DEBUG MODE”));
Serial.print(F(“Total LEDs : “));
Serial.println(LEDS);
Serial.print(F(“LEDs per row : “));
Serial.println(LEDSPERROW);
Serial.print(F(“Rows : “));
Serial.println(ROWS);
Serial.print(F(“Free memory : “));
Serial.println(freeRam());
Serial.println(“Enter message \”|\” Then colour R,G,B,(Scroll Speed in Milliseconds): “);
Serial.flush();
// Start up the LED strip
strip.begin();
// Update the strip, to start they are all ‘off’
strip.show();
} // end of setup()
void loop() {
// send data only when you receive data:
if (Serial.available() > 2) {
for( int i = 0; i 0)
{
uint8_t fontWidth, fontHeight, fontStartChar;
uint8_t letter, fontByte, fontBit;
uint8_t letterOffset;
uint8_t row, col;
uint8_t offset;
char ch;
uint8_t layoutStart, layoutMode;
uint8_t colDir, rowDir;
uint8_t colOffset, rowOffset;
layoutStart = LAYOUTSTART;
layoutMode = LAYOUTMODE;
// If LED 0 starts at the bottom, we need to invert the rows when we
// display the message.
if (layoutStart==TOPLEFT || layoutStart==TOPRIGHT)
{
rowDir = DOWN;
}
else
{
rowDir = UP;
}
// If we start from the right side, we will be going backwards.
if (layoutStart==TOPLEFT || layoutStart==BOTTOMLEFT)
{
colDir = RIGHT;
}
else
{
colDir = LEFT;
}
fontWidth = FONTWIDTH;
fontHeight = FONTHEIGHT;
fontStartChar = FONTSTARTCHAR;
//Serial.print(F(“Font size : “));
//Serial.print(fontWidth);
//Serial.print(F(“x”));
//Serial.println(fontHeight);
//Serial.flush();
// Loop through each letter in the message.
for (letter=0; letter<msgLen; letter++)
{
// Scroll fontWidth pixels for each letter.
for (offset=0; offset<fontWidth; offset++)
// If you comment out the above for loop, and then just set offset
// to 0, the sign will scroll a character at a time.
//offset = 0;
{
// Loop through each row…
for (row=0; row<ROWS && row<fontHeight ; row++)
{
letterOffset = 0;
fontBit = offset;
// If going down (starting at top), we will use the loop row,
// else we will calculate a row that goes backwards.
if (rowDir==DOWN)
{
rowOffset = row;
}
else
{
rowOffset = (fontHeight<ROWS ? fontHeight : ROWS)-1-row;
}
// Now loop through each pixel in the row (column).
for (col=0; col=msgLen)
{
ch = ‘ ‘;
}
else // Otherwise, get the actual letter.
{
ch = message[letter+letterOffset];
}
// Get the appropriate byte from the font data.
if (bitRead(pgm_read_byte_near(&font[FONTDATAOFFSET+
(ch-fontStartChar)*fontHeight+rowOffset]),
//(colDir==RIGHT ? 7-fontBit : 7-(fontWidth-1)+fontBit))==1)
//(colDir==LEFT ? 7-fontBit : 7-(fontWidth-1)+fontBit))==1)
7-fontBit)==1)
{
// 1 = set a pixel.
strip.setPixelColor((row*LEDSPERROW)+colOffset,
strip.Color(Red1,Grn1,Blu1));
DEBUG_PRINT(F(“#”));
}
else
{
// 0 = unset a pixel.
strip.setPixelColor((row*LEDSPERROW)+colOffset, 0);
DEBUG_PRINT(F(” “));
}
// Move to next bit in the character.
fontBit++;
// If we get to the width of the font, move to the next letter.
if (fontBit >= fontWidth)
{
fontBit = 0;
letterOffset++;
}
} // end of for (col=0; col<LEDSPERROW; col++)
DEBUG_PRINTLN();
// If the LED strips are zig zagged, at the end of each row we
// will reverse the direction.
if (layoutMode==ZIGZAG)
{
// Invert direction.
if (colDir==RIGHT)
{
colDir = LEFT;
}
else
{
colDir = RIGHT;
}
} // end of if (layoutMode==ZIGZAG)
} // end of for (row=0; row<ROWS && row<fontHeight ; row++)
strip.show();
#if defined(DEBUG)
for (uint8_t i=0; i<LEDSPERROW; i++) Serial.print(F("-"));
Serial.println();
#endif
delay(SCROLLSPEED);
} // end of for (offset=0; offset<fontWidth; offset++)
} // end of for (letter=0; letter0)
} // end of loop()
// Simple utility function to return the current free RAM.
unsigned int freeRam() {
extern int __heap_start, *__brkval;
int v;
return (int) &v – (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
} // end of freeRam()
/*—————————————————————————*/
// End of LEDSign
Hi David, I have two questions:
1) What complements the first #include that is empty, in version 0.03 of your sketch? that is, it looks like this:
#define VERSION “0.03”
#include
#include “LEDSign.h”
2) Is it possible to scroll the message on the Led strip without being through the Serial Monitor? Say, a message fixed in the sketch without having to type in the serial.
Thanks
I can help with the input. I was just doing a test when I wrote this, otherwise it would be a routine you just call with a string.
In the loop, there is this:
Serial.print(“Enter message: “);
msgLen = lineInput(message, MAXMSGLEN);
That puts whatever you type in a character buffer called “message”. Instead of those two lines, you could do:
strncpy(message, “This is my message”, MAXMSGLEN);
msgLen = strlen(message);
But it would be cleaner if you commented out (or removed) those two lines:
//Serial.print(“Enter message: “);
//msgLen = lineInput(message, MAXMSGLEN);
and at the top of loop() you could change it to hard code a string instead:
char *message = “This is my message.”;
uint8_t msgLen = strlen(message);
Then it would loop that forever. I really need to make a routine called DisplayMessage() or something and you just pass a string into that, then you could do:
DisplayMessage(“Don’t Panic!”);
I’ll have to do some updates when I get time.
For some reason the blog cuts this part out>>>>>>>>>>>>>>>>>>>
} // end of setup()
void loop() {
// send data only when you receive data:
if (Serial.available() > 2) {
for( int i = 0; i 0)
{
It did it again.
Want to email it? I can post updates to the github, just make sure you have a credit in the version history.
Hey I’m using a WS2812B Neopixel LED strip, just one. It’s 5 meters in length, and has 300 LEDS in total. When I upload the code, nothing happens. Upload completes, but the lights don’t work. I’ve tested these lights elsewhere and they work. My Arduino also works, but I think it’s my configuration of the code, can anyone help?
Do any of the sample programs with the WS LED library work for you?
Yes, all of the WS LED library examples work.
The only config needed should be the ones that define the pins. If you can wire up the strips to the Arduino and they work with the samples, then we should be able to figure out what’s going on with my sketch,
I wonder if it’s just not getting ENTER on the text you type. That has hung some folks up before, as the program is waiting. You have to make sure the line endings are turned on in the Arduino console so it sends them when you type and send a line. Put “#define DEBUG” at the top of the sketch and you will see it print a ton of stuff and that will let you know if it’s working. It will print out what it would be sending to the LEDs.
I tried that, it didn’t work. I put #define DEBUG at the top but it didn’t work. I’m using your 0.02 version
Are you seeing the prompt where you type in your message and all that? If nothing happens past that, it’s not running for some reason.
What prompt? How do I get the prompt? All I see is the Arduino IDE and that’s it.
When it runs, it prints out the config info and version and all that then prompts you to type in a message.
Hey, So I used the Serial Monitor on Arduino IDE to send the message using the Prompt Enter Message: but nothing happens. I send the message, sends successfully but doesn’t display anything.
If you enter something like one letter “A” it should pause for a moment while it is talking tote LEDs, then return to the prompt again. If it doesn’t, it hasn’t gotten the input yet. There is a LINE ENDINGS box in the serial monitor that has to be set a certain way for Arduino to see input.
Ok it works, but I want it to loop the current text forever until I send another text and then loop that one forever. How would I accomplish this? Thank you.
Yeah I never finished up the code. It would be easy to replace the spot where it inputs the text and just hard code a string of text there instead. Are you much of a programmer?
Actually I think I solved it.
Hello there, I’ve been fiddling with the code to run my setup which is basically WS2812b 4 by 6 individual elements that i soldered as “B” configuration shown in your tutorial. The code runs and every thing but only one led lights. The first top-right LED in the array only. please help. Cheers
There is a define that sets the number of LEDs it will use. That must be changed to match how many you have. I usually suggest running one of the Adafruit samples to test things.
Hi David! Is your code working?
#define VERSION “0.03”
#include
#include “LEDSign.h”
What is this “#include” empty at the beginning?
Put a video of your sketch for everyone to see, please!
WordPress eats things thinking it is an html escape code. Anything between greater and less than symbols often disappears.
Sorry Allen Huffman, is this last sketch yours?
I would like to know what this sketch does; thank you
All my code is on my Github, unmolested by WordPress.
Almost works for me. I’m using 7 strips of 60pixel Neopixels. All works well if I run the “strand test” ino. This program works(sort of). It does not put anything in the bottom two strips. I’ve specified the 4×6 font. I’m getting power from an external power supply.
Am I missing something simple?
Maybe. Have you tried lowercase letters? I seem to recall one of the TV Out fonts was like the old dot matrix printers of the 80s and didn’t use bottom rows except for a few lowercase letters. Might be that.
I am fairly sure I tested it with 8 strips.
No joy on the fonts. I actually looked at the font files and none of the characters use the bottom row. I’ll just use the 6×8 font and add another strip.
Thanks for this project.
I have a holiday light show using LightshowPi. I modified that code to use MQTT to publish the current song name/artist. I’m running your(slightly modified to support MQTT) on a NodeMCU. When it receives an MQTT message with the new song name it updates the sign. Obviously I’m powering the strips from a beefy external supply. But it all works(on the bench). Now to move it to the yard.
am amazed to see this update. kindly show how I can do it, I have some nodeMCU I can use as this match what I search for.
kindly give the code and the procedure. am not a coder yet, just learning by lay hands on these projecs type..
Thanks for this project you shared and yet replying time to time has helped to more and more. But my problem remained unsolved.
I mistakenly shipped ws2811 12v 4packed*5meter strips from China. I purchased ws2812b, individual addresable. While paid, after shipping, it turned out to be 1 chip per 3 LEDs.
Can it still run with this code?
What do I do, how to modify the code or where can I get solution?
I used strand examples , they sometimes just up and never blink, some slow…
All I want to make is scrolling text through Bluetooth and Android.
I have read bunch of …
no understanding yet
Thanks in advance
I don’t have access to any of my LED stuff to look in to this, currently.
I have only worked with the two types of addressable LEDs listed in the article. If it treats three LEDs as one light source, you would probably just get a larger “fat pixel” display for the letters. The main thing is it must be supported by that LED library my code uses. I would start there and see if they are supported.
I’m getting an error that fontAll.h is non-existent
I have the tvfonts library installed
Things may have changed since I originally wrote this. You can find the TVOut fonts here in their Github: https://github.com/Avamander/arduino-tvout/tree/master/TVoutfonts
Hi Allen
Didn’t you want to scroll the text in multiple colors (RGB)?
There are two things I would love to do:
1) Change the LED driver so it is far more memory efficient. Rather than every pixel taking a blog of memory for colors, I’d change each pixel to 4-bits (16 colors from a palette) or 8-bits (256 colors from a palette) which is more than enough for many uses. The driver would look up the palette values and send those to the LEDs, rather than sending out the values from the current LED glob. This could increase the number of pixels supported by 3X+ easily. This would require assembly (the LED drivers bit band using assembly) and is beyond my skillset.
2) It would be trivial to add color support to my example code just by adding an escape sequence to the string, and having the parser set the colors as it renders. If I ever get the LED stuff again, I would revisit this project and add that.
Thanks for the answer; and do you intend to do that?
I’d definitely tackle 2. I just no longer have my LED strip setup.
Looks like David Duce (in comments above) has modifications for color.