Welcome, Guest. Please Login or Register
Arduino: Forum
09.09.2010 at 08:43:56


Pages: 1 2 3 4
Arduino as Capacitive Sensor (Read 34910 times)
paulb
Senior Member
****
Offline

dinosaur cork

Posts: 262

Arduino as Capacitive Sensor
10.02.2007 at 03:57:38
 
Some experiments with the Arduino as a capacitive sensor. All it requires is a 10 M resistor and a piece of wire. I was able to sense a hand about four inches from my 1.5" sq aluminum foil sensor.

Included are some machine code and port manipulation and an easy smoothing filter.


// CapSense.pde
// Paul Badger 2007

// Fun with capacitive sensing and some machine code - for the Arduino (or Wiring Boards).
// Note that the machine code is based on Arduino Board and will probably require some changes for Wiring Board
// This works with a high value (1-10M) resistor between an output pin and an input pin.
// When the output pin changes it changes the state of the input pin in a time constant determined by R * C
// where R is the resistor and C is the capacitance of the pin plus any capacitance present at the sensor.
// It is possible when using this setup to see some variation in capacitance when one's hand is 3 to 4 inches from the sensors
// Try experimenting with larger sensors. Lower values of R will probably yield higher reliability.
// Use 1 M resistor (or less maybe) for absolute touch to activate.
// With a 10 M resistor the sensor will start to respond 1-2 inches away

// Setup
// Connect a 10M resistor between pins 8 and 9 on the Arduino Board
// Connect a small piece of alluminum or copper foil to a short wire and also connect it to pin 9

// When using this in an installation or device it's going to be important to use shielded cable if the wire between the sensor is
// more than a few inches long, or it runs by anything that is not supposed to be sensed.
// Calibration is also probably going to be an issue.
// Instead of "hard wiring" threshold values - store the "non touched" values in a variable on startup - and then compare.
// If your sensed object is many feet from the Arduino Board you're probably going to be better off using the Quantum cap sensors.

// Machine code and Port stuff from a forum post by ARP  http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1169088394/0#0



int  i;
unsigned int x, y;
float accum, fout, fval = .07;    // these are variables for a simple low-pass (smoothing) filter - fval of 1 = no filter - .001 = max filter

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

 DDRB=B101;     // DDR is the pin direction register - governs inputs and outputs- 1's are outputs
 // Arduino pin 8 output, pin 9 input, pin 10 output for "guard pin"
 //  preceding line is equivalent to three lines below
 //  pinMode(8, OUTPUT);     // output pin
 //  pinMode(9, INPUT);      // input pin
 //  pinMode(10, OUTPUT);    // guard pin
 digitalWrite(10, LOW);  //could also be HIGH - don't use this pin for changing output though
}

void loop() {
 y = 0;        // clear out variables
 x = 0;

 for (i=0; i < 4 ; i++ ){       // do it four times to build up an average - not really neccessary but takes out some jitter

   // LOW-to-HIGH transition
   PORTB = PORTB | 1;                    // Same as line below -  shows programmer chops but doesn't really buy any more speed
   // digitalWrite(8, HIGH);    
   // output pin is PortB0 (Arduino 8), sensor pin is PortB1 (Arduinio 9)                                  

   while ((PINB & B10) != B10 ) {        // while the sense pin is not high
     //  while (digitalRead(9) != 1)     // same as above port manipulation above - only 20 times slower!                
     x++;
   }
   delay(1);

   //  HIGH-to-LOW transition
   PORTB = PORTB & 0xFE;                // Same as line below - these shows programmer chops but doesn't really buy any more speed
   //digitalWrite(8, LOW);              
   while((PINB & B10) != 0 ){            // while pin is not low  -- same as below only 20 times faster
     // while(digitalRead(9) != 0 )      // same as above port manipulation - only 20 times slower!
     y++;  
   }

   delay(1);
 }

 fout =  (fval * (float)x) + ((1-fval) * accum);  // Easy smoothing filter "fval" determines amount of new data in fout
 accum = fout;  

 Serial.print((long)x, DEC);    // raw data - Low to High
 Serial.print( "   ");
 Serial.print((long)y, DEC);    // raw data - High to Low
 Serial.print( "   ");
 Serial.println( (long)fout, DEC); // Smoothed Low to High
}


Back to top
 
 
View Profile | WWW   IP Logged
TM
YaBB Newbies
*
Offline

Arduino rocks

Posts: 30

Re: Arduino as Capacitive Sensor
Reply #1 - 16.09.2007 at 18:39:17
 
hi, I tried to make your code work but no chance  Cry
I am using a 3.3M resistor and I don't have a clue  Undecided
Here is a picture:



The white cable has a piece of copper ( 4x3cm ) at the other end.
I am new to arduino so you might find me quite silly. I was planning on using a qt but if your technique works it's better.

Thank you for your time and contribution to arduino.
Back to top
 
 
View Profile | WWW   IP Logged
TM
YaBB Newbies
*
Offline

Arduino rocks

Posts: 30

Re: Arduino as Capacitive Sensor
Reply #2 - 16.09.2007 at 18:59:32
 
Hi again, I am really confused  Huh

I just changed the cable position. I moved the cable connected to pin9  and the white cable on the line above. Then I linked the 2 lines with the resistor and now It works !!!!!

I put a picture for the newbies like me ( and documentation ) Smiley



I am sorry for all this, hope that at least it will help others. It must be really silly the way I have done it in the first place. I really need to learn the basics.

Great code by the way, thanks for that !!!
Back to top
 
 
View Profile | WWW   IP Logged
TM
YaBB Newbies
*
Offline

Arduino rocks

Posts: 30

Re: Arduino as Capacitive Sensor
Reply #3 - 16.09.2007 at 19:24:21
 
I really enjoying your technique !!! It's brilliant !!!  Cheesy
It's going to work perfectly for our project. If you are in the UK and not far from Brighton at the beginning of November, It would be a pleasure to see you at the private view. Here is a link to the website for more info : http://www.sonicbody.co.uk

Thanks again.
Back to top
 
 
View Profile | WWW   IP Logged
Digger450
Senior Member
****
Offline



Posts: 350

Gender: male
Re: Arduino as Capacitive Sensor
Reply #4 - 16.09.2007 at 22:06:01
 
If you're curious, the reason it didn't work in your first picture is because you basically bypassed the resistor and your white wire and simply had 8 and 9 connected to each other.
Back to top
 
 
View Profile   IP Logged
TM
YaBB Newbies
*
Offline

Arduino rocks

Posts: 30

Re: Arduino as Capacitive Sensor
Reply #5 - 17.09.2007 at 12:34:41
 
Hi, I've been thinking about what you said. Is it because the two legs of the resistor are on the same line so the two legs are connected together instead of having the two legs separated?
Anyway,Thanks for your previous explanation.
Back to top
 
 
View Profile | WWW   IP Logged
Digger450
Senior Member
****
Offline



Posts: 350

Gender: male
Re: Arduino as Capacitive Sensor
Reply #6 - 17.09.2007 at 14:53:26
 
That is correct.  Good luck with your project  Smiley
Back to top
 
 
View Profile   IP Logged
madskoser
YaBB Newbies
*
Offline

Arduino rocks

Posts: 8

Re: Arduino as Capacitive Sensor
Reply #7 - 24.09.2007 at 10:04:21
 
Hi

I've been trying to do this but I can't get it to work.. Wired everything up as on the photo and then ran the program but nothing happened. Can you give a description on how to do this currectly since I apperently do something wrong.

thanx

//Mads
Back to top
 
 
View Profile   IP Logged
TM
YaBB Newbies
*
Offline

Arduino rocks

Posts: 30

Re: Arduino as Capacitive Sensor
Reply #8 - 25.09.2007 at 22:22:19
 
Hi, did you find what was wrong ?
I am not a expert so I can't really help.
Are you following the second picture?
Maybe your resistor is not the good one, if it's to low it won't do anything.
Maybe your sensor is wrong. Try with copper or aluminium foil ( like in the one in your kitchen ).

Also, I used the commented part of it instead of the 'PORTB' thing.
Here is my code, it's really a quick one just for testing. The 'activation' thing with untouched and store as to be better. I am wondering between the difference between two person or a same person after a different day. It seems that somedays I have more electricity in my body then other days.
I haven't test with the original code again as I am looking into the multiplexer now.

Code:
// CapSense.pde
// Paul Badger 2007

int  i;
unsigned int x, y;
float accum, fout, fval = .07;    // these are variables for a simple low-pass (smoothing) filter - fval of 1 = no filter - .001 = max filter
int ledPin = 5;   // select the pin for the LED
float nonTouched, store = 0;

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

  //DDRB=B101;     // DDR is the pin direction register - governs inputs and outputs- 1's are outputs
  // Arduino pin 8 output, pin 9 input, pin 10 output for "guard pin"
  //  preceding line is equivalent to three lines below
  pinMode(8, OUTPUT);     // output pin
  pinMode(9, INPUT);	// input pin
  pinMode(10, OUTPUT);    // guard pin
  digitalWrite(10, LOW);  //could also be HIGH - don't use this pin for changing output though
  pinMode(5, OUTPUT);

  analogWrite(ledPin,255);
  delay(10);
  analogWrite(ledPin,0);
}

void loop() {
  y = 0;	  // clear out variables
  x = 0;

  for (i=0; i < 4 ; i++ ){	 // do it four times to build up an average - not really neccessary but takes out some jitter

	// LOW-to-HIGH transition
    //PORTB = PORTB | 1;			  // Same as line below -  shows programmer chops but doesn't really buy any more speed
    digitalWrite(8, HIGH);
    // output pin is PortB0 (Arduino 8), sensor pin is PortB1 (Arduinio 9)

    //while ((PINB & B10) != B10 ) {	  // while the sense pin is not high
    while (digitalRead(9) != 1) {    // same as above port manipulation above - only 20 times slower!
	x++;
    }
    delay(1);

    //  HIGH-to-LOW transition
    // PORTB = PORTB & 0xFE;		    // Same as line below - these shows programmer chops but doesn't really buy any more speed
    digitalWrite(8, LOW);
    //while((PINB & B10) != 0 ){		// while pin is not low  -- same as below only 20 times faster
    while(digitalRead(9) != 0 ) {     // same as above port manipulation - only 20 times slower!
	y++;
    }

    delay(1);
  }

  fout =  (fval * (float)x) + ((1-fval) * accum);  // Easy smoothing filter "fval" determines amount of new data in fout
  accum = fout;
  store++;
  if (store<50) {
    nonTouched = fout;
  }
  if (store>50){
    store = 50;
  }


  Serial.print((long)x, DEC);    // raw data - Low to High
  Serial.print( "   ");
  Serial.print((long)y, DEC);    // raw data - High to Low
  Serial.print( "   ");
  Serial.print( (long)fout, DEC); // Smoothed Low to High
  Serial.print( "   ");
  Serial.println( (long)nonTouched, DEC); // Smoothed Low to High
  if (fout>nonTouched+3){
    analogWrite(ledPin,255);
  }
  else{
    analogWrite(ledPin,0);
  }
}
 



Apart from that can't really help. Good luck
Back to top
 
 
View Profile | WWW   IP Logged
madskoser
YaBB Newbies
*
Offline

Arduino rocks

Posts: 8

Re: Arduino as Capacitive Sensor
Reply #9 - 26.09.2007 at 16:34:34
 
Looks cool.. Smiley

And thanx for the help so far.. But I have one problem and that is that the file is to big to fit on the Arduino board. Why can this be??

I will tell you more about the process of the project later...

Thanx

//Mads
Back to top
 
 
View Profile   IP Logged
westfw
God Member
*****
Offline

Strongly
opinionated, but not
official!

Posts: 2424
SF Bay Area (USA)
Gender: male
Re: Arduino as Capacitive Sensor
Reply #10 - 26.09.2007 at 16:48:32
 
madskoser wrote on 26.09.2007 at 16:34:34:
the file is to big to fit on the Arduino board. Why can this be??


The floating point used will presumably add quite a bit of code to a sketch...
Back to top
 
 
View Profile | YIM   IP Logged
madskoser
YaBB Newbies
*
Offline

Arduino rocks

Posts: 8

Re: Arduino as Capacitive Sensor
Reply #11 - 27.09.2007 at 08:37:19
 
So what can I do about  that? I'm really newbie to this.. Learning as I go..

Thanx for your time and help
Back to top
 
 
View Profile   IP Logged
TM
YaBB Newbies
*
Offline

Arduino rocks

Posts: 30

Re: Arduino as Capacitive Sensor
Reply #12 - 27.09.2007 at 09:22:44
 
Strange, maybe you have a older version of the arduino. I looked at mine and I still have plenty of space left after uploading the code. Weird.
It could the float variable like westfw said but that I would find this strange. That would mean you are very very limited then. Try without the two variable I added, so at least you could see something in the Serial Monitor if that's the problem. It's the button next to the Upload one. Upload your code, when done click this button and wait a few second.

Code:
// CapSense.pde
// Paul Badger 2007

int  i;
unsigned int x, y;
float accum, fout, fval = .07;    // these are variables for a simple low-pass (smoothing) filter - fval of 1 = no filter - .001 = max filter
int ledPin = 5;   // select the pin for the LED

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

  //DDRB=B101;     // DDR is the pin direction register - governs inputs and outputs- 1's are outputs
  // Arduino pin 8 output, pin 9 input, pin 10 output for "guard pin"
  //  preceding line is equivalent to three lines below
  pinMode(8, OUTPUT);     // output pin
  pinMode(9, INPUT);	// input pin
  pinMode(10, OUTPUT);    // guard pin
  digitalWrite(10, LOW);  //could also be HIGH - don't use this pin for changing output though
  pinMode(5, OUTPUT);

  analogWrite(ledPin,255);
  delay(10);
  analogWrite(ledPin,0);
}

void loop() {
  y = 0;	  // clear out variables
  x = 0;

  for (i=0; i < 4 ; i++ ){	 // do it four times to build up an average - not really neccessary but takes out some jitter

	// LOW-to-HIGH transition
    //PORTB = PORTB | 1;			  // Same as line below -  shows programmer chops but doesn't really buy any more speed
    digitalWrite(8, HIGH);    
    // output pin is PortB0 (Arduino 8), sensor pin is PortB1 (Arduinio 9)

    //while ((PINB & B10) != B10 ) {	  // while the sense pin is not high
    while (digitalRead(9) != 1) {    // same as above port manipulation above - only 20 times slower!		    
	x++;
    }
    delay(1);

    //  HIGH-to-LOW transition
    // PORTB = PORTB & 0xFE;		    // Same as line below - these shows programmer chops but doesn't really buy any more speed
    digitalWrite(8, LOW);		  
    //while((PINB & B10) != 0 ){		// while pin is not low  -- same as below only 20 times faster
    while(digitalRead(9) != 0 ) {     // same as above port manipulation - only 20 times slower!
	y++;  
    }

    delay(1);
  }

  fout =  (fval * (float)x) + ((1-fval) * accum);  // Easy smoothing filter "fval" determines amount of new data in fout
  accum = fout;

  Serial.print((long)x, DEC);    // raw data - Low to High
  Serial.print( "   ");
  Serial.print((long)y, DEC);    // raw data - High to Low
  Serial.print( "   ");
  Serial.println( (long)fout, DEC); // Smoothed Low to High

}

 



Good Luck.
Back to top
 
 
View Profile | WWW   IP Logged
madskoser
YaBB Newbies
*
Offline

Arduino rocks

Posts: 8

Re: Arduino as Capacitive Sensor
Reply #13 - 30.09.2007 at 14:23:41
 
I fixed the problem with size.. Was working in an old version of Arduino - so now it's no prob.
But I don't seem to get any signal, numbers or anything out..

What could be the problem?

Thanx for your time
Back to top
 
 
View Profile   IP Logged
TM
YaBB Newbies
*
Offline

Arduino rocks

Posts: 30

Re: Arduino as Capacitive Sensor
Reply #14 - 30.09.2007 at 17:05:22
 
I think you have wired correctly. Do it like on the second picture. On yours, the pin8 and 9pin are not connected as they are on 2 seperated parts. The 2 two parts are not connected. See what I mean?
Back to top
 
 
View Profile | WWW   IP Logged
Pages: 1 2 3 4