Arduino as Capacitive Sensor

I really enjoying your technique !!! It's brilliant !!! :D 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.

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.

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.

That is correct. Good luck with your project :)

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

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.

// 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

Looks cool.. :-)

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

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...

So what can I do about that? I’m really newbie to this… Learning as I go…

Thanx for your time and help

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.

// 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.

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.. koser.dk/mads/arduino.jpg What could be the problem?

Thanx for your time

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?

I’m not sure I understand the last part you write… But I tryed using pin13 and the small LED blinks… :slight_smile:
How would I print the exact signal/numbers that is recieved - I need to use these numbers…

Thanx again

//Mads

I got this error when I exported to the board::

Error inside Serial.()

gnu.io.PortInUseException: Unknown Application

at gnu.io.CommPortIdentifier.open(CommPortIdentifier.java:354)

at processing.app.Serial.(Serial.java:127)

at processing.app.Serial.(Serial.java:72)

at processing.app.Uploader.flushSerialBuffer(Uploader.java:67)

at processing.app.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:69)

at processing.app.Sketch.upload(Sketch.java:1699)

at processing.app.Sketch.exportApplet(Sketch.java:1761)

at processing.app.Editor$42.run(Editor.java:1955)

at java.awt.event.InvocationEvent.dispatch(Unknown Source)

at java.awt.EventQueue.dispatchEvent(Unknown Source)

at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.run(Unknown Source)

java.lang.NullPointerException

at processing.app.Serial.setDTR(Serial.java:480)

at processing.app.Uploader.flushSerialBuffer(Uploader.java:76)

at processing.app.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:69)

at processing.app.Sketch.upload(Sketch.java:1699)

at processing.app.Sketch.exportApplet(Sketch.java:1761)

at processing.app.Editor$42.run(Editor.java:1955)

at java.awt.event.InvocationEvent.dispatch(Unknown Source)

at java.awt.EventQueue.dispatchEvent(Unknown Source)

at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.run(Unknown Source)

What can this mean?

It could mean a few things. Is anything else running that might be using the serial port? Have any over-aggressive firewalls? Did you select the right serial port from the Tools > Serial Port menu?

I have a question about adding more capacitive touch sensors through a multiplexer. I'd like to add a bunch more sensors providing continuous data (i.e. not digital on-off buttons). The tests I've made make me concerned that I won't be able to get smooth, consistent data when reading this through a multiplexer (MC14067). I understand that with wires dangling and a breadboard one can pick up stray capacitance so it's not the best test but my tests have led me to be concerned anyway and I thought I'd ask if anyone can confirm the possibility (or impossibility) of this technique before I go through all the effort of getting a PCB made.

Here's the situation:

1) Connecting a sensor and the resistor directly to the Arduino pins produces smooth, continuous data as my finger moves across the sensor (as long as there's some insulation over the copper - scotch tape has worked fine for my prototypes).

2) Connecting the sensor and resistor into a breadboard and then on to the Arduino also produces smooth, continuous values (though slightly different than number 1).

3) Connecting the pins through a multiplexer to read multiple sensors produces approximately accurate results but the values jump around a bit. That is, it won't be completely random but with a constant finger position it will jump back and forth within a small range. Too much change to use smoothing in the code I think.

The fact that both 1 and 2 work well leads me to believe that it's the multiplexer, not the breadboard/dangling wires that is causing the problem.

Anyone have any thought on how/if this setup could work?

Thanks.

P.S. Thanks for sharing this cool technique!

P.P.S - Well, I just figured something out. If I reverse the order of the HIGH-to-LOW and LOW-to-HIGH transition sections, I get much smoother results. Still not quite as smooth as without the multiplexer, but I'm more optimistic about getting this to work.

Any further thoughts would still be appreciated.

Thanks.

Hi,
A guy named Terry Fritz did some work on using multiple capacitance sensors together. It’s not exactly an answer to the multiplexer question, but it could be helpful. I’m not techy enough to know exactly how, but he found a way to clean up and amplify noisy signals from the antennas.
Check it out: http://thereminvision.com/version-2/TV-II-index.html

:) :) :) :)

I've potentially saved a HELL of a lot of money coming across this forum! I'm wanting to toggle a switch like you would with one of those tactile lamps that you touch a few times to get different degrees of intensity. What I'd really, REALLY appreciate would be if someone pointed me in the right direction for achieving this using Max/MSP as the programming language (I'm using 'simplemessagesystem' to interface the Arduino with Max). Would it be too much of a challenge?

Thanks for your time,

Gennaro

:) :) :) :)