As computing becomes more ubiquitous in our objects, designers need to be more aware of how to design meaningful interactions into electronically enhanced objects. At the University of Washington, a class of junior Interaction Design majors is exploring this question. These pages chronicle their efforts.

Tuesday, May 28, 2013

Randy & Charlie: It's All Coming Together

Wiring all the microphones together to later put into a wearable device. Code works pretty well.


/*
  New code for the microphones. 
  Uses four arrays to keep running averages for each microphone for the last ten seconds
  and sets the average of the ten as the threshold.
  Sound below the threshold will not register in the vibration motors.
*/

// The analogue input pins each microphone is plugged into.
const int electret1 = 0;  
const int electret2 = 1;
const int electret3 = 2;
const int electret4 = 3;

// The analogue output pins each vibration motor.
const int vibration1 = 11;  
const int vibration2 = 10;
const int vibration3 = 9;
const int vibration4 = 6;

// Variable to store the value read from the sensor pins.
int sensorReading1 = 0;     
int sensorReading2 = 0;
int sensorReading3 = 0;
int sensorReading4 = 0;

// The queue of running averages for each microphone to set threshold.
int sensorMax1[10];
int sensorMax2[10];
int sensorMax3[10];
int sensorMax4[10];

// Queue to temporarily store data.
int temp[10];

// The minimum.
int sensorMin = 1023;

// The threshold that needs to be surpassed to register.
int threshold1;
int threshold2;
int threshold3;
int threshold4;

// Keep track of time to take samples every instance.
int time;

// SETUP
void setup() {
  
  // Use the serial port 57600 to read faster than 9600.
  Serial.begin(57600);  

  // Set the vibration motors as output.
  pinMode(vibration1, OUTPUT);
  pinMode(vibration2, OUTPUT);
  pinMode(vibration3, OUTPUT);
  pinMode(vibration4, OUTPUT);
  
  delay(2000);
  
  // Record time it took to get here.
  time = millis();
  
  Serial.print("Time: ");
  Serial.println(time);
  // For ten seconds...
  for (int i = 0; i < 10; i++) {
    // Every 5 seconds, add a microphone reading to each microphone reading queue.
    Serial.print("Passed: ");
    Serial.println(millis() - time);
    
    sensorReading1 = analogRead(electret1);   
    push(sensorMax1, sensorReading1);
    
    sensorReading2 = analogRead(electret2); 
    push(sensorMax2, sensorReading2);
    
    sensorReading3 = analogRead(electret3); 
    push(sensorMax3, sensorReading3);;
    
    sensorReading4 = analogRead(electret4); 
    push(sensorMax4, sensorReading4);
    delay(1000);
  }
  
  Serial.print("Setup sensor1:");
  Serial.println(sizeof(sensorMax1));
  
  Serial.print("Setup sensor2:");
  Serial.println(sizeof(sensorMax2));
  
  Serial.print("Setup sensor3:");
  Serial.println(sizeof(sensorMax3));
  
  Serial.print("Setup sensor4:");
  Serial.println(sizeof(sensorMax4));
  
  // Set the threshold for each microphone as the average of the queue.
  Serial.println("Lets begin.");
  averageMicrophones();
}


// THE LOOP
void loop() {
  // For stability, start out with low on all vibration motors.
  digitalWrite(vibration1, LOW);
  digitalWrite(vibration2, LOW);
  digitalWrite(vibration3, LOW);
  digitalWrite(vibration4, LOW);
  
  // Read the sensor and store it in a variable.
  sensorReading1 = analogRead(electret1);
  sensorReading2 = analogRead(electret2);
  sensorReading3 = analogRead(electret3);
  sensorReading4 = analogRead(electret4); 

  // if the sensor reading is greater than the threshold:
  if (sensorReading1 >= threshold1) {
    Serial.print("Mic1: ");
    Serial.print(sensorReading1-threshold1);
    Serial.print("    ");
    if (sensorReading1-threshold1 > 10) {
        digitalWrite(vibration1, HIGH);
    }
  } else {
    Serial.print("Mic1: 0    ");
  }
  
  if (sensorReading2 >= threshold2) {
    Serial.print("Mic2: ");
    Serial.print(sensorReading2-threshold2);
    Serial.print("    ");
    if (sensorReading2-threshold2 > 10) {
        digitalWrite(vibration2, HIGH);
    }
  } else {
    Serial.print("Mic2: 0    ");
  }
  
  if (sensorReading3 >= threshold3) {
    Serial.print("Mic3: ");
    Serial.print(sensorReading3-threshold3);
    Serial.print("    ");
    if (sensorReading3-threshold3 > 10) {
        digitalWrite(vibration3, HIGH);
    }
  } else {
    Serial.print("Mic3: 0    ");
  }
  
  if (sensorReading4 >= threshold4) {
    Serial.print("Mic4: ");
    Serial.print(sensorReading4-threshold4);
    Serial.print("    ");
    Serial.print("\n");  
    if (sensorReading4-threshold4 > 10) {
        digitalWrite(vibration4, HIGH);
    }
  } else {
    Serial.print("Mic4: 0    ");
    Serial.print("\n");  
  }

  Serial.print("Mic1 Average: ");
  Serial.print(threshold1);
  Serial.print("   ");
  Serial.print("Mic2 Average: ");
  Serial.print(threshold2);
  Serial.print("   ");
  Serial.print("Mic3 Average: ");
  Serial.print(threshold3);
  Serial.print("   ");
  Serial.print("Mic4 Average: ");
  Serial.println(threshold4);
  Serial.print("\n");
  
  // Every second, take a reading and use it to adjust the average.
  if (millis() % 1000 == 0) {
    // Put in new data.
    push(sensorMax1, sensorReading1);
    push(sensorMax2, sensorReading2);
    push(sensorMax3, sensorReading3);
    push(sensorMax4, sensorReading4);
    // Average the data.
    averageMicrophones();
  }
  
  delay(2);  // Better for Processing showing data
}


// Averages all the microphone readings.
void averageMicrophones() {
  
  // Average the recordings of micrphone 1.
  int sum = 0;
  for (int i = 0; i < 10; i++) {
     sum = sum + sensorMax1[i];
  }
  threshold1 = sum / 10;
  
  // Average the recordings of micrphone 2.
  sum = 0;
  for (int i = 0; i < 10; i++) {
     sum = sum + sensorMax2[i];
  }
  threshold2 = sum / 10;
  
  // Average the recordings of micrphone 1.
  sum = 0;
  for (int i = 0; i < 10; i++) {
     sum = sum + sensorMax3[i];
  }
  threshold3 = sum / 10;
  
  // Average the recordings of micrphone 1.
  sum = 0;
  for (int i = 0; i < 10; i++) {
     sum = sum + sensorMax4[i];
  }
  threshold4 = sum / 10;
}

void push(int data[], int sensorReading) {
  // Shift all items one slot.
  for (int i = 9; i > 0; i--) {
    data[i] = data[i-1];
  }
  // Add new data to the beginning.
  data[0] = sensorReading;
}

After discovering that we could buy the microphone with working amp all in one package (https://www.sparkfun.com/products/9964) we bought four and hooked them up. They worked immediately. It was joyous. When the


/* 
 Randy
 Starts and you must wait four seconds for it to read the ambient sound in the environment
 and adjust the threshold accordingly.
 */


// these constants won't change:
const int ledPin = 13;      // led connected to digital pin 13
const int electret1 = 0;  // the amplifier output is connected to analog pin 0
const int electret2 = 1;
const int electret3 = 2;
const int electret4 = 3;

// these variables will change:
int sensorReading1 = 0;      // variable to store the value read from the sensor pin
int sensorReading2 = 0;
int sensorReading3 = 0;
int sensorReading4 = 0;
int sensorMax1 = 0;
int sensorMax2 = 0;
int sensorMax3 = 0;
int sensorMax4 = 0;
int sensorMin = 1023;
int threshold1;
int threshold2;
int threshold3;
int threshold4;

void setup() {
  pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
  Serial.begin(57600);       // use the serial port
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  while (millis() < 3000) {
    delay(1000);
    threshold1 = analogRead(electret1);
    threshold2 = analogRead(electret2);
    threshold3 = analogRead(electret3);
    threshold4 = analogRead(electret4);

    // record the maximum sensor value
    if (threshold1 > sensorMax1) {
      sensorMax1 = threshold1;
    }
    
    if (threshold2 > sensorMax2) {
      sensorMax2 = threshold2;
    }
    
    if (threshold3 > sensorMax3) {
      sensorMax3 = threshold3;
    }
    
    if (threshold4 > sensorMax4) {
      sensorMax4 = threshold4;
    }
  }

  // signal the end of the calibration period
  digitalWrite(13, LOW);
  threshold1 = sensorMax1;
  threshold2 = sensorMax2;
  threshold3 = sensorMax3;
  threshold4 = sensorMax4;
  
  // led pins
  pinMode(3, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop() {
  digitalWrite(3, LOW);
  digitalWrite(6, LOW);
  
  // read the sensor and store it in the variable sensorReading:
  sensorReading1 = analogRead(electret1);   
  sensorReading2 = analogRead(electret2); 
  sensorReading3 = analogRead(electret3); 
  sensorReading4 = analogRead(electret4); 

  // if the sensor reading is greater than the threshold:
  if (sensorReading1 >= threshold1) {
    Serial.print("Mic1: ");
    Serial.print(sensorReading1-threshold1);
    Serial.print("    ");
  } else {
    Serial.print("Mic1: 0    ");
  }
  
  if (sensorReading2 >= threshold2) {
    Serial.print("Mic2: ");
    Serial.print(sensorReading2-threshold2);
    Serial.print("    ");
    if (sensorReading2-threshold2 > 10) {
        digitalWrite(3, HIGH);
    }
  } else {
    Serial.print("Mic2: 0    ");
  }
  
  if (sensorReading3 >= threshold3) {
    Serial.print("Mic3: ");
    Serial.print(sensorReading3-threshold3);
    Serial.print("    ");
    if (sensorReading3-threshold3 > 10) {
        digitalWrite(6, HIGH);
    }
  } else {
    Serial.print("Mic3: 0    ");
  }
  
  if (sensorReading4 >= threshold4) {
    Serial.print("Mic4: ");
    Serial.print(sensorReading4-threshold4);
    Serial.print("    ");
    Serial.print("\n");  
  } else {
    Serial.print("Mic4: 0    ");
    Serial.print("\n");  
  }



  delay(2);  // Better for Processing showing data
}

Monday, May 20, 2013

Randy & Charlie: Meeting Our Audience, Professor Forshay

We met with Lance Forshay, a lecturer in the Deaf Studies department of the University of Washington. We sought to get the opinion of a professional and member of the deaf community. After explaining our idea, we asked him questions regarding cultural sensitivity towards hearing aids, Deafhood, and the practicality of our project.

Saturday, May 18, 2013

Breakthrough With Serial Communication Mason/Nick



It may not look like much but this is the result of quite a few frustrating hours. One the hardware side it is a led sure but what is  more important is what is turning that led on. This light is controlled by a text file, and a very simple one at that THe main problem that we had was getting a serial communication between processing and the Arduino. That has been solved.  The main issue was file conventions for macs

Our next steps will be to apply this to the weather report file we have and code some motors.



Processing code below







import processing.serial.*;

Serial comPort;
int counter=0; // Helps to keep track of values sent.
int numItems=0; //Keep track of the number of values in text file
boolean sendStrings=false; //Turns sending on and off
StringLoader sLoader; //Used to send values to Arduino

void setup(){
 comPort = new Serial(this, Serial.list()[6], 9600);
 background(255,0,0); //Start with a Red background
}

void draw(){
}


void mousePressed() {
 //Toggle between sending values and not sending values
 sendStrings=!sendStrings;

 //If sendStrings is True - then send values to Arduino
 if(sendStrings){
 background(0,255,0); //Change the background to green

 /*When the background is green, transmit
 text file values to the Arduino */
 sLoader=new StringLoader();
 sLoader.start();
 }else{
 background(255,0,0); //Change background to red
 //Reset the counter
 counter=0;
 }
}



/*============================================================*/
/* The StringLoader class imports data from a text file
 on a new Thread and sends each value once every half second */
public class StringLoader extends Thread{

 public StringLoader(){
 //default constructor
 }

 public void run() {
 String textFileLines[]=loadStrings("/Users/Nick/Desktop/srialblink/3.txt");
 String lineItems[]=splitTokens(textFileLines[0], ",");
 numItems=lineItems.length;
 for(int i = counter; i<numItems; i++){
 comPort.write(lineItems[i]);
 delay(500);
 comPort.write("6");
 }
 counter=numItems;
 }
}

Thursday, May 16, 2013

Gavia + Noble // Silly String Experiments

The next step of making our theft detection device a reality involved brainstorming what would be triggered upon the movement of ones personal belongings, in addition to the standard flashing lights and blaring alarm. Many ideas were thrown around – a bag of marbles bursting and flying everywhere (deemed too cumbersome), a smoke bomb detonating (too dangerous), text message being sent to your phone (too difficult and expensive considering the time-frame and student budget). Eventually, we decided to go with an aerosol can that sprays silly string, as it's compact and inexpensive while still delivering the spectacle that we wanted. Additionally, the user could potentially replace the silly string with mace, spray paint, or anything else in an aerosol can if they were looking for a more extreme theft deterrent.
We plan on attaching the wire that depresses the spray nozzle to a servo motor. When triggered by the motion sensor, it will rotate in alternating ten second and three second intervals for about 30 seconds, pulling the connecting wire and producing bursts of silly string. The photos below show the first tinkerings with the can and the wire. We used paper clips kept in place by strips of duct tape folded over to create a non-sticky channel through which they could easily pass, and we carved a divot in the top of the nozzle to keep the paper clip in place. Pulling the bottom of the wire with a small amount of force sprayed the string!




Unfortunately, the process of putting it together involved Gavia spraying a good amount of silly string by mistake (sometimes at Noble and other unsuspecting classmate – sorry guys), and the can is now empty. Our next steps will involve finding a more hi-fidelity way to attach the wire to the nozzle and run it along to the bottom of the can actually attach the wire to the servo motor.






Tuesday, May 14, 2013

MotionSensingCameraTriggeringProjectExtraordinaire

The final area of confusion for the success of our Motion-Sensing-Camera-Triggering Project was our ability to mimic an infrared remote control with an IR LED, our Arduino and Amy's Nikon D5100. The internet was helpful-ish (thanks to http://sebastian.setz.name/arduino/my-libraries/multi-camera-ir-control/ andhttp://www.bigmike.it/ircontrol/download.html). We ended up having the bits and pieces of code in our hands but not knowing what to do with them, or how to solve the errors on the Arduino program. Thankfully, and timely phone call with an electrical engineering uncle (Thank you, Andrew Hood!) helped add the appropriate "int"s and ";"s.

The following code was somewhat anticlimactic in that you can't see anything. The nature of the remote controls, and infrared lights, is that the sequence is fast and invisible to the naked eye. Unfortunately we still need to purchase an IR LED, so we weren't able to perform the ultimate test: can we actually take a picture with this bugger? In the end, we elongated the lengths of the light flashes, and plopped a regular old LED in our hardware, and were rewarded with a happy little flicker. More on wether we can actually take pictures with it later.

The Code:
  unsigned long start = micros();
  while(micros()-start<=time){
  }
}
void high(unsigned int time, int freq, int pinLED){
  int pause = (1000/freq/2)-4;
  unsigned long start = micros();
  while(micros()-start<=time){
    digitalWrite(pinLED,HIGH);
    delayMicroseconds(pause);
    digitalWrite(pinLED,LOW);
    delayMicroseconds(pause);
}
void setup(){
}
void loop(){
  int _freq = 40;
   int _pin = 9;
  high(2000,_freq,_pin);
  wait(27830);
  high(390,_freq,_pin);
  wait(1580);
  high(410,_freq,_pin);
  wait(3580);
  high(400,_freq,_pin);
  delay(5000);
}
void wait(unsigned int time){
  }

Sunday, May 12, 2013

Pairing the Photoresistor to the Analog Sensor // karin & kristina's TOOTH MONSTER :)


For the purpose of dispensing floss by utilizing the actuator, this code triggers the actuator to move 180 degrees when the photoresistor is covered. 


#include <Servo.h>    
    Servo myservo;
    int pos = 5;
    int lightPin = 0;
    
    void setup() {
      // attach the pin 9 to the servo
      myservo.attach(9);
      Serial.begin(9600);
    }
    
    void loop() {
      // read the current voltage at lightPin (0) 
      int lightLevel = analogRead(lightPin); 
      Serial.println(lightLevel);
      
      if (lightLevel <= 500) {// turn to 180
      pos = 60;
      myservo.write(pos);
      }
     
      else {//turn to 0
      pos = 0;
      myservo.write(pos);
     }

Friday, May 10, 2013

Maddz & Candz: Arduino Practice Codes

We used to code from the Arduino Example files and modified it to produce both the brute force and for loop code. Both codes essentially makes the LED blink five times (counting 1, 2, 3, 4, 5), then wait for a while, and begin counting again.

Blink Code (Brute Force)
// Used Pin 13 for the LED
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
 // initialize the digital pin as an output.
 pinMode(led, OUTPUT);     
}


// the loop routine runs over and over again forever:
void loop() {
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(500);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(500);   // wait for a second
 
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(500);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(500);   // wait for a second
 
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(500);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(500);   // wait for a second
 
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(500);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(500);   // wait for a second
 
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(500);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(500);   // wait for a second
 
//waits 1 minute before blinking again
 delay (60000);
}


Blink Code (For Loop)

// Used Pin 13 as LED
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
 // initialize the digital pin as an output.
 pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
 // LED blinks so long as count is less than 5.
 for (int count=0; count<5; count++) {
   digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
   delay(500);               // wait for a second
   digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
   delay(500);   // wait for a second
 }
// Waits for 1 minute before blinking again.
 delay(60000);
}



Button
Using the example from http://www.arduino.cc/en/Tutorial/Button, we were able to get the button system working. Here is the code we used from the website:


// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);      
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);     
}

void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);

 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {     
   // turn LED on:    
   digitalWrite(ledPin, HIGH);  
 }
 else {
   // turn LED off:
   digitalWrite(ledPin, LOW);
 }
}


Below is a video showing the button at work:


Thursday, May 9, 2013

Noble + Gavia // Poster Showing Thief Detection Logic

Pseudocode and Ideation for Arduino Theft Detection Project

This is the poster that we made for class.  It outlines the logic behind our project.  Once the system is setup and armed, if somebody tries to steal the person's possessions, the system reacts to draw attention to itself and delay the thief.

Noble + Gavia // Practice Code and Replacement Parts

Since our parts haven't arrived in the mail yet, we made do with what the Sparkfun Inventor's Kit had.  We used the kit's piezo instead of a larger one, a potentiometer instead of a vibration sensor, a button instead of an infrared remote switch, and base LEDs instead of brighter ones.  I recently bought a larger servo from radioshack for the part where it shoots silly string, but this part of the project was done before then.

I coded the Arduino to arm itself when the button is pressed.  A LED comes on to show that it's armed and if the potentiometer's analog reading reaches a certain value, red LEDs flash on and the piezo makes a buzzing noise.  This code has the basic logic of our system.  The system can be armed or disarmed, and the sensor triggers a reaction once a certain value is detected.



Here's our code:


#define LED_ALARM 13   //Red LEDS on output pin 13
#define LED_ON 12   //Green LED on ouotput pin 12
#define BUTTON 2   //Button switch on input pin 2
#define SENSORPIN 0   //Potentiometer on analog input pin A0
#define BUZZER 11   //Piezo buzzer on output pin 11

int val = 0;   //It's value changes based on whether the button is pressed or not
int old_val = 0;   //Stores the old value of the button so it properly turn on or off
int state = 0;   //State of the button, is it on or off?
int sensorValue;   //Value of the potentiometer

void setup() {                
  pinMode(LED_ALARM, OUTPUT);
  pinMode(LED_ON, OUTPUT);
  pinMode(BUTTON, INPUT);
  pinMode(BUZZER, OUTPUT);
}

void loop() {
   val = digitalRead(BUTTON);   //Sets the value to LOW or HIGH based on the button being pressed or not

   if ((val == HIGH) && (old_val == LOW)){   //Changes the state of the button to on or off
     state = 1 - state;
     delay(10);
   }
   
   old_val = val;   //So we know that we're going from one button state to another when it's pressed
   
   if (state == 1) {   //If the button is pressed the green light comes on and the potentiometer starts to read
     digitalWrite(LED_ON, HIGH);
     sensorValue = analogRead(SENSORPIN);
   } else {
     digitalWrite(LED_ON, LOW);    //If the button isnt pressed then the light is off
   }
   if (sensorValue > 500) {   //If the potentiometer is a certain value, the alarm sounds and the red LEDs flash
      digitalWrite(LED_ALARM, HIGH);
      delay(250);
      digitalWrite(LED_ALARM, LOW);
      delay(250);
      
      buzz(BUZZER, 2500, 500);   //buzz the buzzer on pin 11 at 2500Hz for 500 milliseconds
      delay(1000);
    }
}

void buzz(int targetPin, long frequency, long length) {
  long delayValue = 1000000/frequency/2;     //calculate the delay value between transitions
  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
  //// there are two phases to each cycle
  long numCycles = frequency * length/ 1000;    //calculate the number of cycles for proper timing
  //// multiply frequency, which is really cycles per second, by the number of seconds to 
  //// get the total number of cycles to produce
 for (long i=0; i < numCycles; i++){    //for the calculated length of time...
    digitalWrite(targetPin,HIGH);    //write the buzzer pin high to push out the diaphragm
    delayMicroseconds(delayValue);    //wait for the calculated delay value
    digitalWrite(targetPin,LOW);    //write the buzzer pin low to pull back the diaphragm
    delayMicroseconds(delayValue);    //wait again for the calculated delay value
  }
}

Wednesday, May 8, 2013

Randy & Charlie: Microphone

We got our electret microphone to work going off of this schematic: http://www.dtic.upf.edu/~jlozano/interfaces/microphone.html. However it barely picks up any sound at all. We think it's a problem with the op-amp.


/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
 
 This example code is in the public domain.
 */

int vibrationPin = 9;
long strength, data;
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  pinMode(vibrationPin, OUTPUT); 
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  float sensorValue = (float)analogRead(A0);
  // print out the value you read:
  
  strength = (long)voltageToHertz(sensorValue);
  data = (long)voltageToByte(sensorValue);
  Serial.println(sensorValue);
  tone(vibrationPin, strength, 100);
//  String value = String(sensorValue);
//  Serial.write(value);
  delay(2);        // delay in between reads for stability
}

float voltageToHertz(long volts) {
  long value = (float)(180 * ((float)volts / (float)1024));
  if (value > 20) {
    return value;
  } else {
    return 0;
  }
}

float voltageToByte(long volts) {
  long value = (float)(255 * ((float)volts / (float)1024));
  if (value > 20) {
    return value;
  } else {
    return 0;
  }
} 

Randy & Charlie: Vibration Motor with Proximity Sensor

This code is a modified code from a HC-SR04 Tutorial (http://treehouseprojects.ca/ultrasonictutorial/). Using the HC-SR04 sensor to sense the proximity of an object and then activate a vibration motor that vibrates at a rate proportionate to the proximity of the object.

/*

Randy Huynh

This code is a modified code from a HC-SR04 Tutorial 
(http://treehouseprojects.ca/ultrasonictutorial/).
Using the HC-SR04 sensor to sense the proximity of an 
object and then activate a vibration motor that vibrates 
at a rate proportionate to the proximity of the object.

*/
 
//pin which triggers ultrasonic sound
const int pingPin = 13;
 
//pin which delivers time to receive echo using pulseIn()
int inPin = 12;
 
//range in cm which is considered safe to enter, anything
//coming within less than 5 cm triggers red LED
int safeZone = 50;
 
//vibration pin.
int vibrationPin = 9;
 
void setup() {
  // initialize serial communication
  Serial.begin(9600);
}
 
void loop()
{
  //raw duration in milliseconds, cm is the
  //converted amount into a distance
  long duration, cm, strength;
 
  //initializing the pin states
  pinMode(pingPin, OUTPUT);
  pinMode(vibrationPin, OUTPUT); 
 
  //sending the signal, starting with LOW for a clean signal
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
 
  //setting up the input pin, and receiving the duration in
  //microseconds for the sound to bounce off the object infront
  pinMode(inPin, INPUT);
  duration = pulseIn(inPin, HIGH);
 
  // convert the time into a distance
  cm = microsecondsToCentimeters(duration);
 
  //printing the current readings to ther serial display
//  Serial.print(cm);
//  Serial.print("cm");
//  Serial.println();

  strength = (long)centimetersToHertz(cm);
  // Serial.println(strength);
  // Serial.write(strength);
  
  Serial.write((long)centimetersToByte(cm));
  tone(vibrationPin, strength, 100);
  delay(100);
}
 
long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

float centimetersToByte(long centimeters) {
  if (centimeters < safeZone && centimeters != 0) {
    return (float)(255 - (255 * ((float)centimeters / (float)50)));
  } else {
    return 0;
  }
} 

float centimetersToHertz(long centimeters) {
  if (centimeters < safeZone && centimeters != 0) {
    return (float)(180 - (180 * ((float)centimeters / (float)safeZone)));
  } else {
    return 0;
  }
} 


Tuesday, May 7, 2013

Houston, We Have Detection

There's something truly exciting about testing ideas and discovering they actually work. Shoot, it's also exciting to test your idea and find out it doesn't work. The beauty lies in the act of trying. We've been muttering about using a PIR Motion Sensor (by Parallax) for a few weeks now, so when we actually took the little bugger out of its packaging, it was our moment of truth.
Being that we are two individuals with little experience (none, actually) when it comes to coding, Arduinos and sensors, this is an extremely intimidating realm to enter into. Thankfully, once again, the internet is our friend, this time in the form of Dave Giancaspro's article on Wired.com. He was creating some kind of motion-triggered, heart-attack-giving halloween decoration. I bet he would be disappointed that we are using his code to take pretty pictures of Hummingbirds.

Anyway.

Thanks to him we had this code:

int motion_1 = 2;int light_1 = 13;void setup(){ pinMode (motion_1,INPUT); pinMode (light_1, OUTPUT);}void loop (){ digitalWrite (light_1,LOW); delay(1000); //this delay is to let the sensor settle down before taking a reading int sensor_1 = digitalRead(motion_1);\ if (sensor_1 == HIGH){ digitalWrite(light_1,HIGH); delay(500); digitalWrite(light_1,LOW); delay(500); }}

Next, plug in a few wires, the sensor, and an LED, and BLAMMO! We now have an LED light that flashes when the motion sensor has been tripped.


=


For our next step, we intend to replace the flashing LED with a remote that trips the camera. Here's to majestic animal imagery in our future!

Steps As Multi-Dimensional Arrays – Mallika Simone, Sarah Churng

Recap:

We are the drunk walking narc team. OurDuino detects drunk walking and does something about it.

Goal:


  • _COLLECT PRESSURE VALUES from stepping, every 30 seconds every 3 minutes
  • _ANALYZE PATTERNS for degradation in pacing over time
  • _RESPOND with a flag if patterns are determined to be "drunk" (More on what this change will be later)

Strategy:



  • _4 FORCE PRESSURE SENSORS, 2 per foot (1 in heel, 1 in ball)
    We will be using the combined value, in order to accommodate for the variance in distributed weight across the foot.
  • _4 ANALOG PINS on Arduino, with conversions of the analog values to scalar values
  • "Phases[0-N]" MULTI-DIMENSIONAL ARRAYS ", one created every 3 minutes.
    Each contains the following information:
    • "LeftInputs" ARRAY, with 60 cells, 1 every 500 ms. for over 30 seconds
    • "RightInputs" ARRAYwith 60 cells, 1 every 500 ms. for over 30 seconds
  • "Weigh" FUNCTION that analyzes each Phase array and returns a statistical weight for the pacing rate
  • "Compare" FUNCTION that compares the statistical weight from sober (early) phases to current phase

Algorithm Psuedocode:


LeftArray;[]
RightArray[];
PhaseArray[][];

void fillFeetArrays {
   read in left sensor values;
   store values in LeftArray;

   read in right sensor values;
   store values in RightArray;
}

void fillPhaseArray {
   every 3 minutes:
      while ( power != OFF ) {
         int n = 0;

         for (halfsecs = 0; halfsecs < 60; halfsecs++) {
             fillFeetArrays;
             store LeftArray and RightArray in PhaseArray[n][];      
         }
         n++;
      }
}

psuedocode for filling the multidimensional arrays


Code:


/*
  AUTHORS: sarah churng; mallika simone
  SUMMARY: Measures the force exerted in walking.
  Reads in analog input via Force Pressure Sensors (FPS) from pins 
  A0 and A1, and maps the results to 2 respective ranges from 0 to 255.
  
  Stores these results to arrays LeftValues and RightValues,
  inside multidimensional arrays LeftFoot and RightFoot, respectively.
  
  CIRCUITS:
1* FPS connected to analog pin A0.
   Center pin of the potentiometer goes to the analog pin.
   side pins of the potentiometer go to +5V and ground
 * LED connected from digital pin 10 to ground

2* FPS connected to analog pin A1.
   Center pin of the potentiometer goes to the analog pin.
   side pins of the potentiometer go to +5V and ground
 * LED connected from digital pin 9 to ground

   USE AND POTENTIAL for the data collected:
 * PACING: as a function of the inputs over time
 * BALANCE: as a comparison between the two inputs' pressure resistances
  
 */


// ANALOG DATA: Left Foot
const int analogInPin1 = A0;                            // Force Pressure Sensor at A0
const int analogOutPin1 = 10;                           // LED at variable pin 10
int sensorValue1 = 0;                                   // value from variable sensor
int outputValue1 = 0;                                   // value from output to analog out

// ANALOG DATA: Right Foot
const int analogInPin2 = A1;                            // Force Pressure Sensor at A1
const int analogOutPin2 = 9;                            // LED at variable pin 9
int sensorValue2 = 0;                                   // value from variable sensor
int outputValue2 = 0;                                   // value from output to analog out

const int StepsPerPass = 10;
int stepCount = 0;

// ARRAYS
int LeftValues[StepsPerPass];
int RightValues[StepsPerPass];


// INITIALIZE serial communications at 9600 bps
void setup(){ 
  Serial.begin(9600);
}

// FILL ARRAYS with pressure values detected
void fillArrays(){
  
  for (stepCount = 0; stepCount < StepsPerPass; stepCount++){
    // READ: analog values
    sensorValue1 = analogRead(analogInPin1);              // Read in input from left foot
    outputValue1 = map(sensorValue1, 0, 1023, 0, 255);    // Map to range of analog 0 - 255
    analogWrite(analogOutPin1, outputValue1);             // Change the analog out value
    LeftValues[stepCount] = outputValue1;
      
    sensorValue2 = analogRead(analogInPin2);              // Read in input from right foot
    outputValue2 = map(sensorValue2, 0, 1023, 0, 255);    // Map to range of analog 0 - 255
    analogWrite(analogOutPin2, outputValue2);             // Change the analog out value
    RightValues[stepCount] = outputValue2;
    
    delay(500);
  }
}

void loop(){
  
  fillArrays();
  
  for (int n = 0; n < StepsPerPass; n++) {
    Serial.print("Left Foot = " );
    Serial.print(LeftValues[n]);
    Serial.print("\t\tRight Foot = " );
    Serial.println(RightValues[n]);
  }

  // Wait 3 minutes to create a new phase cycle
  delay(3000);
  
}

Next steps and things to think about:

  • What's the response type?
    For the actual response to drunk walking, we are considering various social media and technology tools, to signal to friends of the wearer
  • How are people wearing this prototype?
    The arduino and circuits probably have to be housed in a giant belt buckle, with wires  running down each pant leg to the sensors connected in the shoe insoles.