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

Predictive Policing Awareness Machine

For this assignment we were tasked with choosing a topic to design and build a critical object about. Teams were also given sets of requirements for the created piece. The piece Gilad and I made was required to use an organic element, convey surrealism, and emote anxiety.

After a lot of brainstorming we decided to work around the topic of systemic bias, more specifically that of predictive policing and their use of artificial intelligence. This piece from propublica was eye opening to us and helped to shape the framework of the awareness machine we created.

The critical object we created was based around the idea of of a feedback cycle where data that has an innate bias in it continually gets fed into a system where the output seems uncontaminated but contains remnants of the biased data within it.

The system we created was an organic representation of those black box systems. Having a dropper of durian essence, an extremely pungent fruit that can fill a room quickly, fall onto a flower which acts as the output of the system. The liquid then creates an odd sensation where a flower which is usually associated as beautiful and pleasant smelling is now revolting. The final piece of the system is that the flower has a chance of falling into a blender and being chopped up. This is partially to make a statement about how the American criminal justice system can be a crap shoot and to say that it can have permanent effects on those who fall into it for one reason or another.

We wanted to have the final design of the piece be minimalistic and have an overall sterile look to it. The thinking behind this being that an association with this look and systems of various kinds would occur.

The technology behind the piece was fairly simple. Using a Finite State Machine built in arduino code we were able to asynchronously control a high torque servo and then use a powerswitch tail to control the blender. Everything was controlled using Arduino.

Some pieces were laser cut to help add to the design.

A final video of the working piece can be found below.

Arduino Code:

#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include <ArduinoHttpClient.h>
#include <SPI.h>


#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
char sessionKey[] = SECRET_KEY;
String MAC = SECRET_MAC;

const char serverAddress[] = "tigoe.io";  // server address
String route = "/data";
// set the content type and fill in the POST data:
String contentType = "application/json";
int port = 443;
int sensorPin = A1;

//temperature values
String tempString, newPost, tempData;


byte mac[6];
WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);              // initialize serial communication

  // while you're not connected to a WiFi AP, attempt to connect:
  while ( WiFi.status() != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);           // print the network name (SSID)
    status = WiFi.begin(ssid, pass);  // try to connect

    }

  WiFi.macAddress(mac);

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

}

void loop() {


    //String tempData;

  int sensorReading = analogRead(sensorPin);

  float voltageReading = sensorReading * 3.3;
  voltageReading /= 1024.0;

  //temperature in Celcius
  float tempC = (voltageReading - 0.5) * 100;

  Serial.print(tempC); Serial.println(" degrees C");    tempData = String(tempC);

  //
  //  Serial.println("making POST request");
  //
  //  // send the POST request
  //  //client.post(path, contentType, postData);

  postData(tempData);



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

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
  client.stop();    //close request
  while (true);  // stop



  Serial.println("Wait ten seconds\n");
  delay(10000);
}



void postData(String newData) {
  //  // have to insert extra \ before " in data JSON,
  //  // since it's a JSON string within a JSON string:
  //  newData.replace("\"", "\\\"");

  //  // the template for the body of the POST request:
  //   String body = " {\"macAddress\":\"MAC\",\"sessionKey\":\"KEY\",\"data\":\"DATA\"}";
  ////  Serial.println(body);
  //  // replace the template placeholders with actual values:
  //  body.replace("MAC", macToString(mac));
  //  body.replace("KEY", sessionKey);
  //  body.replace("DATA", newData);
  //  Serial.println(body);
  //  // make the request
  //  //body = "{\"macAddress\":\"84:0d:8e:34:a9:70\",\"sessionKey\":\"31b2cc54-e15d-4c89-9b38-474490983388\",\"data\":\"temperature:26.70\"}";
  //  client.post(route, contentType, body);

  tempString = "{'\"temperature'\":\"";
  tempString += tempData;
  //tempString += "\", \"tempData\":\"";

  newPost = "{\"macAddress\":\"";
  newPost += MAC;
  newPost += "\", \"sessionKey\":\"";
  newPost += sessionKey;
  newPost += "\", \"data\": ";
  newPost += tempString;
  newPost += "}";
  Serial.println(newPost);
  client.post(route, contentType, newPost);


}

void getData() {
  // set the content type and fill in the body:
  String contentType = "application/json";
  // the template for the body of the POST request:
  String body = " {\"macAddress\":\"MAC\",\"sessionKey\":\"KEY\"}";
  // replace the template placeholders with actual values:
  body.replace("MAC", macToString(mac));
  body.replace("KEY", sessionKey);

  // make the request:
  client.beginRequest();
  client.get(route);
  client.sendHeader("Content-Type", "application/json");
  client.sendHeader("Content-Length", body.length());
  client.beginBody();
  client.print(body);
  client.endRequest();
}

void temperatureCheck(){

  
  }




String macToString(byte mac[]) {
  String result;
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      result += "0";
    }
    result += String(mac[i], HEX);
    if (i > 0)  result += ":";
  }
  return result;
}

MTA Service Disruptor

For Critical Objects assignment 2 we were required to create a disobedient object. Meaning an object that serves as a form of social or political protest. The focus for this project was focused more on the critical critique and technology elements.

When thinking about a subject to create a disobedient piece towards I tried to think locally and more specifically towards something that directly impacts me. For all of the things I love about NYC there are plenty of things I can’t stand about it. After living here for three years my tolerance for the MTA has decreased exponentially.

Screen Shot 2019-02-10 at 6.10.50 PM.png

This being so, Adi and I decided to create an object that would be a disruption to the MTA. We wanted the piece to only be noticeable and cause a disturbance when trains do not run on schedule Out of this came the MTA Service Disruptor.

The idea behind the device is that someone protesting the MTA would take the piece and plant it secure location facing the train tracks. The device would then be silent as long as trains were running on the correct schedule. As soon as the trains began to run off schedule then the device would start making an irritating beep sound. The longer the time until the next train the louder and more obnoxious until the trains return to their normal schedule.

The concept is that the Service Disruptor will force people to begin to discuss whats going on and then keep the issue relevant for as long as necessary. The goal of the piece is not to solve the issues with the NYC subway system but to keep the topic relevant and make New Yorkers more hostile towards the heads of the MTA.

IMG_20190210_163409.jpg

The Service Disruptor uses a basic circuit comprised of an ultrasonic sensor, basic speaker and small arduino microcontroller. The small form factor and simplicity of the piece makes it ideal for creating many of them and planting all over the city at different stations.

IMG_20190210_181757.jpg

Code

#include <toneAC.h>

int trigPin = 5;
int echoPin = 6;

void setup() {
    Serial.begin(9600);
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
}

int rangeThreshold = 5000;
unsigned long lastSubwayTime = 0;
int expectedTrainSchedule = 5000; // ms

void loop() {
    float rangeDuration;
    unsigned long now = millis();

    // send a 2 microsecond pulse to start the rangefinder
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // read from the rangefinder
    rangeDuration = pulseIn(echoPin, HIGH);

    // occasionally print sensor value
    if (now % 3 == 0) {
        Serial.print("d: ");
        Serial.println(rangeDuration);
    }

    float toneFrequency = 800;
    float toneVolume = 10;

    if (rangeDuration < rangeThreshold) {
        lastSubwayTime = now;
    } else if (now - lastSubwayTime > expectedTrainSchedule) {
        playNotes(10, 500);
    }
}

int notes[2] = { 800, 400 };
unsigned long lastNoteTime = 0;

void playNotes(int volume, int duration) {
    int i = 0;
    while (i < 2) {
        unsigned long now = millis();
        if (now - lastNoteTime > duration) {
            lastNoteTime = now;
            toneAC(notes[i], volume, duration);
            i++;
        }
    }
}

TRACKS: Creating the first Critical Object

Concept

When thinking about this first assignment and all of the possibilities for creating a critical object it was easy to get overwhelmed with subject matter. This is why Dana and I decided to create a piece that would be light hearted but still make people think. Our ideation really began when we started talking about standardization of things and process that have seemingly just been accepted by people over the years.

After talking about that concept for a bit we started talking about credit cards and how they add a level of separation between the feelings of spending money, which is a serious action, and the feeling of playing, either by swiping, inserting, or tapping a card. From this idea we began to develop a game modeled after wooden train sets. The game we developed is titled TRACKS.

Wooden train track example

Wooden train track example

The theme of the game is that the player opens up a box that looks like it contains a normal game, when they open the box they are initially presented with a credit card and a manual for playing the game. After that they can begin assembling the tracks and use the credit card to play with them.

Design

The design took heavily from minimalist packaging design and old VHS cases. We wanted the packaging and information given in the box to really highlight that this was a game, supposedly designed by a large company. We also wanted the game to be ambiguous to its intentions until the player really reads the information provided and starts to assemble the pieces of track.

Screen Shot 2019-02-03 at 16.52.12.png

Build Process

The actual building of the tracks and the box were more difficult than we had expected. Without access to ITP’s laser we were forced to hand carve each piece of track for the credit card to slide in. Also creating the box proved challenging as we chose the wrong thickness of cardboard at first which gave us issues with bending.

Final materials ended up being hard foam pieces, dowels, cardboard, and paper mixes. Below are some photos of the building process.

IMG_5913.jpg

Final Thoughts

Overall, I feel that the execution of the piece went very well considering the limitations imposed with time and tools. Given more time I would rework the track and maybe design a credit card specifically for the assignment.

Below are some photos of the final piece: