NE: Lightshades (Final Project) – TA

Concept

The idea for this project came from the frustratingly frequent headaches that I would get during long school days spent inside staring at computer screens.  To lights and the setting were really the cause of my headaches, I decided to track the light levels around me throughout the day, for however long I chose to keep track.  I wanted to have an Arduino keep the digital data from sensors and I would keep a journal of my activities and subjective feeling, and these two sets of information could be compared to find any trends that might exist.  Then I would put the data online for anyone to use or visualize as they pleased.  The Arduino would use an SD card to store data, a Bluetooth module to communicate with my computer, and a Real Time Clock to keep track of when the sensor data was taken, even if the Arduino lost power in the process.  The Arduino would be connected to a battery while I was moving around during the day, and I would charge the battery and use my laptop to power the Arduino while I was in a location to conveniently do so.

 

Process

Assembly was not very complicated, but invovled several different components which each took some time to get working.  First I wanted to get the sensor logger working, which meant getting an Arduino outfitted with an SD card, a Bluetooth module, and a Real Time Clock.  The SD card was very simple.  IMA already had a shield that I could plug into my Arduino, and there is a good llibrary that comes standard with Arduino.  For my purposes, I have the Arduino delete the data file every time it sends the data to the laptop, so it only stores the data since the last upload.

The bluetooth module was a bit trickier.  After spending several hours messing with it, I realized someone had reprogrammed the communication speed and that’s why my Arduino wasn’t able to communicate with it.  I reset the communication speed, and everything went smoothly from there.  I was using the DFRobot Bluetooth Module, so I found the programming commands from the DFRobot wiki.

The Real Time Clock was also extremely simple.  I used the YwRobot DS1307, and got the Adafruit library for using it.  The clock was extremely simple to use, but it only arrived the day before I presented my project so I wasn’t able to collect much data.

I also needed a sensor array, and for this I attached several Light Dependant Resistors to a pair of safety glasses to wear throughout the day.  Any kind of sensor system could be switched for this, but it was the simplest sensor setup for me to get working.  My setup had the LDRs serving as a variable voltage divider, each paired with a 12K resistor.  The LDR-resistor pairs were all connected in parallel (connected to the same power and ground lines) but with seperate data lines coming off in connecting to the analog pins of the Arduino.  Half of my LDRs weren’t working properly, so I ended up cutting them off and only using four LDRs in my final version.

On my laptop I made two C programs, one for getting the data over Bluetooth from the Arduino and the other for turning that data into a JSON file.  They were cleverly named bluetooth.c and createJSON.c respectively.  Then I used git to push the JSON file to github where anyone could access it.  Finally, I used p5.js to create a visualization website.  When I imported the data as a JSON file, I used rawgit to get the proper file typing (JSON rather than plain text).

NEfinal2-ta

For my manual log, I simply wrote down my location, what I was doing, what the environment was like, and the time whenever I moved to a new place.  I then manually entered this data into a JSON file and uploaded that to Github.

You can find the JSON files here.

 

Results

I would say the project was a success, at least as a proof of concept.  At this point it would be easy to change out the sensor for any other kind of sensor, and keep logging data about oneself constantly.  The particular sensors I used didn’t tell me much about my orginal problem, particularly because it differentiate between natural and artificial light, and just wasn’t very precise.  I also don’t like my visualization website very much, but I considered that as a secondary project; once the data was online anybody could make a visualization of it, so there was less pressure for me to make the best possible visualization.  I would also try using different wiring, and otherwise do a better job of soldering the sensors together.  I think the weird sensor problems were directly related to my poor soldering job.

All in all, I was able to connect a lot of the topics and technologies that we covered in class in this project.  To see some pictures and videos of the process, and to find the code, look farther down in this post.

 

Media

neFinal_1-tad

neFinal_2-ta

neFinal_4-ta

neFinal_5-ta

neFinal_6-ta     neFinal_3-ta

 

Code

Final Project Angelica Castro-Mendoza

So my initial project for this final was a poetry generator that got information from Reddit. I wanted it to be bad poetry, because uses would probably figure it was computer generated but I was planning to take it straight from Reddit. The vision was that I’d integrate some kind of physical infrastructure. The idea meandered though due to my  indecisiveness. I planned to serve up the web page using arduino and using the Rita javascript library to scrape from reddit. I wanted to set up an old tv and use a bluetooth signal to trigger the website to change. Despite being super gung ho about this project, I had many problems that ultimately resulted in my work not working.

First, I tried going about familiarizing myself with RiTA library. I tried scrambling words by creating my own grammar rules through coding, which was mistake number one. I should have been using a lexicon or markov chains, I was super coonfused by RiTa’s poor documentation.

So having trouble with this, I decided to work on the physical element of my project. I connected the arduino to an ethernet shield, and set up an infared receiver as opposed to using bluetooth. It was a more reliable alternative to a notoriously unreliable technology(bluetooth, that is). The Ethernet cable was fairly reliable and despite my own computer dying and having to switch computers midway through my project. I was able to serve up a website that was functional and working, which was an easier part of my project. Here was my code to get that working.

#include <SPI.h>
#include <Ethernet.h>
#include <IRSendRev.h>
#define BIT_LEN 0
#define BIT_START_H 1
#define BIT_START_L 2
#define BIT_DATA_H 3
#define BIT_DATA_L 4
#define BIT_DATA_LEN 5
#define BIT_DATA 6

const int pinRecv = 2; // ir receiver connect to D2
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 144);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup(){
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

IR.Init(pinRecv);
Serial.println(“init over”);

// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print(“server is at “);
Serial.println(Ethernet.localIP());
}

unsigned char dta[20];
void loop(){
EthernetClient client = server.available();
if (client) {
Serial.println(“new client”);
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you’ve gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == ‘\n’ && currentLineIsBlank) {
// send a standard http response header
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”); // the connection will be closed after completion of the response
client.println(“Refresh: 5”); // refresh the page automatically every 5 sec
client.println();
client.println(“<!DOCTYPE HTML>”);
client.println(“<html>”);
// output the value of each analog input pin
for (int digitalChannel = 0; digitalChannel < 6; digitalChannel++) {
int sensorReading = digitalRead(digitalChannel);
client.print(“digital input “);
client.print(digitalChannel);
client.print(” is “);
client.print(sensorReading);
client.println(“<br />”);
}
client.println(“</html>”);
break;
}
if (c == ‘\n’) {
// you’re starting a new line
currentLineIsBlank = true;
} else if (c != ‘\r’) {
// you’ve gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println(“client disconnected”);
}

{
if(IR.IsDta()) // get IR data
{
IR.Recv(dta); // receive data to dta

Serial.println(“+——————————————————+”);
Serial.print(“LEN = “);
Serial.println(dta[BIT_LEN]);
Serial.print(“START_H: “);
Serial.print(dta[BIT_START_H]);
Serial.print(“\tSTART_L: “);
Serial.println(dta[BIT_START_L]);

Serial.print(“DATA_H: “);
Serial.print(dta[BIT_DATA_H]);
Serial.print(“\tDATA_L: “);
Serial.println(dta[BIT_DATA_L]);

Serial.print(“\r\nDATA_LEN = “);
Serial.println(dta[BIT_DATA_LEN]);

Serial.print(“DATA: “);
for(int i=0; i<dta[BIT_DATA_LEN]; i++)
{
Serial.print(“0x”);
Serial.print(dta[i+BIT_DATA], HEX);
Serial.print(“\t”);
}
Serial.println();

Serial.print(“DATA: “);
for(int i=0; i<dta[BIT_DATA_LEN]; i++)
{
Serial.print(dta[i+BIT_DATA], DEC);
Serial.print(“\t”);
}
Serial.println();
Serial.println(“+——————————————————+\r\n\r\n”);
}
}
}

Having the physical side working, I really wanted to get the poetry generation side of things working, whether it be scraped from reddit or just generated from from a text file. I then tried using markov chains to scrape reddit. I even got the api key. I kept getting errors about the rita.js library files I was using. I was stumped, because I hoped to just get it to work smoothly and integrate it with my arduino code. No matter what I tried I couldn’t get it to work the way I wanted it to.I was able to get the basic webpage working, but not actually ever calling the reddit API.  I tried moving files, checking directories,using the console, and redownloading the rita libraries to no avail.  Here is some of the code I tried. I modified from Daniel Shiffman’s examples on his website. My modified code with my reddit api key was lost on my other computer, but here is some of the example code I worked off of.

Screen Shot 2017-05-20 at 11.18.05 AMScreen Shot 2017-05-20 at 11.16.17 AM

 

My last resort was just writing all the code on the arduino and having the arduino scramble strings from three separate arrays, add them together, then serve them up when the infared sensor was receiving data.  In theory, this could work. My logic made sense mostly. However, Arduino memory space is super low and I realized I needed to serve up the files from somewhere remote. Here is what I tried though.

#include <SPI.h>
#include <Ethernet.h>
#include <IRSendRev.h>
#define BIT_LEN 0
#define BIT_START_H 1
#define BIT_START_L 2
#define BIT_DATA_H 3
#define BIT_DATA_L 4
#define BIT_DATA_LEN 5
#define BIT_DATA 6

const int pinRecv = 2; // ir receiver connect to D2
char newPoem;
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 144);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

IR.Init(pinRecv);
Serial.println(“init over”);

// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print(“server is at “);
Serial.println(Ethernet.localIP());
}
unsigned char dta[20];
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println(“new client”);
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you’ve gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == ‘\n’ && currentLineIsBlank) {
// send a standard http response header
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”); // the connection will be closed after completion of the response
client.println(“Refresh: 5”); // refresh the page automatically every 5 sec
client.println();
client.println(“<!DOCTYPE HTML>”);
client.println(“<html>”);
client.println(“<br />”);
client.println(“Press a button on the remote for a new poem.”);

// output the value of each analog input pin
if (IR.IsDta()) // get IR data
{

client.print(“your new poem”);
client.print(“is”);
client.println(“<br />”);
client.print(“<script>”); var myStrings = [“roses are red”,
“the pool is too cold today”,
“angels cry when they see you”,
“cheeto man has no plan”,
“the moon represents my heart”,
“you ran away and now my heart’s perforated”,
“i am the dancing hippo in fantasia,flailing my limbs around, but with grace”,
“you can’t hold me back”,
“hi,ho,off this bridge i go”,
“He’s a Bukowski stuck in the body of a rodent”,
“listen”,
“i hate your big dumb combat boots”];

var myStrings2 =[ “violets are blue”,
“you are the mac to my cheese”,
“the clock ticks its tocks”,
“my limbs are spilling over my bed”,
“won’t you come home?”,
“carousels keep spinning”,
“wind feels all”,
“sea incapsulates water”,
“bueller?”,
“shades of grey”,
“the light in your room”,
“clear,clear water isn’t really blue”,
“green lights lead me to you”];
var myStrings3=[“who am i?”,
“be a piece of weird furniture in my life.”,
“leave me to drown in the waters of finals.”
“rumble,rumble,thump, thump.”,
“alas, the rivers of life flow on”,
“but o! how i love thee”,
“and i keep staring at the face in your ceiling”,
“keepeth me in thoust heart for eternity.”,
“rose had enough room for jack, goddammit!”,
“wild pangolins hobble through your veins”,
“I can paint with the colors of the wind.”,
“you are like wet socks at amusement parks”,
“the internet sees me.”];

function createPoem(){
var poem;
poem = myStrings[random, 0,10] + myStrings2[random, 0,10]+myStrings3[random, 0,10];
}”</script”);
client.println(“<br />”);
client.println(“Press a button on the remote for a new poem.”);
}

client.println(“</html>”);
break;

}
if (c == ‘\n’) {
// you’re starting a new line
currentLineIsBlank = true;
} else if (c != ‘\r’) {
// you’ve gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println(“client disconnected”);

}
//if (digitalChannel == 1) {
// client.println(random);
// }
if (IR.IsDta()) // get IR data
{
IR.Recv(dta); // receive data to dta

Serial.println(“+——————————————————+”);
Serial.print(“LEN = “);
Serial.println(dta[BIT_LEN]);
Serial.print(“START_H: “);
Serial.print(dta[BIT_START_H]);
Serial.print(“\tSTART_L: “);
Serial.println(dta[BIT_START_L]);

Serial.print(“DATA_H: “);
Serial.print(dta[BIT_DATA_H]);
Serial.print(“\tDATA_L: “);
Serial.println(dta[BIT_DATA_L]);

Serial.print(“\r\nDATA_LEN = “);
Serial.println(dta[BIT_DATA_LEN]);

Serial.print(“DATA: “);
for (int i = 0; i < dta[BIT_DATA_LEN]; i++)
{
Serial.print(“0x”);
Serial.print(dta[i + BIT_DATA], HEX);
Serial.print(“\t”);
}
Serial.println();

Serial.print(“DATA: “);
for (int i = 0; i < dta[BIT_DATA_LEN]; i++)
{
Serial.print(dta[i + BIT_DATA], DEC);
Serial.print(“\t”);
}
Serial.println();
Serial.println(“+——————————————————+\r\n\r\n”);
}
}

Mei you memory!! So then I was encouraged to use an SD card, and then try to use an ajax example. I think the ajax strategy legitimately would have worked if I had my own computer. Since ITS wouldn’t allow me to install node. js, that idea was down the drain. Scott stayed calm and told me to use NAS server space. I figured this would work. I was so excited! Maybe, my efforts would result in a working final project. Sadly, my computer from ITS didn’t even have cyberduck on it. I couldn’t even upload the javascript files I had written to the NAS. At this point, it was IMA showtime. I was busy scamming people into my haunted house for staging fright. I threw in the towel and didn’t look back. I honestly tried super hard to make this project work, but in the end, things fell apart. I would say I was misguided in trying to do what I did. I should have just stuck with what I KNEW I could accomplish in two weeks. Given my two other IMA projects, I should have done something that seemed more tangible. I don’t regret challenging myself by working alone, but I definitely should have been smarter about what I could realistically achieve given my time constraints. I also got a more real sense of where things are served up. You can’t just expect arduino magically can serve and store. Plus, I learned that Murphy’s law is just that:a law. It is true. When you most need your computer, it will break. And ITS will have no empathy. And then your phone will die, too, the night of the show, rendering all your documentation pictures useless. IT COULD HAPPEN TO YOU. SO BE WEARY.

 

Final Project

For my final project I wanted to use an ethernet shield, SD card, and Light sensor to create a server with pictures of the sun and moon at different times of the day. I wanted the images to be change based on the changing values of the light sensor. The images that were supposed to be displayed can be shown through a hologram pyramid and rendered into a visual similar to a hologram.  However, I came across multiple setbacks that prevented me from completely finishing the project. At first I was able to send sensor data to the server without any issues. It wasn’t until I tried to include the pictures that I ran into problems.  Initially I was using a MKR1000 to create the server, but they are incapable of storing any images on them. I then switched to an ethernet shield and attempted to use an sd card to store the images on. The SD card that I attempted to use was incompatible with the ethernet shield. Once I acquired the correct sd car I then ran into complications sending data to the server. In a few moments of luck the server would actually work, however the time it took for the server to open the different images was almost 15 to 20 minutes basically making the project ineffective. I discovered that Arduino was having trouble converting the Strings that were created into Chars.

 

Here is an image from when it was workingIMG_0644

 

Here is an image of the error that keep recieving

IMG_0041

 

 

 

 

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>


// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ   20

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 208, 7, 37); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80
File webFile;
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer



  



void setup()
{
    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);
    
    Serial.begin(9600);       // for debugging
    
    // initialize SD card
    Serial.println("Initializing SD card...");
    if (!SD.begin(4)) {
        Serial.println("ERROR - SD card initialization failed!");
        return;    // init failed
    }
    Serial.println("SUCCESS - SD card initialized.");
    // check for index.htm file
    if (!SD.exists("index.htm")) {
        Serial.println("ERROR - Can't find index.htm file!");
        return;  // can't find index file
    }
    Serial.println("SUCCESS - Found index.htm file.");
    
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients
}

void loop()
{
    EthernetClient client = server.available();  // try to get client


int analogChannel=0;
int sensor1 = analogRead(analogChannel);
    
    
    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // buffer first part of HTTP request in HTTP_req array (string)
                // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
                // print HTTP request character to serial monitor
                Serial.print(c);
                // last line of client request is blank and ends with n
                // respond to client only after last line received
                if (c == 'n' && currentLineIsBlank) {
                    // open requested web page file
                    if (StrContains(HTTP_req, "GET / ")
                                 || StrContains(HTTP_req, "GET /index.htm")) {
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connnection: close");
                        client.println();
                        webFile = SD.open("index.htm");        // open web page file
                    }
                    
                    
                    
                    
                    
                    if (sensorReading >350 && sensorReading<=450){
            client.println(" GET / moon.jpg");
          
          webFile = SD.open("moon.jpg");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
          
          





         
          if(sensorReading>600 && sensorReading<=750){
            client.println("GET /page2.htm"); 
client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/htm");
                        client.println("Connnection: close");
                        client.println();
                        webFile = SD.open("page2.htm");
          }
         
                    
                   
                    
                    }


                    
                    if (webFile) {
                        while(webFile.available()) {
                            client.write(webFile.read()); // send web page to client
                        }
                        webFile.close();
                    }
                    // reset buffer index and all buffer elements to 0
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                // every line of text received from the client ends with rn
                if (c == 'n' && currentLineIsBlank) {
                    // last character on line of received text
                    // starting new line with next character read
                  
                
                
                
                
                
                } 
                else if (c != 'r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)
}

// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}

Network Everything Final project – Missing stuff finder, by Diana and Peter

Project Name: Missing Stuff Finder

Group member: Diana, Peter

Instructor: Scott

IMG_2678

Note: The blue pencil case is the wireless stuff tracker, and the mysterious animal is only for being cute and fun

Inspiration:

When we lose our phone, we usually make a phone call to find our phone. But when we can’t find our other stuff like a charger or an Arduino kit, we have no way to find where they are. Therefore, we decided to create something which functions similarly to a phone call. In this way, people can save much time when they need to find their lost stuff.

Design:

We designed that our system aims at dealing with the problems under the circumstances where someone misplaces their properties, and thus fails to find it quickly. This can be very annoying when someone is in a hurry, such as leaving for work or school in the morning. So, our system has the following parts:

Website: We create a website with several buttons on the page. People need to login their name first, then they can press the button on the page to make the hardware receivers play music.

Xbees: The Xbee hub will send commands to receivers when a button is pressed. The Xbee receivers will receive signals from the Xbee hub, and then ask the buzzer to play music, notifying where they are. People can stop the music by pressing the real button on the Xbee receivers. If they still cannot find the stuff even it is buzzing, they can also press the button on the web page to stop all the music.

Major Devices Utilized:

Arduino UNO: supports Xbees and Ethernet shields

Ethernet shields: holding websites

Xbees: including Xbee shields and antenna, consisting of a hub and three receivers

Communicating Protocols Covered:

Serial communication: sending commands from ethernet shield(server) to the laptop which runs a twitter API written in Python.

I2C: Supports the communication between the ethernet shield(server) and the Xbee hub.

Xbees (wireless serial communication): one to many communication between Xbee hub and all the receivers.

SPI: Supports the communication between the microcontroller on the Arduino UNO and the Ethernet chip.

Components: Functions, Problems, and Solutions.

Ethernet Shield (Serving website, sending commands to hub via I2C, send to Python script to track each user’s lost and found info)

We used the Ethernet shield to serve a website that controls the whole system. The ethernet shield communicates which both our laptop and the hub Xbee. In terms of the communication between the shield and the Xbee, the Ethernet shield(along with the Arduino UNO), reports user’s operation on the website to the hub Xbee via I2C. On the other hand, in terms of the communication between the ethernet shield and our laptop, there are two different communications happening. First, the laptop, as a client, requests the web page from the server, and interact with it. This part of the communication is based on the HTTP protocol on the application layer. Second, the laptop also listens to the serial port which connects to the arduino that is running the server. Each time the server realizes there is a “finding request” on the webpage, it will send to request and the username to laptop via serial communication. Once the python script which runs a twitter API on the laptop gets a command, it will post a message tracking the history of finding for each user.

We did have some big problems for this part, the first one is about the content of HTTP request. After the user testing on last Friday, we found that our checkboxes on the webpage could be confusing and misleading. So we replaced it with buttons. After the replacement, we couldn’t get the xbees responding correctly. It seemed that the server was not reading the HTTP_REQUESTs correctly. To be specific, the server was always reading both the current content in the “GET” message, and the previous one. After a long time of debugging, we realized that the reason is that we allowed the server to read the entire client request each time, and there was a part called “referrer” which records the previous content in the previous message. Therefore, we solved this problem by adding an upper bound to the length of the requests the server reads each time, avoiding the server from reading the unnecessary parts of message that could cause interference.

The second problem we had was on hardware, which was relatively simpler. Our initial plan was to stack the arduino, the Ethernet shield and the Xbee shield together, which would make a delicious hamburger of control center. However, we then find that this idea would not work. The truth is, the ICSP does cause problem in this case. It is true that the ICSP header doesn’t matter in terms of communication. However, it matters in terms of power supply. The Xbee shields gets it power right from the ICSP headers, and since there is no ICSP headers for Xbee on the Ethernet shield, we cannot stack them together. This is why we used another Arduino for the hub Xbee and used I2C to connect it with the ethernet part.

IMG_2676

Note: Here is the control centre! The board with the blue ethernet cable is the ethernet shield, and the one with the silver cable is the Xbee hub. 

Xbee System

Our alarming and found system is essentially consist of a hub and several receivers (in our case, three). First, for the communication between the hub and the Arduino running an ethernet shield, we used I2C. We thought we could stack the Arduino, Ethernet shield, and the Xbee shield together like a hamburger, but it turns out that the Xbee gets power from ICSP, and there is not ICSP output headers provided for Xbee shield on Ethernet shields. Then, when the Xbee hub receives the message about which stuff the user is looking for, denoted by 0, 1, and 2, the Xbee broadcasts the message, in the format of “stuff_id + command” to all of the receivers (since it is a one to many communication). After that, the receivers, which are assigned a unique id each, decodes the message by basically subtracting their id off the message, and if the outcome reads “H”, the buzzer goes off, thus notifying the user where the missing stuff is. Finally, when the user finds the buzzing stuff, he or she can go there and press the  button on the stuff to turn it off (The user can also turn things off on the website, which triggers the hub to send an “L”, with the same encoding and decoding scheme). What’s more, the whole Xbee system runs on a program that implements state machine, therefore, the receiver switches between different states(e.g buzzing or silence) in order to avoid any interference that might occur. The biggest problem about the Xbee system is on flow control. The Xbees do have flow control algorithms built in them, but since their receiving buffers are bigger than those on the UNO, we had to add our own flow control in our arduino codes. Of course we didn’t use the flow control algorithm as TCP, which would be horrible. Our idea is instead, making sure that the receivers always read faster than the speed of sending. What’s more, each microcontroller should clear its buffer before switching from a state to another, thus avoiding the system to become messed up by the redundant messages left in the buffer (the redundant messages are created because multiple signals are sent for any single commands to deal with potential packet loss, since wireless is less stable.)

IMG_2679

Note: Here comes the trackers, and their internal look. Again, the bear is just for being cute.

API

Considering the success rate of posting tweets,we didn’t use MKR1000 which runs with temboo. We chose an API offered by twitter and run it on our laptops. It can read data from serial, decode the data from Arduino to python, and then send tweets. But there are still several problems. First, you are not allowed to send the same tweets within around 24 hours. In order to solve this issue, we added a counter to it, incrementing it to record how many times a user has lost a certain stuff, and simultaneously avoiding creating duplicated tweets. But then we found that the counter wouldn’t restart from zero when we change to another user name. So we created a dictionary in Python to store all the user information, and solved this problem. After testing the API for several times, we found that the API would crush down when we login with “Diana”. It’s because in twitter, letter “d” (along with “F”, and “U”) are default shortcuts for directing message, follow or unfollow a certain person, and are thus reserved from API. To avoid the shortcut issue, we added “T_T” to the beginning of every tweet.

Screen Shot 2017-05-20 at 10.35.50

Note: the above is the result on the twitter account

Screen Shot 2017-05-20 at 10.35.36

Note: The above is the twitter API running in terminal.

Future Development & Takeaways

First of all, as what scott has suggested in class, having multiple “missing stuff” playing music all together might cause confusion, we think there are two approaches to deal with this. First, we could force that there can only be one device playing music at a time, which means that when the user is switching from one device to another without “shutting up” the previous device, that device will be turned off automatically before the second one go off. Actually, it was our original design, which can be implemented with only three more lines of codes. However, we then found that a user might want to find two stuffs at a time, and we then changed to adding the “give up” button which can turn off all the devices. Therefore, if we were to improvement on this part, we would take the second approach, that is, giving different devices different music, thus allowing users to differentiate each stuff from all the other.

Secondly, another improvement, a rather ambitious one, would be extending the system to broader use. At this moment, the system can only find the “temporarily missing stuff” within a certain range(about 30 meters), but people might want to find any of their belongings anywhere they want. This would require refinement in terms of at least two aspect. First, the server should be relocated. We would definitely need a online virtual server which can support actual multiple clients. Second, we can no longer rely on Xbees. In this “universal finding system”, every device needs to get online, report their location to the server.

In conclusion, we feel that the process of doing this project turns out to be a very rewarding experience. We get the chance to try out several relatively advanced communication protocols, ranging from HTTP(request and responses) between server and clients to Xbee one to many communication. Most of the communication approaches we picked were actually the ones in which we were interested, but not entirely confident with. Therefore, after doing this project, we feel that we gained a solid and comprehensive understanding of building and appreciating networks in modern context, which is truly a satisfying closure for our valuable experience in this exciting class over the semester.

Thank you for reading, now that’s see the video demo:

Code:

Web server:

Xbee hub:

Xbee receiver:

Python twitter API:

Note: I am only posting the script that calls the twitter post function, which also keep track of each user’s information. In terms of the twitter post script itself, it was provided by twitter, you can find it on the website of twitter API or on github.

Nicholas Sanchez: Internet of Rube Goldberg

For this final I wanted to create a “simple” project made complex via integrating the “Internet of Things”. Drawing inspiration from the Rube Goldberg midterm, I sought to make a Rube Goldberg machine that was instigated via IoT, and at some points facilitated by IoT. Essentially, this machine would be ignited by turning on a button, which would then connect to twitter and tweet. This tweet would be read by the MAKR1000, and then an actuator would activate the next phase in the Rube Goldberg machine. This process would cycle about three times before finally turning an LED on, and tweeting something along the lines of “Hey, the LED is on”.

WHile such a machine would be a huge hardware concern, it was more difficult for me to configure the micro controller with the MAKR1000. Not only because of the technique, but also because there were no MAKR1000s left for me to use. After fooling around with Ethernet shields and and Arduino Yun, I was introduced to the Particle Photon micro controller – a godsend. After learning how to use this board (which was a lot, considering it has little but significant differences from typical Arduinos) Fortunately, there are many online resources for how to use the Photon in an IoT situation.

Ultimately, I decided to connect the particle to Thingspeak, and use Thingspeak as a medium to connect with Twitter. Thingspeak is an online repository where people using internet boards (such as the ESP8266) can save information. In addition to its data storage and visualization, Thinspeak offers built in applications for connecting to Twitter. By using Thingspeak’s applications ThingtTweet, ThingControl, and ThingHTTP, I was able to scrape my twitter account for certain filters or trigger (in this case, “#Thingspeak” as a filter and “blink” as a trigger). This made it such that if i tweeted a message with both the filter and trigger, this would be written to Thingspeak, which in turn would trigger my Photon. when I typed in a tweet with the same filter and the trigger “led”, this would tell my Photon to turn off the mechanisms.

This meant that I could activate the Rube Goldberg mechanisms from twitter. However, I still needed a way to tweet. The cool bit about this was that I used the Photon to directly tweet, via the TCP client library. After some technical difficulty and another few learning curves, finally it all came together. I had the code working such that if I typed in the filter and trigger, as stated above, the photon would turn on one motor, then another motor, and finally light up an LED, before tweeting “#thingspeak led”. Once this tweet was sent, the Photon would scrape that tweet from twitter, and know to turn itself off.

Screen Shot 2017-05-20 at 10.21.47 AM

Now the next part was building a physical housing. I knew that I wanted gears, pistons, smoke, and an LED. The idea was, when the trigger was activated, the first motor would turn the gears and send a tweet saying “gears are on”. Then the pistons would turn, and also send a tweet. Next, the smoke would turn on and tweet. Finally, the LED would turn on. Due to logistical difficulties, I had to dismiss the smoke, but kept the pistons and gears. Using Illustrator, I designed the SVG case for my animatronic. I iterated through it twice, and eventually had a working model.

Overall, this was a great assignment and fun exercise. It was very challenging, but fortunately the resources were available to me. It would be fun to pursue this a little further, and get the machine working well with the smoke. But for now, I am happy with how the machine turned out.

The outside of the mechanism

The outside of the mechanism

The inner mechanisms: motor connected to piston shaft, motor connected to gear, Particle Photon

The inner mechanisms: motor connected to piston shaft, motor connected to gear, Particle Photon

The madness that was this circuit

The madness that was this circuit

Trump Twitter Trasher, Network Everything, David Santiano

cheeto with that mold that sorta looks like hair but it’s not actually hair

trumpo

The Trump Twitter Trasher is a photograph of Donald Trump that has been modified by me to spit out his inane tweets into the trash(which will then be recycled). It works by a server utilizing the Twitter API to grab tweets from Donald Trump’s twitter stream and then storing them into memory in an array, where the tweets are used to populate an html page served by the website and to also be selected to put into the trash.

https://www.youtube.com/watch?v=qhkuF6bx9tE&feature=youtu.be

The technology used was a node.js server running on the back-end, which served up an html page and also communicated with an Arduino via serial communication for the purposes of printing the tweets.

The basic flow of information was:

Twitter —> node.js server —> html page with buttons for selection —> back to node.js server       —> Arduino —> Receipt Printer —> Trash

The whole project was a bit challenging, as I’ve never touched back-end web development before, so terms like sockets and routing and POST and GET requests really flew around my head, so what follows is the giant list of links that I used to obtain some of the knowledge that I need(and may not have needed as well):

http://stackoverflow.com/questions/12134554/node-js-external-js-and-css-files-just-using-node-js-not-express

http://www.dotnetcurry.com/nodejs/1144/nodejs-html-static-pages-website

http://stackoverflow.com/questions/6084360/using-node-js-as-a-simple-web-server

https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods

https://expressjs.com/en/starter/basic-routing.html

http://stackoverflow.com/questions/18831783/calling-a-server-side-function-from-client-sidehtml-button-onclick-in-node-js

https://nodejs.org/api/http.html

http://stackoverflow.com/questions/39215151/how-to-call-a-function-from-html-to-a-javascript-file-in-node-js

http://stackoverflow.com/questions/9670222/execute-a-nodejs-script-from-an-html-page

https://github.com/nebrius/raspi-io/wiki/Getting-a-Raspberry-Pi-ready-for-NodeBots

https://dev.twitter.com/streaming/reference/get/statuses/sample

https://www.npmjs.com/package/socket.io

https://www.npmjs.com/package/serialport

http://stackoverflow.com/questions/33465557/how-to-stop-page-reload-on-button-click-jquery

QUITE A BIT OF INFORMATION!

But, it was a great learning experience, I feel very comfortable now grabbing information from a source and guiding it as it flows through the network I created…342A2408

… and then into the trash.

Pretty great! But, I’d like to smooth out this nice orange diamond a bit more. During the show I noticed that notifying people of the current status of the printer via an alert wasn’t the best, so I want to integrate the warning a bit better. Also, there is a weird encoding issue with the tweet, and I’m thinking it may have to do with escape characters present in the tweet and all that jazz, so I’ll be looking into that. ALSO, I need to find a way to put it on the www.

Here’s some of the code, the html file, the arduino file, and also the node server javascript file:

 

Network Everything’s Final Project

DOCUMENTATION

The story?

The idea comes from my own problem of having problems finishing a physical book (eBook too actually but that’s another story). I thought, perhaps, if I incentivise myself with some candies, I’d finish a book or two.

All the books I've never got to finish

All the books (and more tbh) that I’ve never got to finish

What does this do?

This project consists of two parts. The first one being a bookmark, while the other one is a candy box. The idea is to make a bookmark that’s placed in between pages that I plan to reach/read. When I reach the page (where the bookmark is placed at), a candy will get dispensed.

The bookmark and the candy box would communicate via wifi. The idea is wherever you are in the world (okay maybe more like, when you’re bookmark and the candy box are in the same city), you can still trigger the candy box (and get candies cos candies are awesome) as long as you’re connected to the wifi. So an example of this would be you would be able to read a book on a subway (so long as you’re connected to the net) and find some candies when you’re home.

What are the materials?

I used two MKR1000, one for the bookmark and the other one for the candy dispenser.

For the bookmark, I used two copper strips hooked up to a MKR1000. They act like a button that activates the candy box. I used pull-up to activate the candy box on the other side.

As for the candy box, I laser-cut a candy box with ramps (FTW!) in it. There will be a gate controlled by a servo that’ll open when you reach the page you’ve placed your bookmark in. When the gate opens, candies will roll out.

The candy box and the bookmark will be connected through wifi via IFTTT’s Maker Webhooks, a project that lets my two MKR1000 talk to each other

Assemble!

The assembly process itself was rather straightforward, except for the constant adjustments, e.g. adjusting the position of the gate, adjusting the delay time, adjusting the position of cables, etc.

Software for the software part, it is rather straightforward except for the part where I was to connect my MKR1000 to IFTTT. This process didn’t feel as intuitive to me and the documentations online didn’t quite feel that helpful either, but after a *while* of tinkering, *good* things started to happen, so that’s great. I tried my best not to jump into making a bookmark that triggers the candy box right away. I tried to start small with turning on an LED with a push of a button (connected via the wifi). From there, when things worked fine, I swapped the LED with servo. I ran into issues incorporating the servo into the equation, but it went fine after a while. Afterwards, I then modified the code of the button to make it trigger the servo with pull-up resistance.

Although the whole process took quite a while, I’m glad that I did it all in small steps as opposed to diving into connecting a servo with a pull up button right away. That helped a lot in identifying issues (and fixing them).

For the bookmark, I combined the code from Marco Schwartz’s IoT Cookbook and Arduino’s Pull Up. As for the candy dispenser, I combined the code from the same book and Arduino’s Mini Servo. For the Mini Servo, I did some modifications with the delay (thanks to Angelica for suggesting how much the delay should be!) and the angle that the servo should move.

Hardware I was wrong when I thought that the software part of this project would’ve taken more time than the hardware part. For the hardware part, there are two components I had to take into account: the bookmark and the candy box.

The bookmark. Initially, I was set on using touch/pressure sensor to trigger my candy box. However, Scott suggested that I swapped the sensors for copper strips because copper strips could get the system running with little to no force/pressure. This would be more suitable because a bookmark that’s placed in between pages won’t usually receive that much force/pressure.

IMG_20170518_121304

The-initially-dispenser-turned-candy-box Initially I wanted to make a candy dispenser that looks like an actual dispenser (sigh). However, after hours of tinkering with 3D modelling software, I figured that I had been spending too much time on it and should probably opt for something simpler, thus the candy box. I laser cut MDF boards and assembled them by using wood glue. For the front part, I use an acrylic board. 

The Result The result is this bookmark that triggers candy dispenser when they two sides of the bookmark aren’t touching.

What I Wish I Could’ve Done Differently

Size of the bookmark I’d love to have a bookmark that’s not as big as the one I designed. I’d love it to be a lot smaller and thinner, and possibly, not wired to a power bank. I imagined it would need a bit more research and thinner-battery hunting.

The dispenser If I had more time, I’d love to work more on the dispenser and make it look like an actual dispenser. I guess there isn’t exactly any problem with this candy box, but I personally would’ve liked to see a better-looking candy box.

Weight sensor I think it would’ve been more fun to have the weight sensor and the notification system, too. I’ve actually made the whole notification system working (using Temboo and Google Mail), but I never got around adding the weight sensor so I had to forgo the idea.

//servo code
// Import required libraries
#include <SPI.h>
#include <WiFi101.h>
#include <PubSubClient.h>
#include <aREST.h>

//servo 
#include <Servo.h>;
Servo servo1; 
int pos;

// Status
int status = WL_IDLE_STATUS;

// WiFi parameters
const char* ssid     = "Tirza";
const char* password = "tirzacarlo";

// Clients
WiFiClient wifiClient;
PubSubClient client(wifiClient);

// Create aREST instance
aREST rest = aREST(client);

// Variables to be exposed to the API
bool ledState = false;

// Function
int ledControl(String command);
void callback(char* topic, byte* payload, unsigned int length);

void setup(void)
{
  // Start Serial
  Serial.begin(115200);

  // Set callback
  client.setCallback(callback);

  // Function to be exposed
  rest.function("toggle", ledToggle);

  // Give name and ID to device
  rest.set_id("didiLED");
  rest.set_name("mkr_led");

  // Connect to WiFi
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, password);

    // Wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("WiFi connected");

  // Pin 6 as output
//  pinMode(6, OUTPUT);

  servo1.attach(6);
}

void loop() {
  
  // Connect to the cloud
  rest.handle(client);

}

// Custom function accessible by the API
int ledToggle(String command) {

  ledState = !ledState;

  servo1.write(90);
  
//  for(position = 180; position >= 0; position -= 1)
//  {                                
//    servo1.write(position);  // Move to next position
//    delay(20);               // Short pause to allow it to move
//  }

  for (pos = 90; pos >= 55; pos -= 1) { // goes from 180 degrees to 0 degrees
    servo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 55; pos <= 90; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    servo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
  }
  delay(5000);
//  delay(1000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //5
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //10 - 10 * 10 * 1000ms
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //15
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //20 - 20 * 10 * 1000ms
  return 1;
}

// Handles message arrived on subscribed topic(s)
void callback(char* topic, byte* payload, unsigned int length) {

  // Handle
  rest.handle_callback(client, topic, payload, length);

}




// Bookmark Code 
// Libraries
#include <SPI.h>
#include <WiFi101.h>

// Status
int status = WL_IDLE_STATUS;

// Credentials
const char* ssid     = "Tirza";
const char* password = "tirzacarlo";

// IFTTT settings
const char* host = "maker.ifttt.com";
const char* eventName   = "toggle";
const char* key = "p96PFiscY---nII2hLRkE7BOhVGjUHfgLpz30adDNrm";

void setup() {

  // Seroa;
  Serial.begin(115200);
  delay(10);

  // Connect to WiFi
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, password);

    // Wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("WiFi connected");

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  //pulllup
  //start serial connection
  Serial.begin(9600);
  //configure pin 6 as an input and enable the internal pull-up resistor
  pinMode(6, INPUT_PULLUP);
}


void loop() {
  int sensorVal = digitalRead(6);
  
  if (sensorVal==HIGH) {

    // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // We now create a URI for the request
  String url = "/trigger/";
  url += eventName;
  url += "/with/key/";
  url += key;
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1rn" +
               "Host: " + host + "rn" + 
               "Connection: closernrn");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }
  
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('r');
    Serial.print(line);
  }
  
  Serial.println();
  Serial.println("Closing connection");
  delay(5000);
//  delay(1000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //5
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //10 - 10 * 10 * 1000ms
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //15
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000);
//  delay(10000); //20 - 20 * 10 * 1000ms - 3 minutes 

  }else{
    Serial.println("You're not at the page you want yet!");
  }
  
}

Network Everything Final Project – Intrudead – Ale, Olesia, Elaine

Our Original Idea

After learning that someone took equipment from our class cart without our instructor’s permission we decided to prevent this from happening again. Our solution was to create an alarm system that will tell our professor when someone has taken something from our class equipment without his permission. We imagined that we could do this by sending an email to our professor with the picture of the person who’s stolen our equipment. In addition to that, we would discourage anyone to steal from our class cart by uploading a picture of the people who have stolen from us to a public website. We dubbed this website the “Hall of Shame”.

 

Our Final Product

I guess we have accomplished everything we wanted. As for now, we have a fully set-up system that detects intruders. So, let me explain how our project works. Essentially, we built a light sensor circuit, the light sensor is in the state of constant darkness. If an intruder opens the box or the cart, the light sensor gets exposed to the light and this mechanism triggers several things: first, a picture of the intruder is being taken, it is being sent to Scott’s email, it is being uploaded to the website called “Hall of Shame” (publicly available at here)  which stores all the photos of all intruders. Moreover, we also set up an RFID system and assigned a particular RFID tag to Scott. Basically, if Scott is the one who opens the cart then there is no need to send an email and post the photo to the website, hence, Scott can swipe his own tag which will cancel the email sending and posting pictures to the blog. However, you have to hold the tag for 10 seconds in order to cancel the email.

The source code is available at https://github.com/ElaineAng/Final-Project-Net. Email us if you have access issues.

Here are two short videos recording how we expect it to work:

Here is a screenshot of some of our “Intruders” appearing in the email attachment.

intruderPic

Technical Difficulties

First, the RFID tag would not work all the time. It took us may days to figure out why the RFID system stopped working even though none of the code had been changed. Once we figured it out, we had to connect the RFID tag system to the main processing code via Bluetooth. There was no major hindrance with that. It was just the matter of time. However, we lost the initial tag that had been assigned to Scott, so we had to replace it with another and go through the whole setup process again. Thanks to the amazing  Arduino Atmega board that provides multiple serial communication interfaces, we are able to receive information from the RFID reader and send information to the processing sketch via bluetooth using one board.

 

Setting up the email system was also a challenge for us. At first, we tried using Temboo to send e-mails. Although we could successfully send emails with Temboo and Processing, we weren’t able to send picture attachments as it asked us for a URL and couldn’t attach pictures that were stored locally. Our second attempt at fixing this issue was to use Processing with the Javax mail library. However, this didn’t work out as the library is deprecated and the example code dated from 2007. Finally, we used Node and Processing to solve this issue. We basically ran a local server that runs an email script every time someone tries to access a specific page. Processing becomes the client by making a GET request to the page that triggers the Nodemailer script to send an email with a picture attached to it.

 

Posting the image to a website after it’s being taken is a bit challenge as well. Since we need to arrange for the processing sketch to post the picture in real time, and it was a new experience for each of us. We did not find any suitable APIs or image hosting sites that does this for us, so we decided to write our own script. We find two open source php script that does similar things and put them on a web server, which is configured to be accessed via a domain name. The index.php scripts handles reading a directory and displaying the image, the upload-n-save.php scripts handles image posting and saving them locally on the server.

 

What we would want to change

The only change we would  want to implement is to upgrade the way we use external cameras (e.g. use an external web-cam or using a serial camera attached  to a Raspberry Pi) to increase the quality of the photos taken because sometimes the embedded web-cam would take pictures of humans parts’ of the body or the box. This would improve the content of the website as well as help Scott to identify the intruders and punish them. I guess this is the only change that would make a difference.

Final Documentation: The Alert Bracelet (Sidra and Gabriela)

Project Partners: Sidra Manzoor and Gabriela Naumnik

Idea:

We wanted to help older people quickly and easily notify their family member in case of an emergency. We were inspired by a “Grace and Frankie” episode in which both older ladies fell, could not get up and had no possibility of calling for help as their phones were in different rooms. Based on this episode, our idea was to create a bracelet with a button, which, once pressed, would trigger an email message to be sent to a family member with information that help is needed as well as the location of the person. In order to better visualise the target users, we thought of “Grandma Edith”: an old lady in her 70s who lives by herself in New York.

1st stage of development:

(link: http://ima.nyu.sh/documentation/2017/05/09/the-alert-bracelet-tuesday-updates-gabriela-and-sidra/):

We started off by creating a Temboo for Gmail API. To do this, we had to verify one of ours Gmail accounts to get the verification key (which required activating Gabriela’s Polish phone number since our Chinese numbers did not work for some reason). Then, we set the title of the alert email to “HELP ALERT!” and the body to “I need help. Please, come as soon as possible.” We decided that the email is going to be sent when the button is pressed from “Grandma’s” account: nefron17@gmail.com to Sidra’s account (“close relative”). The next step included generating the code and connecting MRK1000. Initially, we had problems connecting MKR1000. It turned out the the one we checked out was broken. Thus, we managed to obtain another MKR1000 which worked just fine. The second problem was that the working MKR100 was not connecting to the WIFI because we did not include the WIFI password in the code. Finally, after fixing that issue, we run the Temboo choreo request and it worked! The Serial monitor showed the following request:

Temboo request 1

After a minute, the HELP ALERT email showed up in Sidra’s inbox:

Screen Shot 2017-05-19 at 1.43.10 pm

However, later on we encountered some problems. Our email was sent out once and we could not make it send again. So, to solve this, we decided to set up an entirely new gmail account called grandmaold98@gmail.com. This time we went through Google’s Developer’s Console to obtain our gmail account’s client Id and Secret and run the Temboo Choreo through that process. This time, our choreo requests were successful! At this point we added in a push button to control when the help email would be sent. The following video shows that once the button is pressed, Sidra receives an email from grandmaold98@gmail.com:

2nd stage of development:

This week we experimented with the Grove GPS module to get location data for the alert message. In order to see what values were given out from the module, we used example code from class. After connecting the module we received the following readings indoors:

Screen Shot 2017-05-11 at 4.05.13 pm

After making sure we connected it properly, we took the module outside and we got readings!

While using the module, we had a hard time understanding the data that was given through it. In order to only get the latitude and longitude values, we used the tinyGPS++ library. Through that we were able to directly call latitude and longitude without much difficulty. After successfully getting the GPS data, we tried to get the module to work with the MKR1000. The main problem here was that the software serial did not work with the MKR1000 therefore we had to use the hardware serial which did not give us immediate feedback. Due to this, it was very difficult to keep track of the GPS data that was being recorded through the GPS module. Our work around for that was that we first connected the module to an Arduino Uno to see the GPS readings. Through this, we found that they were floats logged in as 0.00 (The value was zero since we were indoors and could not get accurate location). After knowing that it was a float, we tried to send that 0.00 as a string in an email through Temboo. However, after many failed attempts we realised that zero by itself cannot be sent through the server since it reads as a null value. To solve this problem, we wrote a string in the email body “My location is at: ” and concatenated the latitude and longitude values to a google maps url to finally be able to send the values in an email.

Screen Shot 2017-05-12 at 8.47.12 pm

After getting the code to work, we soldered all the different parts onto a perfboard and powered the bracelet with a lipo battery. We then sewed a bracelet with a pocket to place the board within. Here’s what the board and bracelet looked like. We used the foam hand because why not be extra?

File_000   File_001

3rd stage of development:

This time, we started running tests on our device. At this point, we were confident that our device would work properly; however, things don’t always go as planned. Unfortunately, while getting the GPS module onto the perfboard, we accidentally damaged it. Due to which, we were no longer able to get location data. Since this was the last module we had, we could not work with GPS any longer. 

However, as an alternative solution, we decided to replace the module with three push buttons, each of which would send out a different location in the email on being pressed. As our target group are older people living alone, with health problems, it makes sense to assume that they do not move much around the town during the day. They may either be at home, at friend’s home, grocery store or, for example, a park. Therefore, we linked the three locations (her home, friend’s house, and central park) to the three push buttons. We also linked the buttons to three different LED’s so that once the button is pressed, the user would get feedback from the bracelet i.e. an LED would light up.

 

File_001 (1)

Screen Shot 2017-05-19 at 2.36.34 pm

Reflection:

All feedback given by other IMA friends indicated that our project is useful and indeed needed. Within a short time frame we created a wearable which works and serves its purpose of making sure that older people can get help if they find themselves in a hopeless situation alone. Even though GPS Grove broke down, we found another solution and demonstrated a developed product which can be used. We feel that we learned a lot from the process which helped us better understand how devices can be networked and how knowledge gained in the classroom can be applied to solve real world problems.

 

Week 14: Final Project Documentation (Fitzgerald)

Partner: Robert

Our final iteration of our project took a slight turn from our original whack a mole idea. At first, we wanted to have a series of five targets that the user would then throw a ball at to trigger a vibration sensor. However, this idea was perfect in concept but when it came time to put it into action some aspects began to falter. Therefore, we shifted to a revised version of whack-a-mole that was more reminiscent of a target shooting game. Our final iteration had two targets, where one would randomly pop up and then the user would have to hit the target with the ball. We felt this game was engaging and interactive, making it both a fun and technically challenging final.

Since we have had a basic concept down, which include work with buttons, LED lights and Twitter API, we have decided to continue to work on parts of our project which we have originally planned. However, we came across some problems. The Small Arduino Servo Motors that came with the original Arduino Kit were not powerful enough to support the bull’s eye, which we have attached to each motor. In the process of doing so, two of the motors (out of 5 broke), because they were very fragile to start with. We could not borrow the motors from the check-out room because they did no longer not have any, thus we asked some of our peers to lend us, but they did not have it either. Since the small servo motors were so prone to be broken and could not support the bull’s eye, we decided to go with the Bigger-Size Servo Motors. However, they only had two of them, so our initial idea of using 5 servo motors (one for each bull’s eye), came down to using two. Here is the picture of how it looked after we have switched our motors:

IMG_6900

While we were still working with big servo-motors, we have only taped them with scotch tape (middle bottom part of the above picture), instead of hot-glue gun gluing it, in case if we had to change the position of the servos (left side-right side). Thus, all of the bull’s eyes were laying on their right side, and they were going to pull-up by rotating anti-clockwise. The wires in the pictures have not yet been taped together because of we were in the stage of testing how each servo worked as well as the servo schematic. From this situation, we have learned that better planning strategy regarding our hardware parts should be implemented at early stages of our project, in order to later avoid downscaling the project, instead of shooting for more and pushing our limits. This is how it looked like:

IMG_6899

After we have tested our servos and made sure that they were wired properly, as well as that they were functioning correctly we have decided to glue it to the wooden framework using the hot-glue gun. However, just as we did that the middle servo-motor (out of total 3 servo-motors that we had) suddenly stopped working and we could not figure out why, so we have eventually ended up only using 2 big servo motors. However, after that, we have come across the issue of vibration sensor not working as intended. In our initial plan, we have decided to use the vibration sensor which would be placed being the bull’s eye, so each time that it would be hit, it would detect vibration, and send that information to an Arduino. However, the sensor only worked if we have pressed it very hard with our finger, and only then would it display the significant change in the vibration levels in the Arduino Serial Monitor. We have thought to test the sensor by putting it in the middle of bull’s eye, and hitting the exact middle with something extremely hard, however, that did not prove to be effective either.

However, we have finally managed to come up with another fairly successful solution – using the motion sensor. Although this is something that we haven’t planned from the start, we have decided to attach two motion sensors, one on top of each bull’s eye, which would track specific movement that comes within its range in case if the player hits the specific area of the bull’s eye (approx. strip line in the middle). The medium-sized balls that we made were created out of approx. 5 meters of scotch tape each. After careful consideration of the shooting range, and the height of the platform to which we have mounted the sensors onto. We have set values for the motion sensors in the Arduino: If the user threw a ball and a motion sensor would detect that the ball has successfully hit the bull’s eye, the Arduino would update the result for the specific player who was playing that part of the game. This is the video of the project working.

Although most of our hurdles were on the hardware side of things, our project was not without its software difficulties. Since we were working with the MKR1000 to have a wireless connection, we had to depend on the school IMA wifi. However, the network topography of our school’s wifi makes the MKR1000’s connection unreliable. Additionally, we both decided to use a simple, in place, sorting algorithm-which ordered a subset of a 2d array. This aspect, although simple to say proved to be hard in programming since we are used to programming in java-where data structures function very differently. Lastly, the area we spent a lot of time on was having an accurate timing system, where the US range sensor would read at the exact moment the motor swept to the top and would stop reading once it began to sweep down.  As a side note, working with Temboo proved to be unreliable and a finicky situation. In the end, our success rate (on temboo’s end) was hovering around 50%, which for a final project is not ideal.

If we were to do this again, we would plan our hardware components more carefully – everything from the servo-motors to the types of sensors that we are using. We would also go check-out particular part of hardware which is fairly popular several weeks before the project was due, in order to ensure that this part of hardware will be available. If we have access to any type of sensors at the moment, we would most likely use a different type of vibration sensors and increase the number of servo motors that we have decided to include. We could also potentially add the 4th player, so the number of all players for a single game is even, rather than odd, thus people can play it in pairs!

#include <Servo.h>

//LEADERBOARD
String leaderboard[4];
String finalMessage;
int runs = 0;

//Vibration and Motor VALUES
int pingPin = 9;
int pingPin2 = 10;


//MOTOR
Servo motor1;
Servo motor2;

//Game Variables
int score = 0;
int gameLength = 8;

//Libraries and Wifi
#include <SPI.h>
#include <WiFi101.h>
#include <Temboo.h>
WiFiClient client;
int status = WL_IDLE_STATUS;
#define WIFI_SSID "NYUSHIMA"
#define WPA_PASSWORD "Vlc5k$zf"

//Twitter Info
int calls = 1;   // Execution count, so this doesn't run forever
int maxCalls = 10;   // Maximum number of times the Choreo should be executed
String twitterName;

//Temboo Info
#define TEMBOO_ACCOUNT "robertp"  // Your Temboo account name 
#define TEMBOO_APP_KEY_NAME "myFirstApp"  // Your Temboo app key name
#define TEMBOO_APP_KEY "aLoLsqjPQQ5fFlgks7s8pXN11dBVegIv"  // Your Temboo app key

void setup()
{
  //Beginging Serial and Connecting to Wifi
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to WiFi network:
  
    while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(WIFI_SSID);
    //Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(WIFI_SSID, WPA_PASSWORD);

    // wait 10 seconds for connection:
    delay(10000);
    }
  
  Serial.println("Connected to wifi");

  //BUTTON SETUP
  Serial.begin(9600);
  getName();
  motor1.attach(6);
  motor2.attach(8);
}

void loop() {
  if (runs > 0) {
    {
      Serial.println();
      Serial.println("Get ready to play");
      Serial.println("3");
      delay(1000);
      Serial.println("2");
      delay(1000);
      Serial.println("1");
      Serial.println("START!");

      //THIS IS WHERE I RUN THE GAME
      int x = 0;
      while (x < gameLength) {
        motor1.write(0);
        motor2.write(0);
        int randNumber = random(2);
        if (randNumber == 0) {
          Serial.println("MOTOR 1");
          motor1.write(0);
          delay(2000);
          long duration, inches, cm;
          motor1.write(240);
          delay(500);
          long starttime = millis();
          long endtime = 0;
          while ((endtime - starttime) <= 3000) // do this loop for up to 1000mS
          {
            long duration, inches, cm;
            
            pinMode(pingPin, OUTPUT);
            digitalWrite(pingPin, LOW);
            delayMicroseconds(2);
            digitalWrite(pingPin, HIGH);
            delayMicroseconds(5);
            digitalWrite(pingPin, LOW);

            // The same pin is used to read the signal from the PING))): a HIGH
            // pulse whose duration is the time (in microseconds) from the sending
            // of the ping to the reception of its echo off of an object.
            pinMode(pingPin, INPUT);
            duration = pulseIn(pingPin, HIGH);
            cm = duration / 29 / 2;
            if (cm < 20 and cm > 3) {
              Serial.println("YOU HIT THE DANG BALL");
              score++;
              break;
            }
            endtime = millis();
            delay(100);
          }
        }
        if (randNumber == 1) {
          Serial.println("MOTOR 2");
          motor2.write(0);
          delay(2000);
          long duration, inches, cm;
          motor2.write(240);
          delay(500);
          long starttime = millis();
          long endtime = 0;
          while ((endtime - starttime) <= 3000) // do this loop for up to 1000mS
          {
            long duration, inches, cm;
            
            pinMode(pingPin2, OUTPUT);
            digitalWrite(pingPin2, LOW);
            delayMicroseconds(2);
            digitalWrite(pingPin2, HIGH);
            delayMicroseconds(5);
            digitalWrite(pingPin2, LOW);

            // The same pin is used to read the signal from the PING))): a HIGH
            // pulse whose duration is the time (in microseconds) from the sending
            // of the ping to the reception of its echo off of an object.
            pinMode(pingPin2, INPUT);
            duration = pulseIn(pingPin2, HIGH);
            cm = duration / 29 / 2;
            if (cm < 20 and cm > 3) {
              Serial.println("YOU HIT THE DANG BALL");
              score++;
              break;
            }
            endtime = millis();
            delay(100);
          }
        }
        x++;
      }
      checkLeaderboard();
      if (runs >= 3) {
        sendTweet();
      }
      score = 0;
      getName();
    }
  }
  runs++;
}

void getName() {
  Serial.println("Please enter your twitter name with the @ sign");
  Serial.println("If you do not have a twitter account, enter normal name");
  Serial.println();
  while (Serial.available() == 0) {}
  char rx_byte = 0;
  String rx_str = "";
  while (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // get the character

    if (rx_byte != 'n') {
      // a character of the string was received
      rx_str += rx_byte;
    }
  }
  rx_str.trim();
  twitterName = rx_str;
  Serial.println("Welcome " + twitterName + " to the game!");
}

void checkLeaderboard() {
  if (runs == 1) {
    leaderboard[0] = String(score) + twitterName;
  }
  else if (runs == 2) {
    if (leaderboard[0][0] < score) {

      leaderboard[0] = String(score) + twitterName;
    }
    else {
      leaderboard[1] = String(score) + twitterName;
    }
  }
  else {
    if (runs == 3) {
      leaderboard[2] = String(score) + twitterName;
    }
    else {
      leaderboard[3] = String(score) + twitterName;
    }
    String copy[4];
    for (int i = 0; i < 4; i++) {
      copy[i] = (leaderboard[i]);
    }
    for (int i = 0; i < (4); i++) {
      for (int o = 0; o < (4 - (i + 1)); o++) {
        if (copy[o][0] >= copy[o + 1][0]) {
          String t = copy[o];
          copy[o] = copy[o + 1];
          copy[o + 1] = t;
        }
      }
    }
    Serial.println();
    Serial.println("HERE IS THE CURRENT LEADERBOARD!!!!");
    String name1 = String(copy[3]);
    String score1 = String(copy[3][0]);
    name1.remove(0, 1);
    String name2 = String(copy[2]);
    String score2 = String(copy[2][0]);
    name2.remove(0, 1);
    String name3 = String(copy[1]);
    String score3 = String(copy[1][0]);
    name3.remove(0, 1);

    finalMessage = " " + name1 + " " + score1 + " " + name2 + " " + score2 + " " + name3 + " " + score3;
    Serial.println(finalMessage);
    Serial.println();
    leaderboard[0] = copy[3];
    leaderboard[1] = copy[2];
    leaderboard[2] = copy[1];
    leaderboard[3] = "";
  }
}

void sendTweet() {
  Serial.println("WIFI STATUS");
  Serial.println(status);

  TembooChoreo StatusesUpdateChoreo(client);

  // Invoke the Temboo client
  StatusesUpdateChoreo.begin();

  // Set Temboo account credentials
  StatusesUpdateChoreo.setAccountName(TEMBOO_ACCOUNT);
  StatusesUpdateChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
  StatusesUpdateChoreo.setAppKey(TEMBOO_APP_KEY);


  // Set Choreo inputs
  Serial.println(finalMessage);
  String StatusUpdateValue = "LEADERBOARD " + String(finalMessage);
  StatusesUpdateChoreo.addInput("StatusUpdate", StatusUpdateValue);
  String ConsumerKeyValue = "GCgsedFeeDPjGcXX6w7omleM4";
  StatusesUpdateChoreo.addInput("ConsumerKey", ConsumerKeyValue);
  String AccessTokenValue = "861505638966243330-NnNA8w7IiMYkKzlGhJv1vxpK2F3CAcj";
  StatusesUpdateChoreo.addInput("AccessToken", AccessTokenValue);
  String ConsumerSecretValue = "8ZkAB0IDCwPCg0w6gADnCzCRYufI4n7hSJkufS3UBCRa45vdPI";
  StatusesUpdateChoreo.addInput("ConsumerSecret", ConsumerSecretValue);
  String AccessTokenSecretValue = "sTCuHtTozozZvYVX3oFRIuF4tfLUOEXRpe1waaKU2R3AJ";
  StatusesUpdateChoreo.addInput("AccessTokenSecret", AccessTokenSecretValue);

  // Identify the Choreo to run
  StatusesUpdateChoreo.setChoreo("/Library/Twitter/Tweets/StatusesUpdate");

  // Run the Choreo; when results are available, print them to serial
  StatusesUpdateChoreo.run();

  while (StatusesUpdateChoreo.available()) {
    char c = StatusesUpdateChoreo.read();
    Serial.print(c);
  }
  twitterName = "";
  StatusesUpdateChoreo.close();
  Serial.println("nWaiting...n");
  delay(10000);
}