Making Things Interactive

March 10, 2008

Lightchaser v5 [part 2]

Filed under: 7: Mid-Term Project,Gaku Sato — ponkotsu @ 8:02 pm

Schematic:
lightchaser-schematic.pdf

Pics:
lightchaser1.jpg
Top (left to right): 9V battery pack, 6V battery pack, Tamiya Twin-Motor Gearbox
Center: H-bridge circuitry
Bottom: Arduino, photoresistor circuitry
lightchaser2.jpg

BB Gun:
  The lightchaser was initially designed with a range weapon to be fired when it reached the target, but since the main goal is to chase the target, it was left out of the final code.
  For optional implementation, the construction of a solenoid-actuated rapid-fire BB gun is photographed below.  The wiring schematic is included in the pdf attached above.  The code would have been simply to ON/OFF the transistor input (drawn as digital 12 pin output) intermittently.  The current code includes a “display I/O variables every second” portion at the bottom, so this can be modified to send a HIGH output every 1/10 second (–> 600rpm) or something around there.

bbgun.jpg

Lightchaser v5

Filed under: 7: Mid-Term Project,Gaku Sato — ponkotsu @ 3:32 pm

Description:
  This is a motorized light-chasing trike with the left and right motors having independent motor controls for the ability to turn/rotate in place.  It takes inputs from three light sensors on its left, right, and back sides.
  The front left/right sensors are the main inputs used to control the motors.  There are two main control algorithms:

1. ABSOLUTE
   This takes sensor inputs and compares them individually to a constant threshold to get the desired motor output.  For instance, if the left sensor detects low levels of light, the right motor should run at a low speed, and vice versa.  So if the right sensor detects high levels, it would run the left motor at high speed, allowing the trike to steer towards the light.  If they are both low, the trike would drive straight forward but slowly, so as to not wildly run after slight differences in ambient light, etc.  Also, there are MIN/MAX thresholds set so that the trike will stop running when the sensors read above MAX (sensors/trike is close enough to light source) or when they read below MIN (light source too far away or nonexistant).

2. RELATIVE
   This takes sensor inputs and compares them to each other.  For instance if the front inputs vary greatly, this means that the trike is not facing the light source.  For example, if the left input reads 700 and the right input reads 500, both of which are above the specified MIN threshold, the initial ABSOLUTE algorithm would tell the right motor to run HIGH and the left motor to run LOW.  However, since the difference is 200 (quite large), this means that the light source is hitting the sensors from the left side of the trike, so in fact, the left motor should not run at all and allow the trike to pivot without moving forwards (i.e. away from the light).  Also, while the sensor inputs have been calibrated by a coefficient to read on matching light scales, they will still have variations, especially with noise.  Relative input parsing can account for some of this and eliminate twitch motions by allowing the motors to run at the same speed if the inputs are only slightly different.

  The algorithm was the most challenging part.  Below is the motion logic from L/R sensor inputs to L/R motor outputs.  The MIN/MAX input conditions are the absolute thresholds mentioned above, and the L/H conditions are LOW<—>HIGH analog controls.

Input  Output
L      R      L      R
min min   0      0
min L       L      0
min H      H      0
min max  H     0
L     min   0      L
L     L       L      L
L     H       H     L
L     max  H      0
H    min    0     H
H     L       L      H
H     H      H      H
H     max  L      0
max min  0       H
max L      0       H
max H      0      L
max max 0      0

  The rear sensor is used to turn the trike around if it is facing the wrong way.  If the input here is significantly higher (difference threshold specified) than the front inputs, it rotates the trike towards around by almost 180degrees in the direction of the higher front input.  So if the left is slightly higher than the right when the light hits the back of the trike, this probably means that the light source is slightly more to the right, so when it turns around, it doesn’t do a full 180; it rotates slightly less to face more towards what is probably the location of the light source.

Pictures:
  Here is my current setup.  I’m working on making it fully operational, but it’s difficult to fit all the parts onto the chassis for remote operation.  So far the I/O works perfectly under various ambient conditions and light sources.  Once I get all the parts onto the chassis, it should just be a matter of tweaking the constant coefficients and thresholds in the code.
  [I’m having trouble with the camera so I will have this up soon!]

Code:

int LightL = 2;   // input analog pin – photoresistor [left]
int LightR = 3;   // input analog pin – photoresistor [right]
int LightB = 4;   // input analog pin – photoresistor [back]
int MotorL1 = 6;  // output digital pin – motor [left] – direction 1
int MotorL2 = 5;  // output digital pin – motor [left] – direction 2
int MotorL = 9;  // output analog pin – motor [left] – speed
int MotorR1 = 8;  // output digital pin – motor [right] – direction 1
int MotorR2 = 7;  // output digital pin – motor [right] – direction 2
int MotorR = 10;  // output analog pin – motor [right] – speed

int Lin;  // input – photoresistor [left]
int Rin;  // input – photoresistor [right] * coefficient
int Bin;  // input – photoresistor [back] * coefficient

long Lout;  // output – motor [left]
long Rout;  // output – motor [right]

int LightMin = 450;    // light input MIN for motion
int LightMax = 800;    // light input MAX for motion

int SpeedLow = 70;    // motor output LOW (MIN for motion)
int SpeedHigh = 255;  // motor output HIGH

int RotateDiff = 100;  // light input different threshold to rotate
int RotateTime = 1500; // motor ON time (ms) to rotate <180deg int msecond = 0; void setup() {   Serial.begin(9600);   pinMode(LightL, INPUT);   pinMode(LightR, INPUT);   pinMode(LightB, INPUT);   pinMode(MotorL, OUTPUT);   pinMode(MotorL1, OUTPUT);   pinMode(MotorL2, OUTPUT);   pinMode(MotorR, OUTPUT);   pinMode(MotorR1, OUTPUT);   pinMode(MotorR2, OUTPUT);   analogWrite(MotorL, 0);   digitalWrite(MotorL1, HIGH);  // forward: HIGH   digitalWrite(MotorL2, LOW);   // forward: LOW   analogWrite(MotorR, 0);   digitalWrite(MotorR1, HIGH);  // forward: HIGH   digitalWrite(MotorR2, LOW);   // forward: LOW   Lin = analogRead(LightL);   Rin = analogRead(LightR) *1.1;   if(max(Lin,Rin)>LightMin)
  {LightMin = max(Lin, Rin);}  // calibrate light input MIN
}

void loop()
{
  Lin = analogRead(LightL);
  Rin = analogRead(LightR) *1.1;
  Bin = analogRead(LightB) *1.0;
  Lout = 0;
  Rout = 0;

  if(Bin>Lin+RotateDiff && Bin>Rin+RotateDiff)
  {  // rotate when light sensed from behind > front + constant
    if(Lin>Rin)
    {  // rotate left
      digitalWrite(MotorL1, LOW);
      digitalWrite(MotorL2, HIGH);
    }
    else
    {  // rotate right
      digitalWrite(MotorR1, LOW);
      digitalWrite(MotorR2, HIGH);
    }
    int ms = millis();
    while(millis() < ms+RotateTime)     {       analogWrite(MotorR, SpeedLow);       analogWrite(MotorL, SpeedLow);     }     digitalWrite(MotorL1, HIGH);     digitalWrite(MotorL2, LOW);     digitalWrite(MotorR1, HIGH);     digitalWrite(MotorR2, LOW);     analogWrite(MotorL, 0);     analogWrite(MotorR, 0);   }   if(LinLightMax) {Lout=255;}
    else if(Rin>LightMin)
    {  // Lout = (SpeedHigh-SpeedLow)*(Lin-LightMin)/(LightMax – LightMin)+SpeedLow
      Lout = SpeedHigh-SpeedLow;
      Lout *= Lin-LightMin;
      Lout /= LightMax – LightMin;
      Lout += SpeedLow;
    }
  }
  if(Lin>LightMax)
  {
    Lout=0;
    if(Rin>LightMin && RinLightMax) {Rout=255;}
    else if(Lin>LightMin)
    {
      Rout = SpeedHigh-SpeedLow;
      Rout *= Rin-LightMin;
      Rout /= LightMax – LightMin;
      Rout += SpeedLow;
    }
  }
  if(Rin>LightMax)
  {
    Rout=0;
    if(Lin>LightMin && LinLightMin && LinLightMin && RinRin+200) {Lout=0;}
  if(Rin>Lin+200) {Rout=0;}
  if(abs(Lin-Rin)<50) {Rout=Lout;}   analogWrite(MotorL, Lout);   analogWrite(MotorR, Rout);   msecond = millis()/1000;   if(millis()-msecond*1000 == 0)  // display every second   {     Serial.print("L:i");     Serial.print(Lin);     Serial.print("-o");     Serial.print(Lout);     Serial.print("   R:i");     Serial.print(Rin);     Serial.print("-o");     Serial.print(Rout);     Serial.print("   B:");     Serial.println(Bin);    } }[/sourcecode] Parts List:
3x photoresistors (preferably all same model)
3x 1Kohm resistors (for photoresistor circuit)
1x 22uF capacitor (for H-bridges)
1x 9V battery pack (for Arduino)
1x 6V battery pack (for motors)
2x quad half H-bridges (for motor control)
1x Tamiya Twin-Motor Gearbox (or 2x DC motors & gearboxes + 1x chassis)
1x breadboard (currently on 2 separate in pic, but need to condense)
?x 22awg hookup wires

References:
  http://itp.nyu.edu/physcomp/Labs/DCMotorControl

Midterm Project: Fireflies in a Jar

Filed under: 7: Mid-Term Project,Assignments,Gee Kim — gskim @ 2:00 am

Fireflies in a Jar is attaching tool for children who can’t sleep in the dark. This tool is going to help the child learn to adjust their pupils in the dark, and eventually get used to the darkenss of the room. Hopefully this will take away their fear of the dark.

_______________________

Here is how I set up the wiring from the arduino to the bread board to the jar:

img_0573.jpg

And here is the circuit diagram:

circuit3.jpg

As you can see from the image above, there is a master/mercury switch that is attached to the jar. There are also three LEDs that correspond to three different switches.

How will it work? Each firefly will have an LED attached to it. The fireflies will sit on its own on/off switch. Removing the firefly from the switch will let us know which firefly is being put into the jar and need to be on once the jar is closed. The jar will also has a mercury switch, attached to the lid, that will tell us when the jar is closed. Once a firefly is placed into the jar, and the jar is closed, the program for that firefly will run as long as the jar is closed. If the jar opens and closes, with the same firefly in the jar, the program of that firefly will restart. This works with all the fireflies.

(for more info on this project, read “Midterm Proposal: Fireflies in a Jar”)

_______________________

Parts List: Arduino, 3 LEDs (white), 3 on/off switch, mercury switch, jar/box with lid, circuit wire, wiring tape

_______________________

Here are the links to the video demonstration of how it works:

int switchPin0 = 7;    // connect switch 0 to pin 0
int switchPin1 = 2;    // connect switch 1 to pin 1
int switchPin2 = 3;    // connect switch 2 to pin 2
int switchPin3 = 4;    // connect switch 3 to pin 3
int ledPin1 = 9;       // connect led 1 to pin 9
int ledPin2 = 10;      // connect led 2 to pin 10
int ledPin3 = 11;      // connect led 3 to pin 11
int brightness = 0;    //

void setup ()
{
  pinMode (switchPin0, INPUT);  // set switch 0 as digital input
  pinMode (switchPin1, INPUT);  // set switch 1 as digital input
  pinMode (switchPin2, INPUT);  // set switch 2 as digital input
  pinMode (switchPin3, INPUT);  // set switch 3 as digital input
  pinMode (ledPin1, OUTPUT);    // set led 1 as analog output
  pinMode (ledPin2, OUTPUT);    // set led 2 as analog output
  pinMode (ledPin3, OUTPUT);    // set led 3 as analog output
  //Serial.begin(9600);
}

void loop ()
{
 //Serial.println(digitalRead(switchPin0));
 if (digitalRead (switchPin0) == LOW){         // when switch 0 is low
    if(digitalRead (switchPin1) == HIGH){      // and when switch 1 is high
      { for (brightness = 0; brightness < 255; brightness ++)
         { analogWrite (ledPin1, brightness);  // make LED get bright
           delay (5);                          // delay for 0.5 seconds
         }
      }
      { for (brightness = 255; brightness > 0; brightness --)
         { analogWrite (ledPin1, brightness);  // then make LED dim
          delay (5);                           // delay for 0.5 seconds
         }
      }
   }
    if (digitalRead (switchPin2) == HIGH){     // and when switch 2 is high
      { for (brightness = 0; brightness < 255; brightness ++)
         { analogWrite (ledPin2, brightness);  // make LED get bright
           delay (5);                          // delay for 0.5 seconds
         }
      }
      { for (brightness = 255; brightness > 0; brightness --)
         { analogWrite (ledPin2, brightness);  // then make LED dim
          delay (5);                           // delay for 0.5 seconds
         }
      }
    }
   if (digitalRead (switchPin3) == HIGH){      // and when switch 3 is high
      { for (brightness = 0; brightness < 255; brightness ++)
         { analogWrite (ledPin3, brightness);  // make LED get bright
           delay (5);                          // delay for 0.5 seconds
         }
      }
      { for (brightness = 255; brightness > 0; brightness --)
         { analogWrite (ledPin3, brightness);  // then make LED dim
          delay (5);                           // delay for 0.5 seconds
         }
      }
   }
}
}

March 9, 2008

Midterm: Visual LED Sound Meter

Filed under: 7: Mid-Term Project,Jesse Chorng — Jesse @ 10:37 pm

As you recall from my midterm proposal, the goal of my project was to add functionality to an existing SURG grant. I wanted to focus on three things that would make Boomboxes (see here to refresh your memory) more conducive to social interaction. By utilizing the Arduino, I wanted to add visual, audio, and communication to the mp3 space so that it could be more than just a set of speakers and really encourage social activities. The most successful part of my midterm was the completion of a visual representation of the music. Looking back, it was much easier than I had made it out to be. But in order to do this, it required that I learn a lot about integrated circuits, particularly the LM3915 dot/bar display driver and the LM741 op amp chips. I had planed to use the LM741 op amp to boost the line in audio signal but found out later that it wasn’t really necessary (after hours of trying to wire it all out)  There are various schematics available online about how to use the LM3915 to drive 10 LEDs to act as a 30 db volume meter.

I ended up using one different from the schematic I originally drew for the proposal seen below.

For the audio input, I was trying to get PodGizmo’s iPod breakout board to function using other people’s work on getting functionality through the iPod dock connector. The pinout is exceptionally useful and allowed me to see what each of the 30 connectors in the iPod dock does. However, there is limited work still underway to try and figure out how exactly the iPod dock connector functions and a lot of it still remains a mystery.  I was unable to grab audio from the iPod dock connector for an unknown reason and had to use a 1/8″ stereo headphone cable instead. I suspect that pin 21 in the iPod dock has something to do with setting the iPod in the proper mode. When not in proper state, the iPod continued to output music only thru the headphone jack and not the dock connector. I will continue to work with it and update this post as soon as I get a better understanding of the iPod Accessory Protocol. 

Here is a short video of my meter in action: 

The Arduino code I used was very very basic because working with ICs became my main focus. On the Arduino side all I wanted it to do was detect when music was being played and at what level. Since the music outputs a 0 – 1.5V signal, all I did was read that and print it out on the display.

/* iPod Analog Read*/

int ipodPin = 2;       // sets analog input pin from iPod audio out
int val = 0;            // variable to store the value coming from audio out

void setup(){
     Serial.begin (9600);
}

void loop(){
     val = analogRead(ipodPin); 
     Serial.print(' The iPod input is: ');
     Serial.print(val);
     Serial.println( V);
} 

NoseTouch Sensor

Filed under: 7: Mid-Term Project,Joshua Smith — jssmith44 @ 8:29 pm

For this project I created a system that follows an individual when in the camera’s field of vision, and detects when the user touches his/her nose. Video is displayed below:The project consists of a Processing application (processing.org), an Arduino application (arduino.cc), and a hardware component.  The computer vision component is processed in the Processing application and the user’s physical location and state (nose touch or no touch) is passed to the Arduino application which drives the hardware.   The following Processing code uses the OpenCV framwork (http://www.intel.com/technology/computing/opencv/) and the Face Detect Library for Processing by Jaegon Lee (http://tokage.cafe24.com/facedetect/)  

import FaceDetect.*;
import processing.serial.*;  

FaceDetect fd;
Serial port;

int viewingAngle = 75;  //Camera's Viewing Angle
int MAX = 4;            // Max number of faces detected at once (for game)
int sPosition = 90;     //servo starting position

int[] x = new int[MAX];
int[] y = new int[MAX];
int[] r = new int[MAX];
int[][] Faces = new int[MAX][3];

void setup(){

  size(640,480);
  fd = new FaceDetect();
  fd.start(width,height, 10);
  println(fd.version()); 
  
 
  noStroke();
  println(Serial.list()); // List COM-ports

  //select second com-port from the list
  port = new Serial(this, Serial.list()[0], 19200); 
}

void draw(){
  background(0);

  Faces = fd.detect();
  int count = Faces.length;
  
   
  if (count>0) {
    for (int i = 0;i<count;i++) {
      x&#91;i&#93; = Faces&#91;i&#93;&#91;0&#93;;
      y&#91;i&#93; = Faces&#91;i&#93;&#91;1&#93;;
      r&#91;i&#93; = Faces&#91;i&#93;&#91;2&#93; * 2;
 println(i+1 + ": " + x&#91;i&#93;+", "+y&#91;i&#93; + ", " + r&#91;i&#93;);
 

  int divider = (width)/viewingAngle;  
  int sPosition= x&#91;i&#93;/divider;  //Calculate servo postion from Face X Coordinate
  sPosition = sPosition - (sPosition%1);
  
 
  

  //Output the servo position ( from 0 to ViewingAngle)
  port.write("s"+sPosition); 

    }
  
  }

    
  int&#91;&#93; img = fd.image();
  loadPixels();
  arraycopy(img,pixels);
  updatePixels();

 if (count == 0)  //identifies nose touch (no faces recognized)
    {port.write("w"); 
   delay(250); }

  strokeWeight(2);
  stroke(255,200,0);
  noFill();
  for(int i =0;i<count;i++) {
    ellipse(x&#91;i&#93;,y&#91;i&#93;,r&#91;i&#93;,r&#91;i&#93;);
  }
  
 
}

public void stop(){
  fd.stop();
  super.stop();
}

&#91;/sourcecode&#93;

  <span style="font-family:Verdana;font-size:13px;line-height:18px;white-space:pre-wrap;" class="Apple-style-span">The Arduino code to communicate with the processing code and drive the servo motor and LED eyeball: (note this code requires installation of the Arduino "Servo" library)</span>  


#include 
Servo servo1; 
int ledPin = 13;

void setup() {
  servo1.attach(14);
  servo1.setMaximumPulse(2500);
  Serial.begin(19200);
  Serial.print("Ready");
}
void loop() {
  static int v = 0;
  if ( Serial.available()) {
    char ch = Serial.read();
    switch(ch) {
      case '0'...'9':
        v = v * 10 + ch - '0';
        break;
      case 's':
        servo1.write(v);
        v = 0;
        break;
        
      case 'w':
      blink();
      v = 0;
      
      
    }
  } 

 Servo::refresh();
}

void blink(){
  digitalWrite(ledPin, HIGH);   // sets the LED on
      delay(100);                  // waits for .1 second
      digitalWrite(ledPin, LOW);    // sets the LED off
      delay(100);                  // waits for .1 second
    }

(the include file should be “Servo.H”, but I cant get it to show up in the sourecode editor)

Finally, the hardware component consisted of just an aluminum rod, rubber eyeball, red LED, and a servo motor. The Servo motor was connected directly to the Arduino board in the following manner: Orange: 5V; Black: Ground; Yellow: Analog Input 0;
The Led was connected to Ground and Digital Pin 13.  

March 8, 2008

The Big Black Bag

Filed under: 7: Mid-Term Project,Tiffany Yang — tyang1 @ 5:42 pm

The Big Black Bag has two functions: (1) when the zipper is unzipped, lights inside the bag light up; (2) when my cellphone rings, the bag vibrates.  If I am not holding the bag, a LED on the bag will light up.  If I am holding the bag, the LED will not light up since I cannot see it anyway. 

Zipper

For the zipper portion of the interactive bag, I did not use any code for it.  It is a physical switch that connects when the bag is unzipped.  I sewed conductive thread at the ends so when the zipper reaches the ends, it is connecting the circuit and the LEDs in the bag light up. 

Conductive thread sewn in

Zipper connecting circuit

LEDs lit in bag

Cellphone Ring

For the cellphone ring portion, I sewed the lilypad vibe board in the shoulder straps as well as a push button so my arduino knows when I am holding the bag or not.  If I am holding the bag, the push button is pushed (input = LOW).  If I am not holding the bag, the push button is released (input = HIGH).   To know whether my celllphone is ringing or not, I wanted to use an RF sensor but there is none out there that is off-the-shelf.  I tried buying this key chain for $0.89 which is suppose to detect cellphone rings and then light up but it did not work.  So instead, I used a photosensor to detect incoming cellphone calls since all cellphones light up when it receives a call. 

Testing Code:

Testing photosensor response to cellphone LCD:

Shoulder Strap

shoulder strap embedded w/ vibe board & pushbutton:

Image of front of bag

Inside pockets of Bag

Photosensor

Battery Holder

 A Working Bag…

has not been produced yet.  I used conductive thread and solid wire to make the connections which is something I learned NOT to do.  After putting the bag together nothing worked.  It seems like the connections are not solid and the programming is a bit faulty.  I decided to test the circuit and code again by going back to the breadboard.  Individually the push button and vibe board circuit and the photosensor work but together they do not work.  I don’t understand why.  If someone can figure that one out please let me know.  In the meantime I am going code it a different way.

What not to do

Circuit Schemtic

Breadboard Circuit

Code for the breadboard circuit:

 /* This sketch describes how the BIG BLACK BAG behaves when there is an incoming cellphone call.  
 When there is an incoming call the shoulder strap will vibrate and: 
 (a) if the bag is being carried, the LED on an accessory pin will NOT light up
 (b) if the bag is NOT being carried, the LED on an accessory pin will light up
 */


int photoPin = 0;                               // sets photosensor to analog 5
int val = 0;                                    // variable for storing the value coming from photosensor
int light = 0;                                  // variable for reading photosensor 
float sens = .85;                               // defines sensitivity of the photocells (0 - 1.0 "always on")


int vibe = 5;                                   // sets vibe board to digital 1
int triLed = 7;                                 // sets LEDs to digital 7
int buttonPin = 13;                              // sets input pin for pushbutton to digital 13
int buttonVal = 0;                              // variable for reading the button status


void setup() {  


  pinMode(photoPin, INPUT);                     // declare photosensor near zipper as input
  light = analogRead(photoPin);                 // reads initial state of photosensor i.e. retrieves ambient light value
  pinMode(vibe, OUTPUT);                        // declare vibe as an output
  pinMode(triLed, OUTPUT);                      // declare the triPin as an output 
  pinMode(buttonPin, INPUT);                    // declare photosensor as input 
}  


void loop() {  


  val = analogRead(photoPin);                           // reads resistance from photosensor i.e light value 
  buttonVal = digitalRead(buttonPin);                   // read input value from button


    if ((val > light*sens) && buttonVal == HIGH) {      // If amount of light is larger than threshold & button is released (HIGH)
    digitalWrite(vibe, HIGH);                           // turn vibe board on ...
    digitalWrite(triLed, HIGH);                         // turn LED on.
  }


  if ((val > light*sens) && buttonVal == LOW) {         // If amount of light is exceeds threshold & button is pressed (LOW)
    digitalWrite(vibe, HIGH);                           // turn vibe board on ... 
    digitalWrite(triLed, LOW);                          // turn LED on.
  }
  else {                                                // when there is no incoming call (inactive state)...
    digitalWrite(triLed, LOW);                          // LEDs are off 
    digitalWrite(vibe, LOW);                            // vibe board is off


  }
}

Midterm: Single Pixel of a 3-D Mirror

Filed under: 7: Mid-Term Project,Paul Castellana — paulcastellana @ 4:21 pm

I was trying to insert some images I posted to Flickr, but it’s not working. Here’s the link to flickr though.

I found the formula for linearizing the voltage output from the IR Range sensor here.

Video:

int servoPin = 2;     // Control pin for servo motor
int minPulse = 500;   // Minimum servo position
int maxPulse = 2500;  // Maximum servo position
int pulse = 0;        // Amount to pulse the servo

long lastPulse = 0;    // the time in milliseconds of the last pulse
int refreshTime = 20; // the time needed in between pulses

int val;             // outgoing ADC value
int distance = 0;    // linearized distance value

void setup()
{
pinMode(servoPin, OUTPUT);  // Set servo pin as an output pin
pulse = minPulse;           // Set the motor position value to the minimum
beginSerial(9600);
}

void loop()
{
val = analogRead(0); // read analog input:
distance = (2914 / (val + 5)) - 1;   // linearize sensor readings
printString("distance = "); // print out distance readings for reference
printInteger(distance);
printString("  ");

delay(10);

pulse = distance*125;    // convert distance to a value between minPulse
// and maxPulse

if (minPulse &lt; pulse = refreshTime) {  // pulse the servo again if rhe refresh time (20 ms) have passed:
digitalWrite(servoPin, HIGH);   // Turn the motor on
delayMicroseconds(pulse);       // Length of the pulse sets the motor position
digitalWrite(servoPin, LOW);    // Turn the motor off
lastPulse = millis();           // save the time of the last pulse
} else {
pulse = minPulse;
}
}
}

March 7, 2008

Automated Window Opener

Filed under: 7: Mid-Term Project,Brian Kish — bkish @ 1:54 am

http://www.youtube.com/watch?v=C_Zslar5zkg

My goal is to created a completely automated wall system that helps to control the temperature in the space. In the long term, I hope also have automated louvers that will be controlled by both light and temperature. Unfortunately, I burned out one of my servos and got a couple from the robotics club. However, I guess they modified them by taking out the potentiometer and restricting pins so the they can continually rotate. It took me a long time to try and get them to move back and forth before I figured out that you couldn’t!

For this portion, I am using a linear actuator to open and close a window (the window is still imaginary). It is controlled by the indoor and outdoor temperature. It three conditions and 2 states:

if ((tempOUT >= 65) && (tempIN >=65)) THEN WINDOW OPEN!! (RED LED)

else if ((tempOUT < 65) && (tempIN < 80)) THEN WINDOW CLOSE!! (BLUE LED)

else if ((tempOUT < 65) && (tempIN >=80)) THEN WINDOW OPEN!! (RED LED)

I used an ice-pack to change the temperature in the sensors to verify that the system worked. It works.

Circuit Diagram:

Circuit Diagram

All the Components:
Components of Project

THE LM35 TEMPERATURE SENSOR:

LM35 Temperature Sensor

/*
Temp sensor code for automated window opener. The sensor used is an amplified LM35.
*/
int tempoutPin = 0; //input read pin for LM35 is Analog Pin 0
int tempinPin = 1; //input read pin for LM35 is Analog Pin 1
float tempIN = 0; //variable which will be calculated in process
float tempOUT = 0; //variable which will be calculated in process
int redLED=5; //Pin5 = Red LED
int blueLED=7; //Pin7 = Blue LED
int greenLED=6; //Pin6 = Green LED
long val=0; //variable to store the value coming from the sensor
int openWINpin = 3; // H-bridge leg 1 set to open window
int closeWINpin = 4; // H-bridge leg 2 set to close window
int speedPin = 9; // H-bridge enable pin

void setup()
{
pinMode(redLED, OUTPUT); //redLED set to output
pinMode(greenLED, OUTPUT); //greenLED set to output
pinMode(blueLED, OUTPUT); //blueLED set to output
pinMode(openWINpin, OUTPUT); //openWINpin set to output
pinMode(closeWINpin, OUTPUT); //closeWINpin set to output
pinMode(speedPin, OUTPUT); //speedPin set to output
pinMode(tempoutPin, INPUT); //tempoutPin set to input
pinMode(tempinPin, INPUT); //tempinPin set to output
Serial.begin(9600); // Stars Serial Communication
digitalWrite(speedPin, HIGH); // sets speed to on for Actuator
}

void loop () //loop below process
{

Serial.println(“Outdoor Temperature is “); //Print “Outdoor Temperature is” every loop
val = analogRead(tempoutPin); //read the value of sensor
tempOUT = (32+9*val*10/1024); //convert voltage to temperature (farenheit)
Serial.println ((long)tempOUT); //print temperature value on serial screen
Serial.println (“Degrees Farenheit”); //Print “Degrees Farenheit” every loop

Serial.println(“Indoor Temperature is “); //Print “Indoor Temperature is” every loop
val = analogRead(tempinPin); //read the value of sensor
tempIN = (32+9*val*10/1024); //convert voltage to temperature
Serial.println ((long)tempIN); //print temperature value on serial screen
Serial.println (“Degrees Farenheit”); //Print “Degrees Farenheit” every loop

if ((tempOUT >= 65) && (tempIN >=65)) //Check if temp over x degrees C.
{
digitalWrite (redLED, HIGH); //If so… turn LED on
digitalWrite (blueLED, LOW); //and this LED off
digitalWrite (greenLED, LOW); //and this LED off
digitalWrite(openWINpin, HIGH); // set leg 1 of the H-bridge low
digitalWrite(closeWINpin, LOW); // set leg 2 of the H-bridge high

}
else if ((tempOUT < 65) && (tempIN >=80)) //if temperature does not meet above requirement but is between Y and Z… do below
{
digitalWrite (redLED, LOW); //turn LED off
digitalWrite (blueLED, HIGH); //turn LED on
digitalWrite (greenLED, LOW); //turn LED off
digitalWrite(openWINpin, HIGH); // set leg 1 of the H-bridge low
digitalWrite(closeWINpin, LOW); // set leg 2 of the H-bridge high
}
else if ((tempOUT < 65) && (tempIN < 80)) //if temperature does not meet above requirement but is between Y and Z... do below { digitalWrite (redLED, LOW); //turn LED off digitalWrite (blueLED, LOW); //turn LED off digitalWrite (greenLED, HIGH); //turn LED on digitalWrite(openWINpin, LOW); // set leg 1 of the H-bridge low digitalWrite(closeWINpin, HIGH); //set leg 2 of the H-bridge high } delay(5000); //wait for 5 seconds } //End of process, go back to start of loop - ie check temp...[/sourcecode]

March 6, 2008

Midterm – Interactive Indo Board

Filed under: 7: Mid-Term Project,Assignments,Thomas Hendrickson — tphendrickson @ 9:33 pm

For my midterm project I remained with my original idea of adding interactive elements to my indo board. I originally had thought that my additions would reflect how many times the board was tipped, but realized that it is much more challenging (and more of a workout) to focus on keeping the board as flat as possible.

I used 18 LEDs in 9 columns of 2, in three different colors. Each column is controlled by a digital output on the arduino. The outputs are based on the status of two separate rolling ball tilt switches that are attached to the indo board. Each tilt switch reads if the board is tilted a certain amount on either side. If kept completely horizontal, the tilt switches are activated at 30 degrees, so the switches must be altered a little (bent less horizontal) so that it is feasible to keep the board level long enough to light up the LEDs.

The switches each complete a circuit that act as inputs to the arduino, and the LEDs light up (green to yellow to red) based on how long the switches are NOT activated. When the switches are not activated, that implies that the indo board is balanced. Each LED column lights up a second after the last one has lit up. A ‘while’ statement in the code checks that both switches are not activated, a counter increments every half second however long the switches are not activated, and a series of ‘if’ statements light up the LEDs based on the counter value.


int runPin = 13;      //arduino LED light
int ledPin_1 = 12;    //LED pins
int ledPin_2 = 11;
int ledPin_3 = 10;
int ledPin_4 = 9;
int ledPin_5 = 8;
int ledPin_6 = 7;
int ledPin_7 = 6;
int ledPin_8 = 5;
int ledPin_9 = 4;
int switchPin_1 = 2;  //tilt switch inputs
int switchPin_2 = 3;
int switchStatus_1;
int switchStatus_2;
int counter;   

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin_1, OUTPUT);
  pinMode(ledPin_2, OUTPUT);
  pinMode(ledPin_3, OUTPUT);
  pinMode(ledPin_4, OUTPUT);
  pinMode(runPin, OUTPUT);
  pinMode(switchPin_1, INPUT);
  pinMode(switchPin_2, INPUT);

}

void loop()
{
    counter = 0;

    digitalWrite(runPin, LOW);    //everything is turned off at the start of the loop
    digitalWrite(ledPin_1, LOW);
    digitalWrite(ledPin_2, LOW);
    digitalWrite(ledPin_3, LOW);
    digitalWrite(ledPin_4, LOW);
    digitalWrite(ledPin_5, LOW);
    digitalWrite(ledPin_6, LOW);
    digitalWrite(ledPin_7, LOW);
    digitalWrite(ledPin_8, LOW);
    digitalWrite(ledPin_9, LOW);

    switchStatus_1 = digitalRead(switchPin_1);
    switchStatus_2 = digitalRead(switchPin_2);

    while ((switchStatus_1 == LOW) && (switchStatus_2 == LOW))  //both switches are not activated for the LEDs to light up
    {
      digitalWrite(runPin, HIGH);      //checks that the while loop is working

      if (counter > 1)
      {
        digitalWrite(ledPin_1, HIGH);

        if (counter > 2)
        {
          digitalWrite(ledPin_2, HIGH);

          if (counter > 3)
          {
            digitalWrite(ledPin_3, HIGH);

            if (counter > 4)
            {
               digitalWrite(ledPin_4, HIGH);
            }

              if (counter > 5)
              {
               digitalWrite(ledPin_5, HIGH);
              }

                if (counter > 6)
                {
                 digitalWrite(ledPin_6, HIGH);
                }

                  if (counter > 7)
                  {
                   digitalWrite(ledPin_7, HIGH);
                  }

                    if (counter > 8)
                    {
                     digitalWrite(ledPin_8, HIGH);
                    }

                      if (counter > 9)
                      {
                       digitalWrite(ledPin_9, HIGH);
                      }
          }
        }
      }

        counter++;      //the counter increments
        switchStatus_1 = digitalRead(switchPin_1);
        switchStatus_2 = digitalRead(switchPin_2);

        delay(500);    //the while loop is delayed half a second before starting again

    }

}

After the circuits and code are completed, I cut about 4, 8 foot wires to keep the LEDs away from the indo board. The switches were placed on a smaller breadboard and duct taped down to the indo board, making sure the breadboard was level.Materials:

  • 11 1K Ohm resistors
  • 6 green LEDs
  • 6 yellow LEDs
  • 6 red LEDs
  • Jumper wire
  • 2 rolling ball tilt switches
  • Arduino

    MidTerm Project: Ventillated Jacket

    Filed under: 7: Mid-Term Project,Siddartha Butalia — sbutalia @ 9:10 pm

    Step-by-Step of how I reached my end results 

     Step 1. Attaching the thermistors to sense temperature: I began by creating a an input switch, tweaked to give a reasonable range of input voltages for the thermistor. This took a while to get right, as initially I was getting incoherent data. (below is a picture of the setup)


    Step 2. calibrating the thermistors (scaling): The scaling was performed with the assumption that the thermistors gave off a linear voltage-temperature output. With this I plotted 2 points approximately and ran a regression analysis to determine a trend line. This trendline i used to come up with my fahrenheit values. With this I attached a number LED which was wired and coded as shown below. this was done so I could walk around freely with a jacket and understand which temperatures were uncomfortable and comfortable. I found that values over 85 (Fahrenheit) seemed quite uncomfortable. I then decided to leave this as a variable in my code which could be defined whenever.


    Free Image Hosting at www.ImageShack.us

    sourcecode for the hardwiring of the LED (functions)

    void LEDOutput(int tempF){
      if(tempF > 0){
        if(tempF >10){
          if(tempF >20){
            if(tempF >30){
              if(tempF >40){
                if(tempF >50){
                  if(tempF>60){
                    if(tempF>70){
                      if(tempF>80){
                        if(tempF>90){
                          nine();
                        }
                        else{
                        eight();
                      }}
                      else{
                      seven();
                    }}
                    else{
                    six();
                  }}
                  else{
                  five();
                }}
                else{
                four();
              }}
              else{
              three();
            }}
            else{
            two();
          }}
          else{
          one();
        }}
        else{
        zero();
        }}
    }
    
    void nine()
    {
      allclear();
      half();
      digitalWrite(13,HIGH);
      digitalWrite(12,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(6,HIGH);
    }
    
    void eight(){
      allclear();
      half();
      digitalWrite(13,HIGH);
      digitalWrite(12,HIGH);
      digitalWrite(11,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(6,HIGH);
    }
    
    void seven(){
      allclear();
      half();
      digitalWrite(13,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(6,HIGH);
    }
    
    void six(){
      allclear();
      half();
      digitalWrite(13,HIGH);
      digitalWrite(12,HIGH);
      digitalWrite(11,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(7,HIGH);
    }
    
    void five(){
      allclear();
      half();
      digitalWrite(13,HIGH);
      digitalWrite(12,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(9,HIGH);
    }
    
    void four(){
      allclear();
      half();
      digitalWrite(13,HIGH);
      digitalWrite(12,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(7,HIGH);
    }
    
    void three(){
      allclear();
      half();
      digitalWrite(12,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(6,HIGH);
    }
    
    void two(){
      allclear();
      half();
      digitalWrite(12,HIGH);
      digitalWrite(11,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(6,HIGH);
    }
    
    void one(){
      allclear();
      half();
      digitalWrite(7,HIGH);
      digitalWrite(9,HIGH);
    }
    
    void zero()
    {
      allclear();
      half();
      digitalWrite(13,HIGH);
      digitalWrite(11,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(7,HIGH);
      digitalWrite(6,HIGH);
    }
    
    void allclear(){
    for(int i=0; i < 8; i++){
      digitalWrite(6+i,LOW);
      }
    }
    
    void half(){
      if(int(tempF) % 10 > 5)
      {
        digitalWrite(8,HIGH);
      }
    }

    Step 3. experimenting with various ways to actuate fabric with muscle wire: Initially i wanted the vents to open and close as gills, this however was easier said and done. Finally i came upon using this method to actuate the flaps. I use the pushing nature of muscle wire, it is quite strong when enough current is applied to the wire. Understanding this I had to use a transistor which allowed large currents to flow through.

    Step 4. Assembly: the method of creating the jacket was as follows, I cut out the flaps in the two layer jacket. Then i fused the edges together with fabric fuser and an iron, after that I created the “muscles.” I created these by taking each end and crimping them into copper tubes. the other ends of the tubes were attached to outgoing wires. after doing all the attachments, i soldered in the edges for a tighter fit. In order to successfuly insulate the components from both themselves and the fabric, I used heat shrink tubing to encase the joints. all exposed joints where soldered for strength and conductivity as well as shrink tubed to eliminate as much malfunction as possible. the wires and other components were taped onto the inside layer of fabric which proved to be strong enough. The next step was to determine which wires to use etc. I ran the power supplies through the front pockets as to utilize space to the maximum. Below one will find how the whole jacket is wired in a simple system level diagram indicating components, inputs and outputs.

    
    int inputPin[3];      //declares array of analog inputs
    int outputPin = 8;    //declares pin attached to transistor
    float tempF[3];        //declares variable to store temperature values in
    float tempAVG;        //declares variable to store the average temp in
    int threshTemp = 95;  //defines the temperature at which the vents open
    
    void setup() {
      inputPin[0] = 5;              //defining the input pins
      inputPin[1] = 4;
      inputPin[2] = 3;
      pinMode(10, INPUT);          //defining input and output pins
      pinMode(outputPin, OUTPUT);
      pinMode(inputPin[0], INPUT);
      pinMode(inputPin[1], INPUT);
      pinMode(inputPin[2], INPUT);
      pinMode(13, OUTPUT);
    
      Serial.begin(9600);          
    
     }
    
    void loop(){
    
      tempF[0] = (0.236827*analogRead(inputPin[0])-3.962);  //storing the temperatures from all three thermistors
      tempF[1] = (0.236827*analogRead(inputPin[1])-3.962);
      tempF[2] = (0.236827*analogRead(inputPin[2])-3.962);
      tempAVG = (tempF[0]+tempF[1] + tempF[2])/3;          //calculating the avg temp
      Serial.print(int(tempF[0]));                          //output of values for debugging/checking
      Serial.print(int(tempF[1]));
      Serial.println(int(tempF[2]));
      Serial.println(int(int(tempAVG)));
    
      if((int(tempAVG) > threshTemp) || digitalRead(10) > LOW){  //checks whether temp is > than the threshold or if the manual override button has been pushed
        digitalWrite(outputPin,HIGH);
        digitalWrite(13,HIGH);
      }else{
      digitalWrite(outputPin,LOW);
    digitalWrite(13,LOW);
    }
    
    }

    note* after break I will try and post up some directions/hints for working with muscle wire in the context of my project

    Next Page »

    Blog at WordPress.com.