Archives
All posts for the month December, 2013
The above video demonstrates the operation of an Arduino-driven proximity sensor constructed from a piece of aluminum foil, a resistor, an (optional) capacitor, and two LED’s. One observes marked brightening of the LED’s when the hand is about four inches above the aluminum foil – the foil does not have to be touched.
First, the credits. The project uses the Arduino CapSense Library written by Paul Badger in 2008. See the preceding link for the the needed library, the demo sketch, and a discussion of how CapSense works. The Arduino sketch below is based on Badger’s demo sketch.
Next, the caveats and sticky points. (1) To get good results, you may have to experiment. (2) Look at the output of the Arduino in the serial monitor. The first column gives the time needed for the Arduino to make one measurement and respond. The second column gives the “sensor reading”. (3) Use the second column to calibrate the system. (4) You may need to press the reset button if the system gets flaky. (5) You will notice marked changes in the behavior of the system according to the device that is providing it power. The video and also the settings used in the code below came from a system plugged into my laptop. If you plug it into the wall, it will give different readings. When the Arduino is connected to my laptop, bringing my hand near the laptop brightened the LED’s, just as they were brightened when I brought my hand near the aluminum foil. Why? Because my laptop is part of the capacitance of the circuit.
Overview:
Capacitative proximity sensor: When your hand gets near to or touches the tinfoil sensor, a light brightnes or turns on.
Circuit:
- 10 MOhm resistor between pins 2 and 4. Connect “sensor” wire to pin 2. Connect wire to tinfoil, etc.
- Pin 9 to LED to GND. (LED brightness is controlled by pulse-width modulation.) Same for pin 10.
Discussion:
- Uses a high value resistor e.g. 10M between send pin and receive pin.
- The Capsense library measures the time an RC circuit taked to return to state 1 after being forced in to state 2. This time is several multiples of the time constant RC. Thus, with the resistance R fixed, the measured time is a measurement of the capactance C.
- Human body capacitance is estimateed to be between 100 and 400 pF. If is 10 MOhms, and C 0s 100 pF, then RC is 1 ms.
- Resistor effects sensitivity, experiment with values, 50K – 50M. Larger resistor values yield larger sensor values.
- Receive pin is the sensor pin – attach aluminum foil for higher capacitance sensitivity.
- The values of threshold1, threshold2, and max were set by experimentation. Bring up the serial monitor (command-shift-M) and observe the numbers in the second column when your hand is far, news, or touching. Set these values accordingly. In the code below, LED 1 was set to respond only when my
hand was very close. LED 2 was set to respond to anything. - It helps to manually reset the arduino when the unit becomes flaky.
Arduino code
#include CapacitiveSensor cs_4_2 = CapacitiveSensor(4,2); // 10M resistor between pins 4 & 2, pin 2 is sensor pin // add a wire and or foil if desired int receivePin = 2; int sendPin = 4; int ledPin1 = 10; int ledPin2 = 9; void setup() { cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // above: turn off autocalibrate on channel 1 - just as an example Serial.begin(9600); pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); } void loop() { long start = millis(); long total = cs_4_2.capacitiveSensor(30); Serial.print(millis() - start); // check on performance in milliseconds Serial.print("\t"); // tab character for debug windown spacing Serial.print(total); // print sensor output Serial.println(); // parameters to set level for PWM output float level1; float level2; float threshold1 = 0; float threshold2 = 100; float max = 3000; if (total < threshold1) { level1 = 0; } else { level1= map(total,threshold1,max,0,1023); } if (total < threshold2) { level2 = 0; } else { level2= map(total,threshold2,max,0,1023); } analogWrite(ledPin1,level1); analogWrite(ledPin2,level2); delay(1); // arbitrary delay to limit data to serial port }