Unknown Domain

The Twitter Message Display

Over the Easter weekend I have been working on one of several parts of my final pieces, the moving message display, and I have managed to near enough complete it today.

The display was bought from Maplin, I managed to get a discount of 5% because it had a slight mark on the display which I haven't noticed since so I bought it for £75.99 (from £79.99) at the Maplin on the Strand.

Its very bright and comes with drivers and software only for Windows so I used my parents computer to try and reverse engineer it by monitoring the data it sent using the Windows program I knew I would be able to work out how it worked and make a Mac equivalent using Processing.

Eventually I worked out how it worked, it sends a message to the display in side tags... <ID00> is the first tag and the last two digits determine which display will be responding, in this case 00 means all displays, mine is display 01 and if you address each display directly you get a confirmation message back so I used <ID01>. Each command is then ended with <E> and there are various types of data to go in the middle.

I discovered through experimentation that unfortunately when the command is sent to the display it creates something called a checksum which is a way of adding up the values of all the bits of information sent and creating a short number which the display at the other end then checks to see that it adds up too, any errors and it will send back an error message to the computer.

I discovered by searching the first bit of code in google that other people had tried to make this display work too and while some encountered no checksum others did, which made me realise there must be several displays with the same communication protocol.

After a lot of experimenting with it I finally got some code which would send a message to the display nearly all the time without issues. However I still had to send it Twitter messages so I made another program which listed them out to the screen, once I had a small prototype working I could get it to send them to the message display. After some work last night and today I had a Twitter Message Display which works nearly all the time without issue however some times the display gets confused and will keep sending error messages back so I have created a system where it will send the whole message again and again till it works rather than just giving up.

The only problem is at the moment it will work through 20 tweets from the public timeline and then just stop so I need to work out how to get more.

UPDATE 26/11/2014: Check out the communications protocol manual thanks to Alexander Stohr.

The code:

import processing.serial.*;
int message_no = 0;
String message;
int state = 0;
boolean ready = true;
Serial display;
Twitter twitter;
int num_messages;

void setup() {
display = new Serial(this, Serial.list()[0]);
twitter = new Twitter("username", "password");
}

 

void draw() {

if (state == 0) {

try {
java.util.List statuses = twitter.getPublicTimeline();

Status status = (Status)statuses.get(message_no);
message = status.getText();

num_messages = statuses.size();

}

catch (TwitterException e) {
println(e.getStatusCode());
}

if (message.length() > 239) {
message_no++;
}

}

updateDisplay();

}

String outputMessage() {
String theseChars = "05
" + message + "06";
char check = 0;
for (int c = 0; c < theseChars.length(); c++) {
check = char(check ^ theseChars.charAt(c));
}
return "
" + message + hex(check, 2) + "";
}

void updateDisplay() {

if (display.available() > 2) {

String serialData = display.readString();

if (serialData.equals("ACK")) {
state++;
ready = true;
} else {
state = 0;
ready = true;
println(" I broke a bit, hold on a second...");
}

println(" " + serialData);

}

 

if (ready) {
if (state == 0) {
display.write("05");
ready = false;
} else if (state == 1) {
display.write(outputMessage());
ready = false;
} else if (state == 2) {
display.write("06");
ready = false;
} else if (state == 3) {
println(message_no + ": " + message + " - display updated!");
delay(1325 + (message.length() * 90));
message_no++;
state = 0;
ready = true;
if (message_no >= num_messages) { exit(); }
}
}
}