09 April 2013

Arduino Facebook like-counter with 7 segment display

Last year I wanted to be able to follow the amount of likes on a website, but not by looking at a Facebook or the website itself. I made an IRL display with the amount of likes with an Arduino.

The case
I created an PHP-script, using the Facebook API, checking the amount of likes and just outputting it. My Arduino would regularly check for the value outputted by my PHP script and display this on its display.

Requirements
The stuff I used is:


Result
Check this video for the results:

My Arduino code looks like this:

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
char serverName[] = "xxxxxxxx.nl"; //location of PHP script telling me the amount of likes

const int latchPin = 8;
const int clockPin = 3;
const int dataPin = 9;
byte chars[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0xf7,0xfb,0xab,0x86}; //0-9," ", -, _,i,n,e

// 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;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  
  //Put "ini" on the dis
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[13]);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[14]);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[13]);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
  shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
  digitalWrite(latchPin, HIGH);
  
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    //Put "e" (error) on the dis
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[15]);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    digitalWrite(latchPin, HIGH);
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
}

void loop()
{
  checkOnlineStatus();
  delay(2000);
}

void checkOnlineStatus()
{
  //Serial.println("connecting...");
  boolean newLine = true;
  String line = "";
  
  if (client.connect(serverName, 80)) {
    //Serial.println("connected");
    // Make a HTTP request:
    client.println("GET / HTTP/1.0");
    client.println("Host: rogier.nu");
    client.println();
  }
  
while(client.available()){
    char c = client.read();
    //Serial.print(c);
    
    // if you've gotten to the end of the line (received a newline
    // character) and the line is blank, the http request has ended,
    // so you can send a reply
    if (c == '\n' && newLine) {
      
    }
    if (c == '\n') {
      // you're starting a new line
      newLine = true;
      line = "";
    } 
    else if (c != '\r') {
      // you've gotten a character on the current line
      newLine = false;
      line += c; 
    }
  }
  

  processLine(line);

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    client.stop();
  }
}

void processLine(String line)
{
  if(line.length() > 0) {
    //Serial.println("Verwerken:" + line);

    digitalWrite(latchPin, LOW);

    //Putting up the online value
    for(int i=line.length()-1; i >= 0; i--)
    {
      int bitToSet = (byte)line.charAt(i) - 48;
      shiftOut(dataPin, clockPin, MSBFIRST, chars[bitToSet]);
    }
    
    //Putting up the leading zeroes
    for(int i=0; i<8-line.length(); i++)
    {
      shiftOut(dataPin, clockPin, MSBFIRST, chars[10]);
    }
    
    digitalWrite(latchPin, HIGH);
  }
 }
Improvements
My sketch is relying on an external PHP-script, to make the Arduino code as simple as possible. A better way to do this is by having the Arduino make direct connections to Facebook, as is done in this project: Facebook Like box