The Final Product

I thought we probably should have shared with you all the results so here we are!

20140326_131837

We detected where the ball was using a ‘break the beam’ style and recorded the events from the Arduino in Processing using Firmata. Here is the code for those interested:

import twitter4j.conf.*;
import twitter4j.*;
import twitter4j.auth.*;
import twitter4j.api.*;
import java.util.*;
import processing.video.*;
import processing.serial.*;
import cc.arduino.*;

Arduino arduino;

Twitter twitter; //twitter instance
String searchString = “#heyHoLetsGoBall”; //hashtag to search for
List<Status> tweets; //list of tweets

Capture cam; //camera

int currentTweet; //int to hold the current number of tweets
int runsDone = 0; //how many times has the run function completed
int runTime = 0;
int sensitivity = 10;

int elevatorPin = 3;
int sector1LED = 8;
int sector2LED = 7;
int sector1Gate = 0;
int sector2Gate = 1;

void setup()
{
size(640, 480);

arduino = new Arduino(this, Arduino.list()[0], 57600);
arduino.pinMode(elevatorPin, Arduino.OUTPUT);
arduino.pinMode(sector1LED, Arduino.OUTPUT);
arduino.pinMode(sector2LED, Arduino.OUTPUT);
arduino.pinMode(sector1Gate, Arduino.INPUT);
arduino.pinMode(sector2Gate, Arduino.INPUT);
arduino.digitalWrite(sector1LED, Arduino.HIGH);
arduino.digitalWrite(sector2LED, Arduino.HIGH);
//analog read 0 and 1 for gates

String[] cameras = Capture.list(); //list of available cameras

if (cameras.length == 0) {
println(“No cameras available”);
exit();
}
else {
println(“Cameras available:”);
for (int i = 0; i < cameras.length; i++) {
println(cameras[i]);
}

cam = new Capture(this, cameras[1]);
cam.start(); //start camera 
}

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey(“TOwvucqrfEsfkOHKy7DhQ”);
cb.setOAuthConsumerSecret(“4MmWFfRLqVDqP3S8cXaXz3lalmqaSx9EFUkuXdKlCKI”);
cb.setOAuthAccessToken(“2332151977-viWko3JzJvo1VrSk7z3kqYVwVULvfpYJAizh3Gq”);
cb.setOAuthAccessTokenSecret(“17q8peS67ZWmd2cF8W2vzGkQZIjgvXM0Xxi8rUhuFh4uA”);
//add all the keys necessary for Twitter authentication

TwitterFactory tf = new TwitterFactory(cb.build()); //use authentication

twitter = tf.getInstance(); //pass twitter factory to the instance of twitter

getNewTweets(); //check for all current tweets containing the search query

currentTweet = tweets.size(); //this stops the run starting from preexisting tweets
println(currentTweet);
thread(“refreshTweets”); //refresh tweets is run in a seperate thread, evert 30 seconds it calls getNewTweets
}

void draw()
{

if (cam.available() == true) {
cam.read();
}

set(0, 0, cam); //display the camera
}

void getNewTweets()
{
try //try catch because the internet is a risky place
{
Query query = new Query(searchString); //add the string to be matched to the query

QueryResult result = twitter.search(query); //query twitter

tweets = result.getTweets(); //store the results in an array list
}
catch (TwitterException te)
{
System.out.println(“Failed to search tweets: ” + te.getMessage());
System.exit(-1); //exit on fail
}
}

void refreshTweets()
{
while (true) //just keep running
{
getNewTweets(); //check for new tweets

println(“Updated Tweets”);
if (tweets.size() > currentTweet) { //there is a new tweet!
//start
println(“new tweet received”);
startRolling();
sendTweet(); //send a tweet in response
currentTweet = tweets.size(); //mark the new size of matching tweets
println(“Current matching tweets = ” + currentTweet);
}
delay(30000); // Mustn’t request information too often
}
}

void sendTweet() {
try {
runsDone++; //called again
String t = “Just completed run number ” + runsDone + “! (Runs count since I last booted up) in ” + runTime + ” seconds!”;//make up the string to tweet
StatusUpdate status = new StatusUpdate(t);
File file = new File(“/Users/fearnbrocks/Documents/Processing/tweetRoller2/data/image.jpg”);
status.setMedia(file); //add image
twitter.updateStatus(status); //update the status with the above string
println(“Successfully updated the status to [” + status + “].”);
file.delete(); //delete image
}
catch(TwitterException e) { //print error code if update fails
println(“Send tweet: ” + e + ” Status code: ” + e.getStatusCode());
}
}

void startRolling(){
int sector=1;
runTime=0;
int startTime = millis();
////////////
arduino.analogWrite(elevatorPin, 250);//I’m giving her all she’s got captain
delay(5500);
arduino.analogWrite(elevatorPin, 0);
while(sector == 1){
//Illuminate sector 1
boolean gate1Broken = false;
int gate1Previous = arduino.analogRead(sector1Gate);
int gate1Current = gate1Previous;
int breakCount = 0;
int firstBreak = 0;
while(!gate1Broken){
gate1Current = arduino.analogRead(sector1Gate);
if(gate1Current > 600){ // || gate1Current > gate1Previous+sensitivity){
if(millis() – startTime > 5){
breakCount++;
}
if(breakCount > 1 && millis() – firstBreak < 1){
gate1Broken = true;
delay(300);
saveFrame(“/Users/fearnbrocks/Documents/Processing/tweetRoller2/data/image.jpg”); //save still from camera
int newSector = sector+1;
print(“Gate 1 broken with value “);
print(gate1Current);
print(“. Sector “);
print(newSector);
println(” active!”);
sector++;
} else {
if(breakCount == 1){
firstBreak = millis();
}
if(breakCount > 2){
breakCount = 0;
firstBreak = 0;
}
}
} else {
gate1Previous = gate1Current;
}
}
}

while(sector == 2){
boolean gate2Broken = false;
int gate2Previous = arduino.analogRead(sector2Gate);
int gate2Current = gate2Previous;
int breakCount = 0;
int firstBreak = 0;
while(!gate2Broken){
gate2Current = arduino.analogRead(sector2Gate);
if(gate2Current > 600){ // || gate1Current > gate1Previous+sensitivity){
if(millis() – startTime > 5){
breakCount++;
}
if(breakCount > 1 && millis() – firstBreak < 1){
gate2Broken = true;
println(“Gate 2 broken. Run Complete!”);
//we’re at the end!
int finishTime = millis();
runTime = finishTime – startTime;
print(“Your run took: “);
int runSeconds = runTime /1000;
runTime = runSeconds;
print(runSeconds);
println(” seconds to complete!”);
sector = 0;
} else {
if(breakCount == 1){
firstBreak = millis();
}
if(breakCount > 2){
breakCount = 0;
firstBreak = 0;
}
}
} else {
gate2Previous = gate2Current;
}
}
}

}