Here’s 4 seconds of it in action. It should be longer but youtube doesn’t like it for some reason. You can see a few letters of a message.
//Very initial code borrowed from this example:
//**************************************************************//
// Name : shiftOutCode, Hello World //
// Author : Carlyn Maw,Tom Igoe //
// Date : 25 Oct, 2006 //
// Version : 1.0 //
// Notes : Code for using a 74HC595 Shift Register //
// : to count from 0 to 255 //
//****************************************************************
//Pin connected to ST_CP of 74HC595
int latchPin = 9;
//Pin connected to SH_CP of 74HC595
int clockPin = 8;
////Pin connected to DS of 74HC595
int dataPin = 11;
int enablePin = 10; //Active Low!
//int col[5] = {6,5,2,3,4};
int col[5] = {4,3,2,5,6};
byte row;
byte pattern[80];
byte frame[5] = {B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
};
int i;
int cycles = 0;
int framenum = 0;
int totalframes = 100;
int newline;
int reading_flag = 0;
int readindex = 0;
unsigned long read_timeout;
unsigned long req_timeout = 0;
int nextcheck = 1000;
//——States——
int state = 0;
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(enablePin, OUTPUT);
for(i = 0; i pinMode(col[i], OUTPUT);
}
Serial.begin(9600);
}
void loop() {
for (int j = 0; j
//Set all the column registers high, except the columnwe want to show
for(i = 0; i digitalWrite(col[i], HIGH);
}
digitalWrite(col[j],LOW);
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, LOW);
//disable the outputs while we are shifting
digitalWrite(enablePin, HIGH);
shiftOut(dataPin, clockPin, MSBFIRST, frame[j]);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, HIGH);
//enable the outputs
digitalWrite(enablePin, LOW);
delay(1);
//digitalWrite(col[j],HIGH);
}//done displaying frame
if (Serial.available() > 0) {
newline = Serial.read();
for (int j = 0; j frame[j] = frame[j] }
frame[0] = frame[0] | (newline & 1) == 1;
frame[1] = frame[1] | (newline & 2) == 2;
frame[2] = frame[2] | (newline & 4) == 4;
frame[3] = frame[3] | (newline & 8) == 8;
frame[4] = frame[4] | (newline & 16) == 16;
}
}
import processing.serial.*;
class twit {
String description;
int[] bytes = new int[len*5];
int pxlength;
twit () {
description = “”;
pxlength = 0;
}
void update () {
nextpos = 0;
for(int c = 0; c description = description.toLowerCase();
bytes = addLetter(description.charAt(c), bytes, nextpos+1);
}
pxlength = nextpos;
}
void drawpx (int xref, int yref) {
for(int x = 0; x if((bytes[x] & 1) == 1) {point(x+xref, yref+0);}
if((bytes[x] & 2) == 2) {point(x+xref, yref+1);}
if((bytes[x] & 4) == 4) {point(x+xref, yref+2);}
if((bytes[x] & 8) == 8) {point(x+xref, yref+3);}
if((bytes[x] & 16) == 16) {point(x+xref, yref+4);}
}
}
}
int bits=5;
int len=200;
int i = 0, j = 0;
int sqrsize = 5;
int centerx, centery;
float avg;
float bias = .1;
int xpos, ypos;
float h = random(0,255);
int rowint[] = new int[len];
String lines[] = new String[20];
String new_lines[] = new String[20];
twit tweets[] = new twit[20];
int black = 0;
int nextpos = 0;
int next_tw_refresh = 30*60;
int current_twitter = 0;
int next_line = 0;
int rate = 15;
Serial myPort;
void setup()
{
background(255);
colorMode(RGB, 255);
ellipseMode(CORNERS);
strokeWeight(1);
noSmooth();
frameRate(30);
centerx = width/2;
centery = height/2;
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
for(i = 0; i tweets[i] = new twit();
}
update_twits();
size(len*sqrsize, lines.length*sqrsize+1); // Size should be the first statement
}
void draw()
{
background(255);
stroke(255,0,0);
line(125,0,125,400);
stroke(0);
for(int count = 0; count tweets[count].drawpx(0,count*(sqrsize+1));
}
if(frameCount > next_tw_refresh) {
println(“Refreshing messages…”);
next_tw_refresh = frameCount + 3000; //30 fps x 60 seconds
print(frameCount);
update_twits();
}
if(frameCount > next_line_time) {
myPort.write(tweets[current_twitter].bytes[nextline]);
nextline++;
if(nextline >= tweets[current_twitter].pxlength) {current_twitter++;}
if(current_twitter >= 20) {current_twitter = 0;}
}
}
void update_twits() {
new_lines = loadStrings(“http://linuxbox.dotmatrixdesign.net/~david/twit.php”);
if(new_lines[0] != lines[0]) {
lines = new_lines;
current_twitter = 0;
for (int i=0; i tweets[i].description = lines[i];
tweets[i].update();
}
println(“new Twitters downloaded”);
}
}
void write_to_arduino (twit tosend) {
myPort.write(‘w’);
/*for(i = 0; i myPort.write(byte(tosend.bytes[i]));
print(tosend.bytes[i]);
print(” “);
delay(15);
}*/
myPort.write(byte(tosend.bytes));
print(byte(tosend.bytes));
println(“sent”);
}//end write
int[] addLetter(char letter, int bytes[], int startpos) {
int col[] = new int[8];
String colstr[] = new String[8];
int letter_length;
String zeros = “000”;
switch (letter) {
case ‘a’:
colstr[0] = “11110”;
colstr[1] = “00101”;
colstr[2] = “11110”;
letter_length = 3;
break;
case ‘b’:
colstr[0] = “11111”;
colstr[1] = “10101”;
colstr[2] = “01010”;
letter_length = 3;
break;
case ‘c’:
colstr[0] = “01110”;
colstr[1] = “10001”;
colstr[2] = “10001”;
letter_length = 3;
break;
case ‘d’:
colstr[0] = “11111”;
colstr[1] = “10001”;
colstr[2] = “01110”;
letter_length = 3;
break;
case ‘e’:
colstr[0] = “11111”;
colstr[1] = “10101”;
colstr[2] = “10101”;
letter_length = 3;
break;
case ‘f’:
colstr[0] = “11111”;
colstr[1] = “00101”;
colstr[2] = “00101”;
letter_length = 3;
break;
case ‘g’:
colstr[0] = “01110”;
colstr[1] = “10001”;
colstr[2] = “10101”;
colstr[3] = “11101”;
letter_length = 4;
break;
case ‘h’:
colstr[0] = “11111”;
colstr[1] = “00100”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ‘i’:
colstr[0] = “10001”;
colstr[1] = “11111”;
colstr[2] = “10001”;
letter_length = 3;
break;
case ‘j’:
colstr[0] = “11100”;
colstr[1] = “10000”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ‘k’:
colstr[0] = “11111”;
colstr[1] = “00100”;
colstr[2] = “01010”;
colstr[3] = “10001”;
letter_length = 4;
break;
case ‘l’:
colstr[0] = “11111”;
colstr[1] = “10000”;
colstr[2] = “10000”;
letter_length = 3;
break;
case ‘m’:
colstr[0] = “11110”;
colstr[1] = “00001”;
colstr[2] = “11110”;
colstr[3] = “00001”;
colstr[4] = “11110”;
letter_length = 5;
break;
case ‘n’:
colstr[0] = “11111”;
colstr[1] = “00010”;
colstr[2] = “00100”;
colstr[3] = “11111”;
letter_length = 4;
break;
case ‘o’:
colstr[0] = “11111”;
colstr[1] = “10001”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ‘p’:
colstr[0] = “11111”;
colstr[1] = “00101”;
colstr[2] = “00111”;
letter_length = 3;
break;
case ‘q’:
colstr[0] = “11111”;
colstr[1] = “10001”;
colstr[2] = “11111”;
colstr[3] = “01000”;
letter_length = 4;
break;
case ‘r’:
colstr[0] = “11111”;
colstr[1] = “00101”;
colstr[2] = “11010”;
letter_length = 3;
break;
case ‘s’:
colstr[0] = “10111”;
colstr[1] = “10101”;
colstr[2] = “11101”;
letter_length = 3;
break;
case ‘t’:
colstr[0] = “00001”;
colstr[1] = “11111”;
colstr[2] = “00001”;
letter_length = 3;
break;
case ‘u’:
colstr[0] = “11111”;
colstr[1] = “10000”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ‘v’:
colstr[0] = “00111”;
colstr[1] = “11000”;
colstr[2] = “00111”;
letter_length = 3;
break;
case ‘w’:
colstr[0] = “01111”;
colstr[1] = “10000”;
colstr[2] = “01111”;
colstr[3] = “10000”;
colstr[4] = “01111”;
letter_length = 5;
break;
case ‘x’:
colstr[0] = “11011”;
colstr[1] = “00100”;
colstr[2] = “11011”;
letter_length = 3;
break;
case ‘y’:
colstr[0] = “00111”;
colstr[1] = “11100”;
colstr[2] = “00111”;
letter_length = 3;
break;
case ‘z’:
colstr[0] = “11001”;
colstr[1] = “10101”;
colstr[2] = “10011”;
colstr[3] = “10001”;
letter_length = 4;
break;
case ‘0’:
colstr[0] = “01110”;
colstr[1] = “10001”;
colstr[2] = “01110”;
letter_length = 3;
break;
case ‘1’:
colstr[0] = “00010”;
colstr[1] = “11111”;
letter_length = 2;
break;
case ‘2’:
colstr[0] = “11010”;
colstr[1] = “10101”;
colstr[2] = “10010”;
letter_length = 3;
break;
case ‘3’:
colstr[0] = “10101”;
colstr[1] = “10101”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ‘4’:
colstr[0] = “00111”;
colstr[1] = “00100”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ‘5’:
colstr[0] = “10111”;
colstr[1] = “10101”;
colstr[2] = “01001”;
letter_length = 3;
break;
case ‘6’:
colstr[0] = “11111”;
colstr[1] = “10101”;
colstr[2] = “11101”;
letter_length = 3;
break;
case ‘7’:
colstr[0] = “11001”;
colstr[1] = “00101”;
colstr[2] = “00011”;
letter_length = 3;
break;
case ‘8’:
colstr[0] = “11111”;
colstr[1] = “10101”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ‘9’:
colstr[0] = “00111”;
colstr[1] = “00101”;
colstr[2] = “11111”;
letter_length = 3;
break;
case ’ ‘:
colstr[0] = “00000”;
colstr[1] = “00000”;
letter_length = 2;
break;
case ‘!’:
colstr[0] = “10111”;
letter_length = 1;
break;
case ‘.’:
case ‘,’:
colstr[0] = “10000”;
letter_length = 1;
break;
case ‘:’:
colstr[0] = “01010”;
letter_length = 1;
break;
case ‘/’:
colstr[0] = “11000”;
colstr[1] = “00100”;
colstr[2] = “00011”;
letter_length = 3;
break;
case ‘\’:
colstr[0] = “00011”;
colstr[1] = “00100”;
colstr[2] = “11000”;
letter_length = 3;
break;
case ‘+’:
colstr[0] = “00100”;
colstr[1] = “01110”;
colstr[2] = “00100”;
letter_length = 3;
break;
case ‘-‘:
colstr[0] = “00100”;
colstr[1] = “00100”;
colstr[2] = “00100”;
letter_length = 3;
break;
case ‘@’:
colstr[0] = “11111”;
colstr[1] = “10001”;
colstr[2] = “11101”;
colstr[3] = “11101”;
letter_length = 4;
break;
case ‘?’:
colstr[0] = “00001”;
colstr[1] = “10101”;
colstr[2] = “00111”;
letter_length = 3;
break;
case ‘'’:
colstr[0] = “00011”;
letter_length = 1;
break;
case ‘*’:
colstr[0] = “00010”;
colstr[1] = “00111”;
colstr[2] = “00010”;
letter_length = 3;
break;
case ‘(‘:
colstr[0] = “01110”;
colstr[1] = “10001”;
letter_length = 2;
break;
case ‘)’:
colstr[0] = “10001”;
colstr[1] = “01110”;
letter_length = 2;
break;
default:
colstr[0] = “11111”;
colstr[1] = “11111”;
colstr[2] = “11111”;
letter_length = 3;
break;
}
for(int ch = 0; ch colstr[ch] = zeros.concat(colstr[ch]);
bytes[startpos+ch] = unbinary(colstr[ch]);
}
nextpos = startpos + letter_length;
return(bytes);
}
$ch = curl_init();
// set URL and other appropriate options
$test_str = “http://twitter.com/statuses/friends_timeline/davidnin.xml”;
curl_setopt($ch, CURLOPT_URL, $test_str);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
// grab URL and pass it a string
$str = curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
if (!$myxml=simplexml_load_string($str)) {
echo ‘Error reading the XML file’;
}
foreach($myxml as $status){
echo $status->{‘user’}->{‘screen_name’} . “: ” . $status->{‘text’} . “\n”;
} //end for each status
?>
…with a couple of slight tweaks of course. (note the tiny green and yellow wires)