Motoring on through!

At the beginning of the run, the ball sits at the bottom of the run awaiting the elevator to turn on and carry it to the top. This was the simplest solution for having a single run setup. In order to start and stop the elevator component, the motor needed to be modified so that it could be controlled by the arduino.

There were two ways to do this. As the motor consisted of a power source and a switch we could have done one of the following:

  • Disassemble or replace the switch, allowing the arduino to control the power flow
  • Attach new wires to the power source input and use the arduino to power the elevator leaving the switch always on.

In the end, I decided to go for the latter mainly because I would be able to use the whole elevator/motor system as it was manufactured in the future should I wish whereas with the first method I would have always needed an arduino.

The process of doing this was simply soldering on additional wires, drilling a small hole in the housing to allow them to come out and then connecting these to the arduino. The option did have the added difficulty that we had to use a PWM pin in order to provide the correct amount of power and a transistor to make it into direct current. The results were what we envisaged and this part of the project worked faultlessly from the start.

Break a beam!

Well, not quite don’t break a leg but it’s close!

 

An integral part of the project was detecting where the ball was and whether it had passed a certain point or not. In order to do this I used some phototransitors coupled with some IR emitters as an improvised beam trip. When the ball passes between the phototransistors and IR emitter the arduino is able to detect the slight drop in the readings which indicates the ball has travelled past. This meant that we could flip booleans in the logic to indicate where the ball was in the system.

We had a slight issue with the bouncing of the sensors because occasionally the light levels would fluctuate and due to the fact the phototransistors detect a much wider range of light than an IR detector, it would occasionally simulate tripping the beam. To ensure this really was a ball passing through I wrote a small segment of code to ensure that the beam break time was synonymous with a real break.

Once I had created a working prototype on the breadboard I then created several smaller beam break modules using small squares of stripboard. These were mounted onto the small clips that held the track together and then the Emitter and phototransistor were aligned for best results.

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

}

Tweeting Images

Screen Shot 2014-03-25 at 09.11.58

 

Originally I was going to use a LinkSprite JPEG Camera to add in pictures. Using the Arduino 1.0.4 IDE I was able to capture images to the SD card using Adafruit’s wonderful library (it didn’t work with 1.0.5, unsure why). The plan was to take the snapshot to the SD card reader on the Arduino’s ethernet board and then delete it when it had been used.

Sadly now we are using Processing to do Twitter posting and connecting to the Arduino with Firmata using an external library is out. If I was really desperate to use the Arduino for this I could set up a serial link to Processing rather than using Firmata but trying to send the file from the SD card over serial whilst viable is certainly overcomplicating matters.

So, as a result, my code still isn’t touch the Arduino’s sensors yet, sorry! Rather I am using a webcam and the saveFrame() function to save an image. This is attached to the tweet using Twitter4j and then deleted after uploading is complete.

Here is the extra code used to take the photo and add it into the tweet (camera instantiation not included):

saveFrame(“/your/datapath/image.jpg”);
delay(2000); //time to save
File file = new File(“/your/datapath/image.jpg”);
status.setMedia(file);
twitter.updateStatus(status); //update the status with the above string
println(“Successfully updated the status to [” + status + “].”);
file.delete();

 

Huston we have tweet-off.

Sort of unsettlingly the twitter code doesn’t touch the Arduino. As I’ve had to use Processing we will connect with the sensors and actuators using Firmata. It’s cool, and certainly with how Twitter has made checking tweets such a pain it is logical, it just feels a bit weird since this is being made for a Physical Computing course! The part for checking tweets is a modification of the code found here.

Anyway, here is the code (sans Firmata for now) for checking tweets and sending out a tweet in response using Twitter4j:

import twitter4j.conf.*;
import twitter4j.*;
import twitter4j.auth.*;
import twitter4j.api.*;
import java.util.*;

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

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

void setup()
{
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey(“”);
cb.setOAuthConsumerSecret(“”);
cb.setOAuthAccessToken(“”);
cb.setOAuthAccessTokenSecret(“”);
//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

thread(“refreshTweets”); //refresh tweets is run in a seperate thread, evert 30 seconds it calls getNewTweets
}

void draw()
{
//All’s quiet on the drawing front
}

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”);
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)”;//make up the string to tweet
Status status = twitter.updateStatus(t); //update the status with the above string
println(“Successfully updated the status to [” + status.getText() + “].”);
} catch(TwitterException e) { //print error code if update fails
println(“Send tweet: ” + e + ” Status code: ” + e.getStatusCode());
}
}

A list of methods for reading tweets from Twitter that don’t work.

I’ve tried several different methods for reading tweets now. I may currently be onto a winner and if it works by gum will it be documented to save others the hassle. This post however, is basically a list of things that don’t work since Twitter changed to API 1.1 and implemented OAuth 2.0, which will hopefully save some people time.

Method 1: Twitter libraries for Arduino.

There are two Twitter libraries that I know of for the Arduino. The library listed on Arduino.cc and the Markku Rossi twitter library. Neither of these have methods for retrieving tweets.

Method 2: Hook the Arduino up to Processing via Firmata and use the Twitter4j library.

I was sold the Twitter4j library was going to be the solution. One of the biggest problems anyone trying to check Twitter from the Arduino seems to have is memory. Using Processing on say a Raspberry Pi and then communicating with the Ardino would solve this. Setting up Twitter4j and Processing is a bit weird, Processing has some very strict conventions about how it reads libraries so a few file names and folders have to be changed. There are some very good examples with Twitter and Processing on the Carnegie Mellon University website. Using these I was able to tweet when a button was pressed on the Arduino. Sadly the examples for checking for tweets use an older version of the Twitter4j library and trying to use them I had authentication errors, I suspect from Twitters overzealous implementation of OAuth 2.0. There is still some hope for resolving this but I abandoned it for the moment as I thought stumbling upon method 3 I had found the solution…

UPDATE: This method works! Copypasta from here is getting results.

Method 3: Back to the Arduino, this time Frankenstein-ing Adafruit code.

So I discovered this example of using tweets to control an RGB LED. After a little Googling I also found the code used on the Arduino website. Using a Twitter API endpoint this searches tweets and then parses the returned JSON files. I converted it to work with the Ethernet Shield and was able to successfully reach the endpoint. I just couldn’t get any results from it. Eventually I realised this was actually still using the 1.0 API, but as it is said in the video the actual Twitter part of the code is taken from an Adafruit library for their Internet of Things printer so I went searching for this hoping it had been updated to work with the current 1.1 version of Twitters API. It had! Sadly, an issue was raised two months ago that it had stopped working. This sadly coincides with Twitter changing it’s API again so it can only be queried via https, which as far as I can tell the ethernet shield is incapable of handling. Sadly here ended any real hope I had that this project could be implemented solely on Arduino. Good thing I got Processing working on the Pi!

Additionally…

Method 4: The Arduino Yún.

The Arduino Yún is an Arduino made specifically for Internet of Things type applications. It’s a bit of a beast, alongside the micro-controller is a separate processor which runs a Linux distribution. I’m 98% sure if you wanted to use this for Twitter you could. I’m not sure if the https only scuppers the WiFi as it does the Ethernet shield but there are separate libraries from Temboo to handle things like Twitter timelines.  It’s just a shame you’d have to spend ~£55 on a new board to be able to use it.

 

Processing and the Raspberry Pi

So, after a lot of trying to mess about with RSS and make listening for tweets work without a separate computer feeding into the Arduino I have sadly resigned to the fact it isn’t going to happen. No library I can find supports actually checking a twitter stream, and for posting images to Twitter I have found only one somewhat lacking in documentation library.

These things however are quite frequently worked around by interfacing Arduino with Processing. As this project is intended to be able to be left on dedicating a laptop to it seemed like a bad idea. Simple I thought, I will use the good ol’ Raspberry Pi! I was not as right as I could have been, out of the box Processing is unable to run on the Pi. You have to mess about with Java to get it working. Happily this lovely person has it all worked out: http://scruss.com/blog/2014/01/07/processing-2-1-oracle-java-raspberry-pi-serial-arduino-%E2%98%BA/ Not only do the explain how to exchange the Java packaged with Processing to the new Hard-Float Java 7 which is supported by the Pi, it also gets serial up and working (which is one way of interfacing between the Adruino and Processing).

Processing actually runs fairly reasonably on the Pi, I found 2.1 was much more reasonable in speed than 2.1.1. I suspect if I were doing much intensively this wouldn’t be an option but to send and receive data to the Arduino it seems like a viable option.

Ball’s First Tweet

Today Ball tweeted!

Screen Shot 2014-03-04 at 19.34.39

 

This was done using the Arduino Twitter library and an el’ cheapo ethernet shield I purchased from Amazon. It uses the SimplePost example from the library but when trying to use this I found an interesting thing: as it is the example doesn’t work!

To begin using the library you have to set up a few things, including getting a key to use their service from this website: http://arduino-tweet.appspot.com/ There you authorise the library as an app so it can post to your account on your behalf. Then you take the tolken they give you, insert it into the sample code and hit play. Sounds easy and too good to be true, and that’s because it is. Sadly after hitting go I was frequently met with ‘Connection Failed’ messages. At first I thought this may be the fault of the ‘el cheapo Ethernet Shield. To test it I set up a Telnet server (check out the ‘chat server’ sample supplied with the Ethernet Shield library). I connected to it through my mac and got a response.

Screen Shot 2014-03-04 at 19.45.08 Screen Shot 2014-03-04 at 19.46.03

 

So, ‘el cheapo Ethernet Shield proves to be a sound purchase! So why no Twitter? To the Googlemobile! A quick search brought me to a post suggesting I should try it with DHCP. Huston we have liftoff! If you want to know why the SimplePost doesn’t work this post holds the answer. It suggests unless you specify a gateway (twice) the gateway for the Ethernet Shield is erroneously set to the IP causing the connection to fail. I tested this theory and found the solution to work! (This method is how the second tweet was sent).

Screen Shot 2014-03-04 at 19.52.31

 

So there you have it, a simple post to Twitter, and why it isn’t quite as simple as you’d hope!

Welcome

TweetRoller is a project for a 3rd year computing course. We are creating a ball run which people can tweet at to activate, and which will at the end of it’s run tweet how long the run took and a picture from that run (like a rollercoaster).

To do this we are using an Arduino Uno, an ethernet shield, a LinkSprite JPEG color camera, pieces of SpaceRail and an array of solenoids, motors and servos to make a fun moving run!