Critical Objects Midterm: Instagram Accountability System

Guidelines:

For the Critical Objects Midterm assignment students were given the option to choose any topic to make a project from. I decided to do the following:

Topic: Voluntourism(Unsustainable volunteering)

Device: Juxtaposition

Attribute: Interactive

Mood: Surprising

IMG_20190325_165420.jpg

The piece that I decided to make was based around the statistics that show how unsustainable volunteering or voluntourism has long term negative impacts on communities affected. Some of these impacts include economic losses and high turnover at orphanages.

I wanted to highlight how many people who practice this type of tourism post their activity on social media, in doing so they help to perpetuate this kind of behavior and thoughtlessness. When people like posts that show this activity they encourage the person posting to continue down that path.

Taking the idea that social media has an impact on this behavior I created the Instagram Accountability System. I created an instagram page that aggregated a few photos of unsustainable volunteer activity and when any of the photos in the account were liked enough times a brick would fall and break a clay plate. In this case, the brick, traditionally thought of as an object to help build, is used destroy an object.

Screenshot_20190401-024548.png

Technical Elements:

The first part of the project began with me writing the server client to connect to the instagram API. Initially I planned to do the entirety of the project in Arduino to minimize any unnecessary coding or data sending. After a week of attempting to use the Arduino for the project I made the decision to write my client to stream the instagram data to. There I would send the data to a node server I had written and finally that data would be sent to Arduino where it would be parsed and used to control a pulley system.

Some of the biggest challenges in the programming portion of the project were the initial attempts at trying to do everything using an Arduino. It was very difficult to do and frustrating at times. Other challenges were sending the instagram data back to the Arduino. The number of likes had to be sent as a string but couldn’t be uploaded to my server that way and that caused a good amount of time being devoted to figuring out a solution. The final challenge was dealing with the string once it was sent to Arduino. converting a string that is an array of numbers was massivly annoying and in the end I wasn’t able to completely do it. I had to take the hex values of each and compare them to control the motor pulley system I had built.

The initial Pulley System I had built used a servo with a blade attached to it to cut a rope but the system took too long to cut the rope and was unreliable. So I switched to a single throw pin pull system which worked much better.

Fabrication:

The fabrication portion took the least amount of time. Most of it involved ensuring that the brick would be able to hang safely and not break the system. A good amount of laser cutting, metal cutting, and wood glueing took place for the final product.

Final Thoughts:

Overall, I am happy with how the piece turned out. I think the level of abstractness works for it and the concept is solid. If I were to iterate on it I would definitely redesign the look of the enclosure and possibly what was being crushed. I learned a lot from this project and I think I hit a spot pretty close to the middle of the Critical Triangle.

Heres a video of the piece in action:

Arduino Code:

/*
 ITP Critical Objects Midterm Spring 2019
 Morgan Mueller
 Get request from Node Server and parse the string sent over, then control motor.
*/
#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
#include <Servo.h>

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

char serverAddress[] = "10.17.79.241";  // server address
int port = 8000;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;
boolean forward = true;

Servo myServo;
int angle;
int increment;

int ControlPin = 3;   //give your arduino pin a name


unsigned long ts = millis () ;   // time accounting.
#define DELAY 20

void setup() {
  Serial.begin(9600);
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    ///////// Servo code /////////////
    myServo.attach(2);

    pinMode(ControlPin, OUTPUT); // initialize the digital pin as an output.



  }

  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void loop() {


  Serial.println("making GET request");
  client.get("/");

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  // Serial.print("response 1: ");
  //Serial.println(response.length());
  //response.remove(0,1);
  int opening = response.indexOf('[');
  int closing = response.indexOf(']');
  response.remove(opening, 1);
  response.remove(closing);

  for (int i = 0; i < response.length(); i++) {
    int commas = response.indexOf(',');
    int otherCommas = commas + i;
    response.remove(commas, 1);

  }



  // response.toInt();
  Serial.print("this is the first position of response: ");
  Serial.println(response[0]);
  //Serial.print("this is the second position of response: ");
  //Serial.println(response[1]);

  //   char buf [] = response.length() + 1;
  int len = response.length() + 1;
  //response.toCharArray(buf, sizeof(buf));

  //int testRes1 = atoi(&response[0]);
  int testRes2 = response[1];
  //int testResTotal = testRes1 + testRes2;


 //for (int k = 0; k < response.length() - 1; k++  ) {
  if (response[0] == 51 ) {
    Serial.println("SPIN TO WIN");

    digitalWrite(ControlPin, HIGH); // turn the motor on by making the voltage HIGH

    //
    //    for ( angle = 0; angle < 180; angle++) {
    //      myServo.write(angle);
    //      //increment = angle;
    //      delay(15);
    //      if (angle == 0) {
    //        for (increment = 180; increment > 0; increment--) {
    //          myServo.write(increment);
    //          increment = angle;
    //          delay(15);
    //        }
    //
    //
    //      }
    //    }
    //    // now scan back from 180 to 0 degrees


  }
 //}


  Serial.println(testRes2);
  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
  Serial.println("Wait five seconds");
  delay(5000);
}

Javascript Code:

var express = require('express');       // include express.js
var server = express();           // a local instance of it

var likes = [];
// [{ id: STRING, likesCount: INTEGER }, ...]

var newBody;

var url = 'https://api.instagram.com/v1/users/self/media/recent/?access_token=12161955647.a06c9e9.3d22233be15b4b72822cba3386950c3b&likes';


const request = require("request");


//----------------------------------------------------------- Handles Instagram

// this checks the API and populate the # of likes
function checkLikes(){

  request.get(url, (error, response, body) => {


    try {
      let json = JSON.parse(body);
      if (json && json.data) {
        likes = [];
        json.data.forEach(function(element) {
          likes.push(element.likes.count)
        });
      }
    } catch (error) {
      console.log("OMG ERROR", error)
    }

    })

  //});
  // Add the code to check the API (Instagram)

  // Populate the array of likes
  //likes = [];
}
// Check the API every **** ms



//----------------------------------------------------------- Handles Arduino

// this runs after the server successfully starts:
function serverStart() {
  var port = this.address().port;
  setInterval(checkLikes, 30000);
  console.log('Server listening on port '+ port);
}

// this is the handler for the root of the site:
function getRoot(request, response) {
    response.json(likes);                   // send # of likes back to the client
    // response.end();                  // close the connection
}

// start the server:
server.listen(8000, serverStart);
server.get('/', getRoot);                           // GET the root of the site