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, June 11, 2013

Trash Talk | IR beam testing | Sam + Willie

Willie and I have decided on building a recycling can that can detect "shots" (when the paper you throw at it goes into the can), and provides audio feedback with sound effects from NBA Jams. The first step was to think about how we could detect these things going in. Infrared sensing made the most sense. We bought sensor and emitter pairs from Radio Shack which worked really well. We were also really surprised with how much stuff Radio Shack had to cater to the Arduino tinkerer. Definitely an under-rated resource.

Anyways, we got the IR pairs to detect and set off a normal LED. SWEET! Basically, we watched the Serial monitor for values, and then manually set a threshold.

Here's a photo:
















Here's our code for the simple IR detections:

//
// IR_Sensors_2.ino -- play the current value of an IR Sensor on a 5v speaker, adjusting
// from a base pitch of C3 (220hz)
//
// Dervied from http://arduino.cc/forum/index.php?topic=94690.0
//
// Note: Detector is clear, emitter is dark
//
//

// Constants

const int IR_IN_ANALOG_PIN = 2; // analog input pin -- Detector (clear)
const int IR_OUTPUT_PIN = 2; // digital output pin -- Emitter/dark)
const int LEDsignalPin          = 13;   // signal pin setup

const String INTRO = "Starting...";

// IR level values

int irLevel = 0; // variable to store the value read from input pin
int minIRLevel = 1000;
int maxIRLevel = 0;
int lastIRLevel = 0;
int irTone = 0;

bool firstLoop = true;
bool debug = true; // Set false to turn off Serial tracing
bool newRange = false;


//
// setup
//
void setup() {

// Set up the output LED

pinMode( IR_OUTPUT_PIN, OUTPUT );
digitalWrite( IR_OUTPUT_PIN, HIGH ); // Turns on the emitter
        pinMode( LEDsignalPin, OUTPUT );    //sets signal LED to off

// Turn on tracing

if ( debug ) {
Serial.begin( 9600 );
}
}


//
// loop -- show the current input to the detector.  Sense and highlight changes to the observed
// min, max and avg values of the signal
//
void loop() {

// read value of analog input
     
irLevel = analogRead( IR_IN_ANALOG_PIN );

// Play its value

//irTone = NOTE_C3 + irLevel;
//tone( SPKR_PIN, irTone );

// print header & initial irLevel

if ( firstLoop == true ) {
if ( debug ) {
Serial.println( INTRO );
Serial.print( "initial irLevel = " );
Serial.println( irLevel );
}
firstLoop = false;
}

// Check if irLevel changed

newRange = false;
if ( irLevel < 60) {
                digitalWrite (LEDsignalPin, HIGH);
                delay(50);
                digitalWrite (LEDsignalPin, LOW);
        }

        if ( irLevel != lastIRLevel ) {

// Trace the new IR level

if ( debug ) {

// Print the level

Serial.print( "irLevel = " );
Serial.print( irLevel );

// Print increase/decrease

if ( irLevel > lastIRLevel ) {
Serial.print( " +++" );
} else {
Serial.print( " ---" );
}
}

// Save new minimum

if ( irLevel < minIRLevel ) {
if ( debug ) {
Serial.print( " new MIN" );
}
newRange = true;
minIRLevel = irLevel;
}

// Save new maximum

if ( irLevel > maxIRLevel ) {
if ( debug ) {
Serial.print( " new MAX" );
}
newRange = true;
maxIRLevel = irLevel;
}

// Finish the trace line

if ( debug ) {
Serial.println( "" );
}

// Print new range

if ( newRange ) {
if ( debug ) {
Serial.print( "Range: [ " );
Serial.print( minIRLevel );
Serial.print( ", " );
Serial.print( maxIRLevel );
Serial.println( " ]" );
}
}

// Save the irLevel

lastIRLevel = irLevel;

// wait half a second

if ( debug ) {
delay( 5 );
}
}


}


We later added a calibration to the IR setup, so that it would calibrate itself to the surrounding IR levels, and then watch for those to be changed. This means we can turn it on in any situation and it will adjust to the ambient about of IR light. Here's the code for that:

// this is an LED blink sketch with calibration for just one Sensor


const int sensorOne = A0; // analog input pin -- Detector (clear)
const int sensorTwo     = A1;
const int sensorThree   = A2;
const int emitterPin = 2; // digital output pin -- Emitter/dark)
const int signalPin  = 13;   // signal pin setup

// variables:
int sensorValue   = 0;         // the sensor value
int sensorMin     = 1023;        // minimum sensor value
int sensorMax     = 0;           // maximum sensor value


void blink() {
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
}

void setup() {
  // turn on LED to signal the start of the calibration period:
  pinMode(signalPin, OUTPUT);
  digitalWrite(signalPin, HIGH);

  pinMode( emitterPin, OUTPUT );
  digitalWrite( emitterPin, HIGH ); // Turns on the emitter

  // calibrate during the first three seconds
  while (millis() < 3000) {
    sensorValue = analogRead(sensorOne);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }

  // signal the end of the calibration period
  digitalWrite(signalPin, LOW);
  Serial.begin(9600);
}

void loop() {
  // read the sensor:
  sensorValue = analogRead(sensorOne);

  // apply the calibration to the sensor reading
  sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);

  // in case the sensor value is outside the range seen during calibration
  sensorValue = constrain(sensorValue, 0, 255);

  if(sensorValue <= (sensorMax - 8)){
    digitalWrite(13, HIGH);
    delay(300);
    digitalWrite(13, LOW);
  }

  Serial.print("sensor value = ");
  Serial.println(sensorValue);

  delay(5);
}

No comments:

Post a Comment