Towards better software

Putting My LED Sign on the Internet

  • March 6, 2016

When I was in school at the University of Illinois in the 90's a particular student project caught my attention. There was a hobby-built LED sign hanging in the Computer Science building hooked up to an email address. You could email the sign and see your message scroll by. Designing and building an LED sign would stretch my skills into new areas. I had a lot to learn about electronics and was really looking forward to coding for a microcontroller. A few years out of school I did end up building an LED sign. I used an Atmel AVR at90s8515 with 8K of flash and 512 bytes or SRAM. The sign uses 8 5 X 8 LED arrays to make a 40 X 8 array and can recieve messages over RS232 serial. I'll probably write more about the sign at some point, but this post is about giving the sign an email address.

The AVR at90s8515 is not very capable by today's standards and not suitable for hooking up directly to the internet. If I was building this sign today I would probably using something like the Raspberry Pi and have everything I needed right out of the box. I'm not going to build this sign again, so I'll have to rely on the serial port and use something else to actually retrieve email. A Raspberry Pi is perfect for the job. To handle the RS232 serial I bought a shield that gives me a 9 pin serial connection - less than $10 on Amazon.

Raspberry Pi with RS232 Serial Shield

The sign maintains a FIFO queue of messages. Messages in the queue are continously scrolled until new messages are added that force the old messages out. The idea is simply to recieve emails on an email address and add them to the queue on the sign. The serial protocal implemented in the sign requires that messages start with STX and end with ETX ascii characters (0x02 and 0x03) - you'll see that in the code below. There is also a semaphore used to ensure that only one message is being written to the sign at a time.

The code on the Raspberry Pi needs to handle:

  • Retrieving email from a gmail account.
  • If the subject starts with 'scroll: ' then send the rest of the subject to the LED sign.
  • Run continuosuly, checking email every 10 minutes.
  • Remember messages that are already scrolled so that they are not added to the sign again.

I chose to write my code using Node.js and use Redis to help with remembering messages that are already scrolled. The code below handles the job nicely. This deep nesting is begging for an async library like Bluebird, but I didn't want to introduce extra complexity in the blog listing. The node-fibers library is supposed to allow node to handle other events while the loop in this code sleeps (timeout). I will find out if I did this correctly when I add a web front-end that allows users to add messages on a web sign.

var Fiber = require('fibers');
var MailParser = require("mailparser").MailParser;
var mailparser = new MailParser();
var redis = require("redis");
var redisclient = redis.createClient();
var SerialPort = require("serialport").SerialPort
var serialPort = new SerialPort("/dev/ttyAMA0", {
  baudrate: 9600
}, false);

var Client = require('yapople').Client;
var client = new Client({
  hostname: '',
  port:  995,
  tls: true,
  mailparser: true,
  username: '',
  password: 'xxxxxxxx'

var Semaphore = require("node-semaphore");
var pool = Semaphore(1);

redisclient.on("error", function (err) {
    console.log("Error " + err);

function work() {
    var fiber = Fiber.current;

    while(true) {

        client.connect(function() {
	    // Retrieve all email messages from the account
            client.retrieveAll(function(err, messages) {
        	try {
                    messages.forEach(function(message) {
                        var subject = message.subject.toString();
                        // Look for messages with subjects that start with 'scroll: '
                        if (/^scroll/.test(subject)) {
                            subject = subject.substring(8);
                            redisclient.exists(subject, function(err, value) {
                                if (value == 1) {
                                    console.log("Message already scrolled: " + subject);
                                } else {
                                    redisclient.set(subject, subject);
                                    pool.acquire(function() {
                                        // Add message to sign
                                            if (error) {
                                                console.log('failed to open: '+error);
                                            } else {
                                                var send = String.fromCharCode(2) + subject + String.fromCharCode(3);
                                                serialPort.write(send, function(err, results) {
                                                    if (err) {
                                                        console.log('err ' + err);
                                                    } else {
                                                        console.log('results ' + results);
                                            console.log("New message: " + subject);
                } catch (err) {
                    console.log("Error: " + err.message);

        setTimeout(function() {
        }, 300000);
Fiber(function() { work(); }).run();

Here is the sign with a message scrolling.  Serial input and power come in on the left. The large chip towards the left is the AVR microcontroller. The sign was based on a parallel port design in an electronics magazie. I used most of the electronics, but replaced the paralllel port input with a microcontroller. I am happy to share more detail on this sign and the C code, but only some of it would be applicable. There are much better microcontrollers availalbe nowadays and boards like the Pi and Arduino to get a project like this started.

LED Scrolling SignLED Scrolling Sign