Introduction to Physical Computing
Week 5, Lab: Serial



In the serial lab we connect a sensor to the arduino, which transmits
data back to the computer via USB, which processing then reads and
processes. For the sensor I used a 3-axis accelerometer, the same which
we will be using for our midterm (I am working with Ramona and Syed).
It was no problem connecting the accelerometer to the breadboard and
reading in values.

Next I attached the arduino and breadboard to a dowel, hoping to get a
wand effect, something easy for people to swing and play with. I
composed the arduino code to monitor the values of the accelerometer,
taking the difference of the three axis' over 100 milliseconds, in 10
millisecond cycles. If the difference exceeded a predefined value, this
was considered movement in that axis and a 1 is sent, otherwise 0 is
sent to the serial port.

The format for sending data is:
XYZ255XYZ255XYZ255
The 255 denotes markers, so processing knows which of the three bytes is
X, Y, and Z respectively. X, Y, and Z are 0 or 1, 0 meaning no
movement, 1 movement in that axis.

Processing then reads these values, and as the want is swung pictures or
taken, or a dialog on screen advances.

ADD PHOTOS

Here is the code used with the accelerometer.


/*
* MidTerm code for Accelerometer based wand
* by Alexander Reeder
* Oct 9, 2007
*/

// THRESH represents the threshold's for change
#define X 0
#define XTHRESH 35
#define Y 1
#define YTHRESH 25
#define Z 2
#define ZTHRESH 35

// for ADC we delay(10)
// CYCLE denotes how many of these cycles
// we wait before comparing differences
#define CYCLE 10

int sensor[3];        // array to hold the sensor values
int lastsensor[3];    // last sensor value
int c = 0;        // counter
int tmp = 0;        // temporary variable for caculations
int diff[3];        // cumulative differences between sensor and
            // lastsensor, refreshed each cycle or on change

void setup() {
    // initialize the serial port:
    Serial.begin(9600);
}

void loop() {
    // read in analog values, of which there are three: X, Y and Z
    for (int i = 0; i < 3; i++) {
        sensor[i] = analogRead(i)/4;
        // if the value is 255, truncate it so we can use 255
        // as a unique value to punctuate the sentence:
        if (sensor[i] == 255) {
            sensor[i] = 254;
        }
        //DEBUGGING
        //Serial.print(sensor[i], BYTE);
        //Serial.print(sensor[i], DEC);
        //Serial.print(" ");
    }
    //DEBUGGING
    //Serial.print(255, BYTE);
    //Serial.println("");
    
    // if we have done one cycle, reset the difference array and counter
    if (c == CYCLE) {
        for (int i = 0; i < 3; i++) {
            diff[i] = 0;
            lastsensor[i] = sensor[i];
        }
        c = 0;
    } else {
        // otherwise, add up the difference between sensor and last sensor
        for (int i = 0; i < 3; i++) {
            tmp = lastsensor[i] - sensor[i];
            // make sure the value is positive
            if (tmp < 0)
                tmp = tmp*-1;
            diff[i] = diff[i] + tmp;
            lastsensor[i] = sensor[i];
            //DEBUGGING
            //Serial.print(diff[i], DEC);
            //Serial.print(" ");
        }
        
        // X-axis change, 1 on change 0 on none
        if (diff[X] > XTHRESH) {
            Serial.print(1, BYTE);
            diff[X] = 0;
        } else
            Serial.print(0, BYTE);
        
        // Y-axis change
        if (diff[Y] > YTHRESH) {
            Serial.print(1, BYTE);
            diff[Y] = 0;
        }
        else
            Serial.print(0, BYTE);
            
        // Z-axis change
        if (diff[Z] > ZTHRESH) {
            Serial.print(1, BYTE);
            diff[Z] = 0;
         }
         else
             Serial.print(0, BYTE);
        
        // end of data string
        Serial.print(255, BYTE);
    }
    c++;
    delay(10);
}



At first, I was unsure about the range of values an accelerometer would
provide. I wrote a little code to measure the range of values.


/*
* Using an accelerometer,
* determine the range of its values over a period of time
* by Alexander Reeder    
* Oct 5, 2007
*/

int sensor[3];        // array to hold the sensor values
int high[3], low[3];    // high and low values
long lastPulse = 0;
int refreshTime = 2000;    // period of monitoring

void setup() {
    // initialize the serial port:
    Serial.begin(9600);

    // setup
    for (int i = 0; i < 3; i++) {
        high[i] = analogRead(i)/4;
        low[i] = high[i];
    }
    delay(10);
}

void loop() {
    for (int i = 0; i < 3; i++) {
        sensor[i] = analogRead(i)/4;
        if (sensor[i] == 255) {
            sensor[i] = 254;
        }
        if (high[i] < sensor[i])
            high[i] = sensor[i];
        if (low[i] > sensor[i])
            low[i] = sensor[i];
        //Serial.print(sensor[i], DEC);
        //Serial.print(sensor[i], BYTE);
        //Serial.print(" ");
    }
    //Serial.print(255, BYTE);
    //Serial.println("");
    delay(10);
    if (millis() - lastPulse >= refreshTime) {
        Serial.println("");
        Serial.print(high[0], DEC);
        Serial.print(" ");
        Serial.print(high[1], DEC);
        Serial.print(" ");
        Serial.print(high[2], DEC);
        Serial.println("");
        Serial.print(low[0], DEC);
        Serial.print(" ");
        Serial.print(low[1], DEC);
        Serial.print(" ");
        Serial.println(low[2], DEC);
        Serial.println("Set down, resetting!");
        delay(2000);
        for (int i = 0; i < 3; i++) {
            high[i] = analogRead(i)/4;
            low[i] = high[i];
        }
        delay(10);
        lastPulse = millis();
        Serial.println("Move it!");
    }
}






-- Thu, 11 Oct 2007 10:28 -0400

Copyright © 1996-2008 Alexander Reeder
All rights reserved unless otherwise noted