Uncategorized – Intro to Physical Computing: Student Work https://courses.ideate.cmu.edu/60-223/f2018/work Intro to Physical Computing: Student Work Sun, 16 Dec 2018 16:38:47 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.25 Productivity Tree https://courses.ideate.cmu.edu/60-223/f2018/work/productivity-tree/ https://courses.ideate.cmu.edu/60-223/f2018/work/productivity-tree/#respond Thu, 25 Oct 2018 18:31:18 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4485 This is a project to promote productivity by creating a “punishment” if I look at my phone, and a “reward” if I go long enough without looking at it.

This is an overall photo of my project; this includes the tree and the phone cover as well as the wiring that makes all of it work.

This is a picture of the main tree alone; this was laser cut using white acrylic, and is the focal point of the project.

This is what the back of the tree looks like; there are LEDs hot glued to the back that will light up eventually.

 

This is the inside of the phone cover; there is a light sensor (that will probably not be used) and an accelerometer that checks to see if you move the cover to access your phone.

Here is a gif displaying the “success” reaction (when the person manages to wait the full time length without distraction)- followed by a wait, then the “failure” reaction (what happens when/if the person gets distracted and tries looking at their phone).

Process

Initially I had the (ambitious) idea of creating about 5 trees that could be raised at a controlled rate, and all would “grow” and eventually all create a “forest.” The major roadblock I had with that idea was finding out that making things go up and down (especially at a controlled rate) is not trivial- it requires a pulley system to make things go up and down, and it requires a stepper motor to make things move at a controlled rate. Unfortunately, a stepper motor is quite heavy and somewhat large- which convinced me that it was probably impractical to have 5 different stepper motors all moving these trees. I also didn’t think it would really be doable- or visually attractive- to have the stepper motor hovering above where the tree would be lifted, so I thought of creating a pole for a string for the pulley to go over, so the motor could be hidden within a box on ground level.

This is a schematic of my original idea; you can see how the tree was supposed to emerge from a hole, and how the stepper motor was supposed to be hidden.

My work came to another halt as I tried to understand how to laser cut everything I needed to- I don’t have permission to laser cut on my own, so I would need to try and make the one hour a day that the laser cutter open hours were available to laser cut- as well as try to learn the software needed to create my designs. By the end, I managed to learn more; but the day before, I still had not created the gears needed to be put around the stepper motor, or the box that everything would hide underneath. I decided that I was making this too large an undertaking and rethought my idea; I had all the code working, so I could keep the concept and just change the execution.

I changed ideas- instead of having a physical tree “grow,” there would be a large tree already standing that would symbolically “grow”- with lights going up the tree as time passed to show that time is passing. If I looked at my phone and “failed” it would flash red lights, and if I managed to not procrastinate I would “succeed.”

Here is a crude diagram of my final idea- in this sketch, I feature about 11 lights on the tree, and show where I chose to put them, and how long I want each one to take before lighting up.

An unexpected difficulty that I did not anticipate was the wiring and the length of time it would take to solder- each LED needs an input and an output- so 22 wires for that- and each LED also needs a resistor (of 330 ohms), so that was 11 more resistors that I also needed to solder onto my breadboard. This photo is a picture of the mess of wires that took place about halfway through the soldering process.

Discussion

In the crit, I got a few responses, such as: “I don’t fully understand the purpose of the light sensor”. This made me evaluate the purpose of including a light sensor as well; initially, I thought that if the person was to click on their phone or move it that the program would “fail”, however with a cover it is impossible for someone to click their phone without moving the cover. I think that trying to incorporate a light sensor overcomplicated the project and didn’t match my purpose; so I would get rid of the code that involved lighting and remove the light sensor- in the circuit diagram I didn’t include it because it lost its purpose as is.

I also got a response saying “I really liked the concept, but maybe you could make another tree for the back to hide the wiring and lights”. I really liked this comment, because I never thought of adding a back to this project- I only envisioned it being 2D with a front and not a back that would be used. I also imagined hiding the majority of the wiring with another box, that would also hide the breadboard and the Arduino. After creating the extra box with the material I have, I will see if I have enough to create a back for what I have now- I think it would make my project cleaner and more attractive in other locations.

Frankly, I am not totally satisfied with how my project came out. I really like how my tree and phone cover came out, but the extra wiring is very off-putting. In addition, during the crit my code didn’t fully work because I forgot to add the wiring of the accelerometer. I consider this project unfinished because I want to work at it until it both looks attractive and functions well consistently.

That being said, I learned a ton in this process. One of the things I learned is that moving things are more difficult than I anticipated. I also learned how to create my own laser cutting file- something that I think may come in handy in the future for my own projects. Due to all the soldering I did, I got a lot of practice and got to work on proper soldering techniques. This project was frankly frustrating at many points, and I am the type who hates having to downscale (like when I changed directions from having 5 moving trees to 1 large stationary tree), but I’m very grateful for learning the different difficulties that comes with creating a project. Next project I think I will focus on all the hardware first, especially all the sizing/laser cutting things- and get more help earlier when I run into something I am more unfamiliar with.

I still plan to work more on this project- I want to create a box, or some kind of container, that can hold the wiring, breadboard, and Arduino in a way that is attractive. I want to make sure all the lights on the tree are bright as well- and maybe add an LED strip to make there be more lights and a more dramatic effect. I also want to learn how to connect my project to a battery pack so I may use it to study when I’m not near my computer. Also as of right now the timer and the button are in inconvenient spots; I would integrate them into the box that I will be creating.

 

//Megan Roche
//Productivity Tree
//This is the code to create a "tree" that has lights that help you stay productive. A list of the inputs/outputs and what they do are below.


//what is needed (input): mute button, potentiometer (timer), set time button, maybe second timer?
//what is needed (input sensors): photosensor (dramatic change), accelerometer (dramatic change)
//what is needed (output): various lights? all on string, motors that move gradually
//different effects:
//  if set button pressed, start timer for whatever potentiometer is at
//    use internal clock and compare, have timer be unsigned long
//  if dramatic change happens with either sensor, then immediately "quit"
//    if "quit", then have motors (trees) go all the way down
//    if not "quit", then have motors continue moving gradually

#include <AccelStepper.h>

unsigned long timer;
const int LIGHTONE = 0;
const int LIGHTTWO = 1;
const int LIGHTTHREE = 2;
const int LIGHTFOUR = 6;
const int LIGHTFIVE1 = 5;
const int LIGHTFIVE2 = 9;
const int SLIGHT1 = 3;
const int SLIGHT2 = 7;
const int SLIGHT3 = 11;
const int fLight1 = 4;
const int fLight2 = 10;
//lights 0-7,9-11


int secLight = 0;
int thirdLight = 0;
int fourthLight = 0;
int fifthLight = 0;

const int POTTIMER = A0;
const int SETBUTTON = 8;
const int X = A5;
const int Y = A4;
const int Z = A3;
int moveThresh = 1000;
int currpos = 0;

//const int PHOTOSENS = A2;
const int ACCEL = 12;
//two things are looking at the accelerometer

//const int MOT1 = 10;

const int numRots = 3;

unsigned long duration = 0;
int lightThresh = 1000;
bool timerGoing = false;
bool failure = false;
unsigned long timeStart = 0;

bool lightsON = false;
int timeForEach = 0;

//4 steps/revolution rn
//const int steps_needed = 50;
//const int STEP_PIN = 11;
//const int DIR_PIN = 10;

//const int fLight = 2;
//const int sLight = 3;

//this creates an object myMotor
//AccelStepper myMotor(1, STEP_PIN, DIR_PIN);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(LIGHTONE,OUTPUT);
  pinMode(LIGHTTWO,OUTPUT);
  pinMode(LIGHTTHREE,OUTPUT);
  pinMode(LIGHTFOUR,OUTPUT);
  pinMode(LIGHTFIVE1,OUTPUT);
  pinMode(LIGHTFIVE2,OUTPUT);
  pinMode(SLIGHT1,OUTPUT);
  pinMode(SLIGHT2,OUTPUT);
  pinMode(SLIGHT3,OUTPUT);
  pinMode(fLight1,OUTPUT);
  pinMode(fLight2,OUTPUT);
  
  pinMode(POTTIMER,INPUT);
  pinMode(SETBUTTON,INPUT_PULLUP);
  pinMode(PHOTOSENS,INPUT_PULLUP);
  pinMode(ACCEL,INPUT);

  //digitalWrite(LIGHTFOUR,HIGH);
  //digitalWrite(SLIGHT1,HIGH);
  //digitalWrite(SLIGHT3,HIGH);
  //pinMode(MOT1,OUTPUT);

  //pinMode(fLight,OUTPUT);
  //pinMode(sLight,OUTPUT);

  //myMotor.setAcceleration(500);
}

int failed() {
  Serial.println(analogRead(PHOTOSENS));
  Serial.println(analogRead(ACCEL));
  Serial.println("FAILED");
  timerGoing = false;
  
  digitalWrite(fLight1,HIGH);
  digitalWrite(fLight2,HIGH);
  delay(500);
  digitalWrite(LIGHTFIVE1,LOW);
  digitalWrite(LIGHTFIVE2,LOW);
  delay(500);
  digitalWrite(LIGHTFOUR,LOW);
  delay(500);
  digitalWrite(LIGHTTHREE,LOW);
  delay(500);
  digitalWrite(LIGHTTWO,LOW);
  delay(500);
  digitalWrite(LIGHTONE,LOW);
  delay(500);
  digitalWrite(fLight1,LOW);
  digitalWrite(fLight2,LOW);
}

int success() {
  Serial.println("SUCCEEDED");
  timerGoing = false;
  for(int a = 0; a < 5; a++) {
    if(lightsON == false) {
      digitalWrite(SLIGHT1,HIGH);
      digitalWrite(SLIGHT2,HIGH);
      digitalWrite(SLIGHT3,HIGH);
      digitalWrite(LIGHTONE,HIGH);
      digitalWrite(LIGHTTWO,HIGH);
      digitalWrite(LIGHTTHREE,HIGH);
      digitalWrite(LIGHTFOUR,HIGH);
      digitalWrite(LIGHTFIVE1,HIGH);
      digitalWrite(LIGHTFIVE2,HIGH);

      lightsON = true;
    }
    else {
      digitalWrite(SLIGHT1,LOW);
      digitalWrite(SLIGHT2,LOW);
      digitalWrite(SLIGHT3,LOW);
      lightsON = false;
    }
    delay(1000);
  }
  if(lightsON == true) {
    digitalWrite(SLIGHT1,LOW);
    digitalWrite(SLIGHT2,LOW);
    digitalWrite(SLIGHT3,LOW);
  }
  //delay(3000);
  //failed();
}

//0-1023
void loop() {
  // put your main code here, to run repeatedly:
  
  //Serial.println(digitalRead(SLIGHT2));

  if(digitalRead(SETBUTTON) == LOW && timerGoing == false) {
    timeStart = millis();
    //changing duration for testing purposes; turn back to 3 * analogRead after this
    duration = ((analogRead(POTTIMER))/3.0)*1000;
    //myMotor.moveTo(steps_needed);
    int xpos = analogRead(X);
    int ypos = analogRead(Y);
    int zpos = analogRead(Z);
    currpos = (xpos+ypos+zpos)/3;
    moveThresh = currpos + 10;
    Serial.print("potentiometer reading: ");
    Serial.println(analogRead(POTTIMER));
    Serial.print("duration (in seconds) is ");
    Serial.println(duration/1000);
    Serial.print("X position: ");
    Serial.println(analogRead(X));
    Serial.print("Y position: ");
    Serial.println(analogRead(Y));    
    Serial.print("Z position: ");
    Serial.println(analogRead(Z));
    Serial.print("average position: ");
    Serial.println((xpos+ypos+zpos)/3);
    timeForEach = (duration)/5;
    //myMotor.setSpeed((4*numRots)/(duration/1000));
    digitalWrite(LIGHTONE,HIGH);
    secLight = timeForEach;
    thirdLight = timeForEach * 2;
    fourthLight = timeForEach * 3;
    fifthLight = timeForEach * 4;
    
    Serial.print("light sensor: ");
    Serial.println(analogRead(PHOTOSENS));
    timerGoing = true;
    //find the range for potentiometer, then change output into range 0-1hour
    
  }

  
  if(timerGoing == true && (analogRead(PHOTOSENS) < lightThresh) && millis() < (timeStart+duration)) {
    Serial.print("photo ");
    Serial.println(analogRead(PHOTOSENS));
    Serial.print("accel ");
    Serial.println(analogRead(ACCEL) - moveThresh);
    Serial.println(analogRead(PHOTOSENS) < lightThresh || analogRead(ACCEL) > moveThresh);
    //failed();
    timerGoing = false;
  }
  if(timerGoing == true && millis() >= (timeStart+duration)) {
    success();
    timerGoing = false;
  }
    if(timerGoing == true && digitalRead(LIGHTTWO) == LOW && millis() >= (timeStart + secLight)) {
    digitalWrite(LIGHTTWO,HIGH);
  }
  if(timerGoing == true && digitalRead(LIGHTTHREE) == LOW && millis() >= (timeStart + thirdLight)) {
    digitalWrite(LIGHTTHREE,HIGH);
  }
  if(timerGoing == true && digitalRead(LIGHTFOUR) == LOW && millis() >= (timeStart + fourthLight)) {
    digitalWrite(LIGHTFOUR,HIGH);
  }
  if(timerGoing == true && (digitalRead(LIGHTFIVE1) == LOW || digitalRead(LIGHTFIVE2) == LOW) && millis() >= (timeStart + fifthLight)) {
    digitalWrite(LIGHTFIVE1,HIGH);
    digitalWrite(LIGHTFIVE2,HIGH);
  }

}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/productivity-tree/feed/ 0
Interactive Memory Box https://courses.ideate.cmu.edu/60-223/f2018/work/interactive-memory-box/ https://courses.ideate.cmu.edu/60-223/f2018/work/interactive-memory-box/#respond Thu, 25 Oct 2018 18:20:43 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4293 Interactive Memory Box is a tool relying on neuroscientific findings used to strengthen the engraving of long term memories right before sleep.

 

 

This project is a concept work which draws upon neuroscientific findings regarding the lasting  effects of memory books on progressive memory loss. It works by systematically reminding you of certain memories by physically printing them on paper right before going to sleep, which causes a strengthening of neural pathways. This is thought to improve memory and protect it from potential neural damage.

 

 

 

 

 

 

 

Process

I started by working with the thermal printer, and getting it to print the content I wanted in a specific format. This meant creating a long and thorough string, my memories. Over the course of a week, I documented past memories which had been pivotal in my life in one way or another, and hardcoded the list of 100+ memories as a string. One of the things I struggled with in the programming section was getting the text to print upside down, so that it would appear right side up while coming out of the box. Unfortunately after many hours of troubleshooting I found that arduino had discontinued that command and it couldn’t be achieved without hacking into the printer.

 

First successful trials with the Adafruit thermal printer

 

One of the main qualms I have with physical computing is often the lack of craft which goes into the physical part of the work. I felt that a piece which relies so heavily on humanity,  tactility and poetry could not be 3D printed or laser cut. I therefore opted to make a hardwood box and spent a significant part of the project time in the woodshop. I purchased some nice Pennsylvania maple a bit outside of town and started the making process.

 

Rockler hardwood section

 

Preparing the maple

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Grooves and miter joints

 

The hardest part of this project was probably the execution of somewhat dangerous cuts on the tablesaw and bandsaw. Measurements and cuts needed to be precise and there was no room for mess ups in this short time frame. The box only fit together after 4 or so hours of fine tuning.

 

 

 

 

 

 

Fine tuning of the miter joints and grooves

 

 

 

 

 

 

Fitting of the hardwood box

 

I finally drilled in holes for the power wires and the side button, assembled the box, added brass hinges, did the sanding and finished the box with tung oil.

 

Finishing of the box and adding the hinges

 

Discussion

During my critique, Claire made a really nice point which made me wish I had thought of it first. She mentioned that the button on the side of the box, although discretely located, did not really respect the object’s physical language. She suggested I used a trigger which upholds the magical aspect of the box, such as an IR sensor. Another very valuable critique I got, was that the receipt printer seemed too removed from the concept. How could I make that interaction more special? Maybe I could build my own plotter, which would ‘hand’ write the notes. Finally, Joey mentioned that a more intuitive UI for the adding of memories to the string should be included, every time my laptop is opened for instance.

I am satisfied with the way this project turned out, as it is relevant to the big picture of my work and has giving me an excuse to  exceed my fabrication qualifications. The concept is strong and loosely based on actual scientific evidence, which I find meaningful when making  something “useful.” I did run into some issues however, such as the arduino’s storage space for my very VERY long string of memories. The genuino uno seemed to only be able to contain, 5 or 6 long sentences, which adds many complications if this project were to actually be used.

Through this project I have gained significant knowledge in the consideration of form and intent, as well as practical skills to execute these theories correctly. I found that mixing the physical and the digital gracefully is a really daunting task, and one that I might have only partially succeeded at. If I were to recreate this project, I would add more magic to the interaction, by replacing the button with an IR sensor. This would be more in line with the product language and would give it more of its own presence. Additionally, my minimal experience in the woodshop made the building process a much slower and tedious one, which would not be the case if I were to attempt to create something out of wood again.

 

Schematic 

 

 

/* Project 02 : Interactive Memory Box
 * By Chloe Desaulles, andrew ID: cdesaull 
 * Made with the Adafruit Thermal Printer Library for Arduino
 * 
 * This code tells a thermal printer to print a memory at random
 * from a string every time the button is pressed.
 * The button is meant to be pressed each night before bed, i.E.
 * before long term memory encoding, which is meant to help with
 * slowing down memory loss processes as well as with memory 
 * recall.
*/


//---------------PRINTER NONSENSE--------------------


#include "Adafruit_Thermal.h"
#include "adalogo.h"
#include "adaqrcode.h"

// Here's the new syntax when using SoftwareSerial (e.g. Arduino Uno) ----
// If using hardware serial instead, comment out or remove these lines:

#include "SoftwareSerial.h"
#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor
// Then see setup() function regarding serial & printer begin() calls.

//--------------------- CONTENT NONSENSE -------------------

int seed;

String myStrings[] {"This is memory 1", "This is memory 2", "This is memory 3",
  "This is memory 4", "This is memory 5", "This is memory 6", 
  "This is memory 7", "This is memory 8"
};



int BUTTONPIN1 = 2;


void setup() {

  //----------------- PRINTER SETUP ----------------

  // This line is for compatibility with the Adafruit IotP project pack,
  // which uses pin 7 as a spare grounding point.  You only need this if
  // wired up the same way (w/3-pin header into pins 5/6/7):
  pinMode(7, OUTPUT); digitalWrite(7, LOW);


  //mySerial.begin(19200);  // Initialize SoftwareSerial - I added it later
  //Serial1.begin(19200); // Use this instead if using hardware serial
  printer.begin();        // Init printer (same regardless of serial type)


  //------------------- LIGHTS -----------------------

  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);

  //------------------- CONTENT SETUP ----------------------

  seed = analogRead(A0); // so long as A0 isn't actually plugged into something
  randomSeed(seed);

  pinMode(BUTTONPIN1, INPUT_PULLUP);
  mySerial.begin(19200);
  Serial.begin(19200);

}

void loop() {

  //----------------- !!!! PRINTING !!!! -------------------

  int buttonVal1;
  buttonVal1 = digitalRead(BUTTONPIN1);

  // If button one is pressed, print a memory at random from array 1
  if (buttonVal1 == LOW) {

    
  //printer.upsideDownOn(); //Tried to print upside down, but isn't supported anymore


    /*digitalWrite(11, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);
    delay(2000);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    delay(1000);*/

    printer.setLineHeight(100);
    //Set text right justification (accepts 'L', 'C', 'R')
    printer.justify('R');
    printer.println(F("12:24, 25 October 2018"));
    printer.setLineHeight(50);

    printer.justify('L');
    //printer.println(F("Kind of memory or whatever"));
    //printer.println(F(myStrings[random(0,6)]));

    String printedMaterial = myStrings[random(0,7)];
    
    printer.println(printedMaterial);
    Serial.println(printedMaterial);

    printer.sleep();      // Tell printer to sleep
    delay(3000L);         // Sleep for 3 seconds
    printer.wake();       // MUST wake() before printing again, even if reset
    printer.setDefault(); // Restore printer to defaults
  }
}

 

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/interactive-memory-box/feed/ 0
Surprise: Startle Box! https://courses.ideate.cmu.edu/60-223/f2018/work/surprise-startle-box/ https://courses.ideate.cmu.edu/60-223/f2018/work/surprise-startle-box/#respond Tue, 25 Sep 2018 18:08:32 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=4060 Megan Roche & Joey Santillo

The Startle Box is a wooden box with a button on the top face of the box. The box features a button on the top, which when attempted to press, triggers a distance sensor, which in turns opens the lid of the box. The lid of the box opens, revealing a note from within the box, saying “Hi!”.

 

This project was our first time creating a piece of physical hardware that responded to code, and first tangible result of working with an Arduino. The circuitry is fairly simple as is the concept and the box itself, but it took a lot of effort from us to try and understand how to get the hardware and software to work together. One roadblock that took awhile for us to figure out was how to make the servo motor be able to open the lid of the box. After some researching and playing around, we found that using a popsicle to prop it open worked fairly well. We also used laser printing for the first time, and had to get extensive help with that.

If we had more time with this project, we would probably try to figure out how to make the hinge less obvious, and maybe try to incorporate sound in the final product- we were playing around with having a song play when the lid opened. We could also program the button to do something if someone pressed it, instead of being a dummy. Additionally, we would have like to play around with multiple ultrasonic rangers OR cultivating a better solution for hiding the current ultrasonic ranger.

 

Box, with servo only, pre-hole drilling.

The top of the box, after drilling holes. Initially we thought the drill would create holes large enough for the ultrasonic ranger and button, but we had to spend awhile making the holes bigger.

This is the soldering of the bread board we put into the box.

Final Product Gif!

 

Finished product;

The Startle Box!

The Startle Box, after being attempted to be touched, diagonal angle.

The Startle Box, after being attempted to be touched, front view.

The wiring within the Startle Box.

 

// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

/* This code will create a box that will "surprise" its user when it opens up
    as the user gets their hand close.

    It senses that the user is getting close by using an ultrasonic ranger, and
    moves the box up by using a servo motor.
*/

#include <NewPing.h>
#include<Servo.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
Servo June;
const int JUNEPIN = 7;

void setup() {
  June.attach(JUNEPIN);
  pinMode(13, OUTPUT);
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  int handDistance = rangeCheck();
  Serial.print("Ping: ");
  Serial.print(handDistance); // Send ping, get distance in cm and print result (0 = outside set distance range)
  Serial.println("cm");
  if (handDistance <= 30 && handDistance != 0) { // If hand is close
    June.write(20);                               // Close box
    delay(2000);
    June.write(0);
  }
  else {
    June.write(170);
    delay(100);
  }
}


int rangeCheck() {
  delay(50);                     // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  int distance = sonar.ping_cm();
  if (sonar.ping_cm() < 20) {
    digitalWrite(13, HIGH);
  }
  else {
    digitalWrite(13, LOW);
  }
  return distance;
}
]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/surprise-startle-box/feed/ 0
Surprise: A Nessie Surprise https://courses.ideate.cmu.edu/60-223/f2018/work/surprise-a-nessie-surprise/ https://courses.ideate.cmu.edu/60-223/f2018/work/surprise-a-nessie-surprise/#respond Mon, 24 Sep 2018 22:18:08 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=3948 Project Description

The white box has white waves inside and a boat, looking like the boat is in a lake or ocean. When the boat moves forward. When the boat inches forward, strange things happen. If you move the boat halfway down the slider, Nessie’s head pops up and she stares at you, blinking her eyes and waiting for you to make the next move. If you move all the way to the end, Nessie will dive underwater and reappear above your boat, ready to attack. If you move back, she returns to where she came from, happy that the intruders are gone. If you only move a little bit forward, Nessie will call for backup and try to intimidate you into leaving her alone. I guess you can say Nessie’s a bit cranky today but how would you feel if a stranger came into your bedroom and started causing a ruckus?

Progress Photos

Early idea sketches of what we wanted to do, back when the objective was to reverse a switch to its default state.

Attaching the heads onto the servos after the they’ve been screwed onto the servo mounts designed to keep them in place while in the box.

Testing Nessie after the servos and boat were glued to the box.  During this stage, we realized rotating her head enough to push the boat back would rip the Servo from the ground of the box so we adjusted the plan for her react to the boat location. Hidden state on the first image, attack state on the second image.

Super-gluing the rest of the waves to finish Nessie’s home.

Schematic

Nessie Schematic

Code

/*
 * 
 * 60-223 Project 1 Code 
 * by Rolando Garcia III (rolandog) and Lexi Yan (yany1)
 * 
 * Date: 9/14/18
 * 
 */
 #include<Servo.h>

#define SLIDER A0
#define BODYEYE 4
#define HEADEYE 5
#define BODYSERVO 10
#define HEADSERVO 11

Servo bodyServo;
Servo neckServo;

int previousDistanceFromWater;
int timeAnimationBegan = 0;
int animationDelay = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  bodyServo.attach(BODYSERVO);
  neckServo.attach(HEADSERVO);
  pinMode(BODYEYE, OUTPUT);
  pinMode(HEADEYE, OUTPUT);
  pinMode(SLIDER, INPUT);

  bodyServo.write(0);
  neckServo.write(0);
  delay(500);

}

void loop() {

  //Record the current time
  int now = millis();

  //Check how close the boat is to the water
  int distanceFromWater = analogRead(SLIDER);

  //Check if the previous animation has completed
  if( (now - timeAnimationBegan) > animationDelay || (previousDistanceFromWater <  distanceFromWater) ){

    //Reset the timer if we are beginning a new animation
    timeAnimationBegan = now;
    
    //If the boat is closest to the water
    if(distanceFromWater < 100){

      //Delay
      animationDelay = 1000;
  
      //Move the body all the way around & blink eye on body
      bodyServo.write(180);
      digitalWrite(BODYEYE, HIGH);
      delay(500);
      
      //Move the head most of the way around & blink eye on head
      neckServo.write(90);
      digitalWrite(BODYEYE, LOW);
      digitalWrite(HEADEYE, HIGH);
      delay(500);

      //Blink the eye a couple of times
      animationDelay += 700;
      digitalWrite(HEADEYE, LOW);
      delay(500);
      digitalWrite(HEADEYE, HIGH);
      delay(200);
  
    } else if(distanceFromWater < 500) {

      //Delay
      animationDelay = 2100;
    
      //Move the body very small amount, make sure the head doesn't appear
      neckServo.write(0);
      delay(100);
      bodyServo.write(90);
      delay(500);

      //Blink the eye and hold there for a bit
      digitalWrite(BODYEYE,HIGH);
      delay(250);
      digitalWrite(BODYEYE,LOW);
      delay(250);
      digitalWrite(BODYEYE,HIGH);
      delay(250);
      digitalWrite(BODYEYE,LOW);
      delay(250);
      
    } else if(distanceFromWater < 750) {
      
      //Delay
        animationDelay = 3000;
      
      //Move the body small amount + blink eye on body
      bodyServo.write(90);
      digitalWrite(BODYEYE, HIGH);
      delay(500);

      //Move the body back
      bodyServo.write(0);
      delay(1000);

      //Move the head up + turn on eye on head + turn off eye on body
      neckServo.write(90);
      digitalWrite(BODYEYE, LOW);
      digitalWrite(HEADEYE, HIGH);
      delay(500);

      //Move the body back
      neckServo.write(0);
      delay(1000);
      digitalWrite(HEADEYE, LOW);

    //Reset head and body when boat returns back to start
    }  else {

      neckServo.write(0);
      digitalWrite(BODYEYE, LOW);
      digitalWrite(HEADEYE, LOW);
      delay(250);
  
      bodyServo.write(0);
      delay(250);
      animationDelay = 500;
    }

    //Record the last distance from the water read
    previousDistanceFromWater = distanceFromWater;
    
  }

}

 


Final Images

Overall photo for proportion and scale

 

Detail photo of the boat

 

Detail photo of Nessie Creeping

 

Action photos of Nessie Attacking

 

Discussion

This project was not difficult in a technical sense, but relatively difficult in terms of usability. Lexi wanted to keep the project once it was done, so it had to be designed to be a rugged as possible. We had to use external battery power for the Arduino and our servo motors, which required soldering a battery pack into our circuit. Two different voltage sources meant that we had to tie all of our grounding together. This was the source of our biggest headache. We believed that grounding to the servos’ power source was enough, but it caused strange behavior in our sliding potentiometer and servos. When we finally tied the Arduino’s ground in, the problem was solved, but not after about 45 minutes of annoyance.  We also discovered while testing that it wouldn’t be possible for Nessie to push the boat back to the origin as we originally planned without causing damage and had to adjust our expectations/goals as a result, The easy part of the assignment was constructing our enclosure, since both of us had laser-cutting experience. We also had access to some interesting scrap materials, which gave our project a unique visual flair.

Ultimately, we learned the virtue of patience. Neither of us had very consistent schedules, so our work sessions had to be very qualitative. As mentioned above, hardware debugging also caused some problems that could have been fixed with some more patience in making a schematic. In the future, we would have changed this project by making it have a bit more unpredictability, through the use of more user-responsive animations for Nessie, or more sophisticated animation triggers.

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/surprise-a-nessie-surprise/feed/ 0
LED Bao Bao Bag https://courses.ideate.cmu.edu/60-223/f2018/work/led-bao-bao-bag/ https://courses.ideate.cmu.edu/60-223/f2018/work/led-bao-bao-bag/#respond Thu, 30 Aug 2018 00:46:10 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=3825 Sorry, but you do not have permission to view this content. ]]> Sorry, but you do not have permission to view this content. ]]> https://courses.ideate.cmu.edu/60-223/f2018/work/led-bao-bao-bag/feed/ 0 Secret Knock Detecting Lock https://courses.ideate.cmu.edu/60-223/f2018/work/secret-knock-detecting-lock/ https://courses.ideate.cmu.edu/60-223/f2018/work/secret-knock-detecting-lock/#respond Wed, 29 Aug 2018 22:51:34 +0000 https://courses.ideate.cmu.edu/60-223/f2018/work/?p=3817 Project Title: Secret Knock Detecting Door Lock

Project creator: Steve Hoefer

Short description: If the user does the correct knock, the door unlocks. You can reset the knock sequence as well, and use the new lock to unlock the door as well.

Response: This seems pretty cool because it takes something that I wouldn’t think would be interactable- door knocks- and makes it so. Knocking to unlock a door would not be a good way to keep what you’re locking secure however, due to the fact that others around you could hear your knock as well.

A solution to that would be to not have it operate as a lock- maybe make a game where the arduino plays a knocking rhythm that the player has to repeat, and the rhythm gradually gets longer and longer as the player gets the knocking rhythms right.

]]>
https://courses.ideate.cmu.edu/60-223/f2018/work/secret-knock-detecting-lock/feed/ 0