Tuesday, December 8, 2015

Final Project

As a photographer, I am interested in how I perceive my world around me and how I can represent what I see to other people. Upon viewing my photographs, people often ask me where or when the image was taken. So, for the final project, I taped a sensor connected to the Arduino to the button of a point and shoot camera so that every time someone takes a picture on the camera a tweet is sent to Twitter notifying myself as well as followers of my Twitter account that someone has taken a photograph. I connected my Twitter account, https://twitter.com/Arduino_Photo, with ThingSpeak so I could easily connect Twitter with the Arduino. A classmate, Mckenzie, who is also working with ThingSpeak and Twitter for this project, shared her Arduino code with me which greatly helped me out. Once the sensor on the Arudino connects with ThingSpeak and sends a tweet I can then view what time the tweet hit Twitter on my Twitter account. I can then use the time information from each tweet, and the metadata of each photo containing the time it was taken, to upload images to a site or a blog so people can see that a picture was taken, and they can then in turn see the photograph that was taken at that exact moment.


#include <SoftwareSerial.h>
#include <SparkFunESP8266WiFi.h>
#include <SPI.h>

// Local Network Settings
//byte mac[] = { 0xD4, 0x28, 0xB2, 0xFF, 0xA0, 0xA1 }; // Must be unique on local network, not

// ThingSpeak Settings
char thingSpeakAddress[] = "api.thingspeak.com";
String thingtweetAPIKey = "key";

const char ssid[] = "KSU Guest";
//const char pssk[] = "";

// Variable Setup
long lastConnectionTime = 0;
boolean lastConnected = false;
int failedCounter = 0;

// Initialize Arduino ESP8266 Client
ESP8266Server server = ESP8266Server(80);
ESP8266Client client;

void setup()
{
  // Start Serial for debugging on the Serial Monitor
  Serial.begin(9600);
 
  // Start the WiFi
  initializeESP8266();
  connectESP8266();
 
  delay(1000);
}

void loop()

  // Print Update Response to Serial Monitor
  if (client.available())
  {
    char c = client.read();
    Serial.print(c);
  }
 
  lastConnected = client.connected();

  double volts = pressureSensor();
  if (volts > 0.01){
    String message = "Another photo.";
    //message += volts;
    //message += " volts.";
    //message += " volts. #arduino #thingspeak";
    updateTwitterStatus(message);
  }
 
  else{
    Serial.println(F("Not sensing anything..."));
  }

  delay(2000);
}

void updateTwitterStatus(String tsData)
{
  if (client.connect(thingSpeakAddress, 80))
  {
    // Create HTTP POST Data
    tsData = "api_key="+thingtweetAPIKey+"&status="+tsData;
           
    client.print("POST /apps/thingtweet/1/statuses/update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(tsData.length());
    client.print("\n\n");

    client.print(tsData);
   
    lastConnectionTime = millis();
   
    if (client.connected())
    {
      Serial.println("Connecting to ThingSpeak...");
      Serial.println();
     
      failedCounter = 0;

      Serial.println("Made a post!");
    }
    else
    {
      failedCounter++;
 
      Serial.println("Connection to ThingSpeak failed ("+String(failedCounter, DEC)+")");  
      Serial.println();
    }
   
  }
  else
  {
    failedCounter++;
   
    Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter, DEC)+")");  
    Serial.println();
   
    lastConnectionTime = millis();
  }
}

void initializeESP8266()
{
  int test = esp8266.begin();
  if (test != true)
  {
    Serial.println(F("Error talking to ESP8266."));
    errorLoop(test);
  }
  Serial.println(F("ESP8266 Shield Present"));
}

void connectESP8266()
{
  int retVal = esp8266.getMode();
  if (retVal != ESP8266_MODE_STA){
    retVal = esp8266.setMode(ESP8266_MODE_STA);
    if (retVal < 0)
    {
      Serial.println(F("Error setting mode."));
      errorLoop(retVal);
    }
  }
  Serial.println(F("Mode set to station"));

  retVal = esp8266.status();
  if (retVal <= 0){
    Serial.print(F("Connecting to "));
    Serial.println(ssid);
    retVal = esp8266.connect(ssid);
    if (retVal < 0){
      Serial.println(F("Error connecting"));
      errorLoop(retVal);
    }
  }
}

void errorLoop(int error){
  Serial.print(F("Error: ")); Serial.println(error);
  Serial.println(F("Looping forever."));
  for (;;)
    ;
}

double pressureSensor(){
  // Read the input on analog pin 0:
  int sensorValue = analogRead(A0);
 
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  double voltage = sensorValue * (5.0 / 1023.0);
 
  // Print out the value read
  return voltage;
}

I wanted to take the project one step further and make it so that the user could also find and views pictures that are being tweeted in real time on Twitter. So, with Processing, I was able to make a Twitter search for photographs and was able to print the result in the command line of Processing. The viewer will be able to see the username of the people who made the tweet, the time of the tweet, the tweet itself, and a url of the photo they posted. One can then copy and paste the url of the photo into the web browser to view the images. I can run this Processing sketch at the same time as the Arduino sketch in order to create a more depth in the project as well as the viewer experience.

import java.util.Date;


import twitter4j.conf.*;

import processing.serial.*;


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


import twitter4j.api.*;
import twitter4j.util.*;

import twitter4j.*;
import processing.serial.*;
import cc.arduino.*;

// HEY! GET YER OWN KEYS FROM: https://dev.twitter.com/apps/new
static String OAuthConsumerKey    = "";
static String OAuthConsumerSecret = "";
static String AccessToken         = "";
static String AccessTokenSecret   = "";


Twitter myTwitter;
List<Status> tweets;

String  myQueryWord = "photo";
long    previousIdOfTweetContainingQuery = 0;


//===========================================================================
void setup() {
  size(125, 125);
  frameRate(10);
  background(0);
 
 
  loginTwitter();
}

//===========================================================================
void loginTwitter() {

  ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey(OAuthConsumerKey);
cb.setOAuthConsumerSecret(OAuthConsumerSecret);
cb.setOAuthAccessToken(AccessToken);
cb.setOAuthAccessTokenSecret(AccessTokenSecret);
myTwitter = new TwitterFactory(cb.build()).getInstance();
}


void draw() {

  try {
    println ("Searching.... Current time = " + hour() + ":" + minute() + ":" + second());
    Query query = new Query(myQueryWord);
    // how many results to fetch
    QueryResult result = myTwitter.search(query);

     for(Status mostRecentTweetContainingQuery : result.getTweets())
     {
      long mostRecentTweetContainingQueryId = mostRecentTweetContainingQuery.getId();

      if (previousIdOfTweetContainingQuery == 0) {
        previousIdOfTweetContainingQuery = mostRecentTweetContainingQueryId;
      }
      if (mostRecentTweetContainingQueryId != previousIdOfTweetContainingQuery) {
        // yay! someone has just tweeted our favorite word!
        previousIdOfTweetContainingQuery = mostRecentTweetContainingQueryId;
    //    tellArduinoToDoSomething(); // HERE IT IS!

        // print out the new tweet, for fun.
        String user = mostRecentTweetContainingQuery.getUser().getScreenName();
        String msg = mostRecentTweetContainingQuery.getText();
        Date d = mostRecentTweetContainingQuery.getCreatedAt();
        println("Tweet by " + user + " at " + d + ": " + msg);
      }
    }

    /*
    // Indicentally, you can also list all of the most recent tweets containing that search term. Fun!
    for (int i=0; i< tweetsContainingQuery.size(); i++) {
      Tweet t = (Tweet) tweetsContainingQuery.get(i);
      String user = t.getFromUser();
      String msg = t.getText();
      Date d = t.getCreatedAt();
      println("Tweet by " + user + " at " + d + ": " + msg);
    }
    println("--------------------");
    */
   
   
  }
  catch (TwitterException te) {
    println("Error connecting to Twitter: " + te);
  };


  delay (12000); // REALLY IMPORTANT, PEOPLE. You're limited to 350 requests per hour, or about once per 11 seconds.
}


Overall, I found this project to be quite challenging because I had not worked with the Arduino, or any form of electronics, and programming anything before this project. I did a large amount of Google searching and trial and error in order to find code and insight online, and I got help from classmates as well. I feel my project is interesting and relevant to the art world because it is interactive and enables the viewer to connect with photography through a hands on element, an online Twitter account, and allows the viewer to read and access tweets that contain photographs in real time. Ideally, the project could be placed in a public settings so that a viewer can walk up, examine the project, take a photograph, and then later view the Twitter account as well as the site the images are uploaded to in order to see the photograph they made.

No comments:

Post a Comment