Monday, November 16, 2009

Prototype 5 - 2 Sensors, 2 Outputs

Improvements this week:
  • 2 separate foil capacitance sensors
  • 2 variable-brightness LED responses
  • Better processing logic to normalize the currently sensed value
The setup:


Each sensor is connected to 2 pins on the Arduino board. Our CapSense functions set one pin high and measure the delay between the signal and sensor pin.

Rather than blinking (based on a 'delay' variable which actually slowed our sensing too!) the LEDs now respond in brightness (voltage, power) by using the PWM pins on the Arduino. This allows for a continuous loop without a delay.

We also found this DigitalSmooth library on the Arduino website, which we modified to get the maximum value of the most recent group of samples. That gives us much more flexibility in the metallic 'sensor' - we can normalize the range to a percentage of the (recent) maximum. This change in logic makes the system much more resilient, and able to get a useful range of values from a wide variety of physical sensors.

Here's our code this week:

/*
* CapitiveSense Library Demo Sketch
* Paul Badger 2008
*/

#include
CapSense cs_4_2 = CapSense(4,2); // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapSense cs_5_3 = CapSense(5,3); // 10M resistor between pins 4 & 6, pin 6 is sensor pin, add a wire and or foil

/* digitalSmooth
Paul Badger 2007
*/

#define filterSamples 13 // filterSamples should be an odd number, no smaller than 3
int sensSmoothArray1 [filterSamples]; // array for holding raw sensor values for sensor1
int sensSmoothArray2 [filterSamples]; // array for holding raw sensor values for sensor2

long start;
long total1, maxData1; // variables for sensor1 data
long total2, maxData2; // variables for sensor2 data
float normalTotal1, normalTotal2;


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

void loop()
{
// GET THE CAPACITANCE VALUE
start = millis();
total1 = cs_4_2.capSense(30);
total2 = cs_5_3.capSense(30);

// FIND THE MAX OF THE PAST FEW SAMPLES
maxData1 = getMax(total1, sensSmoothArray1); // every sensor you use with digitalSmooth needs its own array
maxData2 = getMax(total2, sensSmoothArray2); // every sensor you use with digitalSmooth needs its own array

// NORMALIZE CURRENT SAMPLES TO RECENT MAX (GET PERCENTAGE VALUE)
normalTotal1 = (float)total1 / (float)maxData1;
normalTotal2 = (float)total2 / (float)maxData2;

// DEBUG print sensor output 1
Serial.print("4_2: ");
Serial.print(total1);
Serial.print("\t");
Serial.print(maxData1);
Serial.print("\t");
Serial.println(normalTotal1);

// DEBUG print sensor output 2
Serial.print("5_3: ");
Serial.print(total2);
Serial.print("\t");
Serial.print(maxData2);
Serial.print("\t");
Serial.println(normalTotal2);


// WRITE 0-255 TO DIGITAL PIN FOR LED OUTPUT

analogWrite(9, (normalTotal1 * 255));
analogWrite(10, (normalTotal2 * 255));
// delay(1000);
}

// GETMAX FUNCTION

long getMax(int rawIn, int *sensSmoothArray){ // "int *sensSmoothArray" passes an array to the function - the asterisk indicates the array name is a pointer
int j, k, temp, top, bottom;
long total;
static int i;
static int sorted[filterSamples];
boolean done;

i = (i + 1) % filterSamples; // increment counter and roll over if necc. - % (modulo operator) rolls over variable
sensSmoothArray[i] = rawIn; // input new data into the oldest slot

for (j=0; j< (filterSamples - 1); j++){ if (sorted[j] > sorted[j + 1]){ // numbers are out of order - swap
temp = sorted[j + 1];
sorted [j+1] = sorted[j] ;
sorted [j] = temp;
done = 0;
}
}
}

top = 0;
for ( j = 0; j <> top ) {
top = sorted[j];
}
}
return top;
}

Here's the prototype in action:

You can see the LEDs getting brighter as Yuval gets closer to stealing the cash. Unfortunately, it's still not enough of a deterrent! And that was my coffee money!



Color us cheap, but we still haven't bought any new aluminum foil... the two sensors are what we had, cut in half. We had to calibrate the resistor to get a good response - 10 kOhm gave us an unpredictable 'blinky' response, with 4.7 kOhm, we had to actually touch the metal to get a response, but with a 6.4 kOhm resistor, it starts reacting 1" away, and gives a smooth corresponding response - the closer your hand, the brighter the LED. A potentiometer (variable resistor) could also be a useful component/improvement.

For our own final prototype, we are thinking of using multiple sensors and multiple outputs, so this has been a solid step toward that wiring setup as well as handling the logic. It also makes the whole system more robust for a wide variety of situations. Stay tuned...

No comments:

Post a Comment