#NaughtyOrNice

Today we’re playing with the Twitter API and 20 LEDs, in the form of 2 10-segment bar graph displays! We are going to help Father Christmas figure out if people are being naughty or nice minute by minute.

twitter_hero

You’ll need:

  • 1 red 10-segment bar graph (or 10 red LEDs)
  • 1 green 10-segment bar graph (or 10 green LEDs)
  • 2 shift registers
  • Arduino Uno
  • Breadboard + wires

1) Working with the Twitter API
Initially, I wanted to use the twitter4j library for Processing, but I couldn’t get it to work properly, so I ended up using the twitter module for node. The javascript file is as follows:

var util = require('util'),
    twitter = require('twitter'),
    fs = require('fs');
var twit = new twitter({
    consumer_key: 'xxx',
    consumer_secret: 'xxx',
    access_token_key: 'xxx',
    access_token_secret: 'xxx'
});

Instantiate your modules, you will also need to create a Twitter App to get your consumer key and access token (replace the ‘xxx’ above by the tokens generated by Twitter).

var tweetNiceCount = 0;
var niceTweets = [];
var tweetNaughtyCount = 0;
var naughtyTweets = [];
var current_date = new Date().getMinutes();
var canUpdateNice = true;
var canUpdateNaughty = true;

Set up all your variables.


setInterval(function(){
	if(current_date != new Date().getMinutes()) {
		tweetNiceCount = 0;
		tweetNaughtyCount = 0;
		niceTweets = [];
		naughtyTweets = [];
		canUpdateNice = true;
		canUpdateNaughty = true;
		current_date = new Date().getMinutes();
	}

	twit.search('#nice', {count:100}, function(data) {

    for(var i = 0; i  0) {
  				for(var j = 0; j< niceTweets.length; j++) {
  					if(niceTweets[j]==util.inspect(data.statuses[i].id)){
  						canUpdateNice = false;
  					} else {
  						canUpdateNice = true;
  					}
  				}
  			}

  			if(canUpdateNice) {
  				tweetNiceCount++;	
  			}

    		niceTweets.push(util.inspect(data.statuses[i].id));
    	}	
    }

    console.log("NICE::", tweetNiceCount);
});

twit.search('#naughty', {count:100}, function(data) {

    for(var i = 0; i  0) {
  				for(var j = 0; j< naughtyTweets.length; j++) {
  					if(naughtyTweets[j]==util.inspect(data.statuses[i].id)){
  						canUpdateNaughty = false;
  					} else {
  						canUpdateNaughty = true;
  					}
  				}
  			}

  			if(canUpdateNaughty) {
  				tweetNaughtyCount++;	
  			}

    		niceTweets.push(util.inspect(data.statuses[i].id));
    	}	
    }

    console.log("NAUGHTY::",tweetNaughtyCount);
});

	if(tweetNiceCount!=0 || tweetNaughtyCount!=0){
		updatePercentage();	
	}
}, 12000);


We set an interval, to make calls to Twitter every 12 seconds (the limit on Twitter is approximately a call every 5 seconds, but we're making 2 calls at once, and I've added a small margin, to avoid any errors). For each hashtag, #nice or #naughty, we check what time they were tweeted; if the minute they were sent corresponds to the current minute, we check if we've already considered it, and if not, increase the counter.

We reset everything each minute.

function updatePercentage() {
	var naughtyPerten = Math.round((tweetNaughtyCount/ (tweetNaughtyCount + tweetNiceCount))*10);
	var nicePerten = Math.round((tweetNiceCount/ (tweetNaughtyCount + tweetNiceCount))*10);
	var naughtyString = "00";
	var niceString = "00";

	if(naughtyPerten!=10) {
		naughtyString = "0"+naughtyPerten;
	} else {
		naughtyString = "10";
	}

	if(nicePerten!=10) {
		niceString = "0"+nicePerten;
	} else {
		niceString = "10";
	}
	var toSave = ''+niceString+''+naughtyString;
	fs.writeFile("tweets.txt", toSave, function(err) {
    if(err) {
        console.log(err);
    } else {
        console.log("The file was saved!");
    }
});
}

Finally, we determine the ratio, out of ten of naughty and nice tweets. And we save the result in a text file as a string of 4 digits, the count for nice being the first 2 digits (we prepend a 0 if the number is lower than 10).

2) The 10-segment displays
I realise the code above is already pretty long to read, so if you've made it that far, well done! I'm not going to go into too much detail for the rest of it, if you need some instructions on shift registers and LEDs, I recommend you check yesterday's post.

Wiring 1 shift register with a ten-segment display will give you control over 8 lights (like on the example below), the two remaining ones will need to be wired to Arduino pins.

To obtain the effect below, just loop through the same array, but assign the value at index arrayLength - i to your second display (wired to a second shift register).

3) Integration
Finally, using Processing and serial communication, we open the text file that we saved earlier.
And we check the file every 2 seconds; I followed this tutorial by Daniel Shiffman for this.

import processing.serial.*;

Serial port;
int savedTime;
int totalTime = 2000;

void setup() {
 size(200,200);
 port = new Serial(this, Serial.list()[8], 9600);
 port.bufferUntil('\n');

 String[] lines = loadStrings("tweets.txt");
 port.write(lines[0]);
 port.write('\n');
//We send the data once, and then we'll send it after 2 seconds.
 
 savedTime = millis();
 

}

void draw() {
  int passedTime = millis() - savedTime;
  if (passedTime > totalTime) {
    String[] lines = loadStrings("tweets.txt");
     port.write(lines[0]);
     port.write('\n');
    savedTime = millis();
  }
}

Again, to read incoming data in Arduino and display the result accordingly, have a look either at yesterday's post or the Countdown to Christmas hack.

And we've got a Naughty and Nice list that will help Santa see what the trend is minute by minute:

twitter_graph

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s