/**/
LaikaBOT

../LaikaBOT

/Projects/

LED Internet Sign

The LED Internet Sign is a physical LED sign that lives in my home office. You are able to send messages to it from the live web feed below.

 

LED Internet SignAdd your email address here to be notified on the days I open the sign up for play.

 

This project is a favourite of mine as I like the idea of people interacting with real world devices over the Net.

 

(Click Here to see my instructable on how to build one for yourself)


Make sure you check out the instructable on how to build this.





Send your message via the form fields below.






 

The following is the sketch uploaded directly to the Arduino.

 

Basically, it is hitting a php script on the server which retrieves the next unread message in the list and returns it to the Arduino for display on the LED signs.

 

In this instance I have hooked up the LED displays in a 4 across x 1 high setup.

 

NOTE: I have also used a Freetronics WatchDog chip to ensure the sign keeps running. If the watchdog does not get pinged by the specified lines in the code within a minute, it reboots the Arduino. I added this as it appeared that every 600 messages or so, the Ardiuino would just hang and I couldn't locate the reason why. This was the next best option.

 

Instructables - Click Here to see my instructable on how to build this project

 


/*
This sketch let's people send live messages from my website to the LED sign in my home office

The person sending the message can watch it being delivered to the LED Internet Sign in real time via a webcam on the same page.

Created by Nat Abood 2012
*/

 

#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "Arial_black_16.h"
#include <Ethernet.h>
#include <stdlib.h>

#define DISPLAYS_ACROSS 4
#define DISPLAYS_DOWN 1

 

// Enter a MAC address for your controller below.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.laikabot.com";

String theMessage;
String cStuff;
int stars = 0;
int watchDog = 2;


// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
IPAddress ip(192, 168, XXX, XXX); // REPLACE THE X's WITH WHATEVER INTERNAL IP YOU ASSIGN YOUR ARDUINO TO
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

 

/*--------------------------------------------------------------------------------------
Interrupt handler for Timer1 (TimerOne) driven DMD refresh scanning, this gets
called at the period set in Timer1.initialize();
--------------------------------------------------------------------------------------*/
void ScanDMD()
{
dmd.scanDisplayBySPI();
}

//----------------------
void connectMe (){

delay(1000);
Serial.println("connecting...");

// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected");
httpReq();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
}

}

//----------------------
void httpReq(){

// Make a HTTP request:
client.println("GET /XXXXX/XXXXX.PHP HTTP/1.0"); // REPLACE WITH ADDRESS OF YOUR PHP PAGE ON THE SERVER
client.println("Host: www.laikabot.com");
client.println("Connection: keep-alive");
client.println();
}

//----------------------
void resetWatchdog() {
digitalWrite(watchDog, HIGH);
delay(20);
digitalWrite(watchDog, LOW);
}

//----------------------
void setup() {

// set the Pin Mode for the watchDog Timer module
pinMode(watchDog, OUTPUT);
resetWatchdog();

// start the serial library:
Serial.begin(9600);
Serial.println("Starting Up....");

// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");

    Ethernet.begin(mac, ip);
}

//initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
Timer1.initialize( 5000 ); //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
Timer1.attachInterrupt( ScanDMD ); //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()

//clear/init the DMD pixels held in RAM
dmd.clearScreen( true ); //true is normal (all pixels off), false is negative (all pixels on)
dmd.selectFont(Arial_Black_16);

// Connect to site
resetWatchdog();
connectMe();
}

//----------------------
void loop(){

    // if the server's disconnected, stop the client:

if (!client.connected()) {
    client.stop();
    //reconnect the server
    connectMe();
}


resetWatchdog();


// if there are incoming bytes available from the server, read them and print them:
if (client.available()) {

    char c = client.read();

    if (stars == 3){ // Read the number prefixes of 3 stars. I use this to identify where in the returned content to start reading the message.
        if (c != '*'){
            theMessage = theMessage + c; // Build the message string
        }


        if (c == '*') { // After reading the message - check for * suffix. I use this to indicate the end of the         returned message


            // Update the display and show the full message
            int myTextLength = theMessage.length();
            char messageChar[300] = "";
            theMessage.toCharArray(messageChar,myTextLength+1);
            dmd.drawMarquee(messageChar,myTextLength,(32*DISPLAYS_ACROSS)-1,0);
            long start=millis();
            long timer=start;
            boolean ret=false;
            while(!ret){
                if ((timer+30) < millis()) {
                    ret=dmd.stepMarquee(-1,0);
                    timer=millis();

 

                }
            }


            // Clear everything - the message has been displayed
            stars = 0;
            client.flush();
            c = 'a';
            theMessage = "";
            resetWatchdog();
            if (client.connected()){
                httpReq();
            }


        }
    }

 

 

    if (c == '*') { // Increment the ster prefix counter
        stars ++;
        String numStars = String(stars);
    }

    if (c == NULL){
        httpReq();
        resetWatchdog();

    }

    }

}