Arduino as Capacitive Sensor

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

:slight_smile: :slight_smile: :slight_smile: :slight_smile:

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

:slight_smile: :slight_smile: :slight_smile: :slight_smile:

Hi all,

I'm a rookie to this Arduino game but I got this code working and it suits my project really well. However, I don't need to read various degrees of pressure, I merely need an on/off register. I know I need to add a boolean but I have no idea where... Any ideas?

Any help is a plus :slight_smile:

I am really interested in to get touch sensiting working together with max/msp, has anyone did that?
I am using the arduino2Max patch to get Arduino talk to max/msp.

hey,

i'm trying to do the same. i was initally using the capsense code but abandoned it because i couldn't seem to create multiply capacitive sensors from it. i'm not that hardcore a programmer you see.

instead, i found this code Arduino Playground - CapacitiveSensor

which works perfectly in arduino, the numbers are outputting and i'm trying to use with the arduino2max patch but no joy. as the pins are declared in the arduino code, surely the max patch should read the digital pins? any help is really appreciated.

Cheers

I'm currently building a capactive measurement system as part of my PHd, I've found, depending on what accuracy you want, that the best way is to use a sigma delta modulation technique. You can find this in Analog Devices AD774x series of Capacitive to Digital Converters. These chips go from one channel to 12 channels for mounting capacitive electrodes and have resolutions between 8 and 24 bits over full scale ranges of around 25pF with a bit of calibration, obviously, that gives a lot of sensitivity.

The chips communicate with a host through the i2c bus, so you ca use Arduino's wire library to get the data out of the slave chip (I sweated over a prototype function for a PIC i2c protocol for months when I found arduino!) and use that to manipulate the data anyway you want.

the only thing is that these chips are only available in TSSOP form so can be a bit of a pain in the arse to solder, however it's quite a nice solution as I am finding out.

What is the purpose of the guard pin (pin 10)? The code seems to work just as well without it...

You are correct that the guard pin doesn't do much and can easily be omitted. This was a klugy way to implement a technique which is used with op amps and other high impedance (low current) circuits.

You can now use the [[Arduino Playground - HomePage capSense library]] and use any pins you want. The results will vary a bit from pin to pin though.

But if you do want to make the wire insensitive and only the foil at the end sensitive, use shielded audio wire and ground the shield on the duino end only. (Make sure the shield on the other end doesn't touch the sensor, or it won't work.

Paul

What is the difference between this and Arduino Playground - CapacitiveSensor? Is the one wire method only for direct touch, while this can sense a longer distance?

bump*

This post is a bit old now but I have a question...

I have used this circuit and because I didn't have a large enough resistor, I connected up an LDR.

I then got a smoothed value of 0 and 4 when I touched it. When I covered up the LDR, producing a massive resistance it would give me values of 100-200 when I was ~1m away and then increase to just over 1000 when I walked up to it.

I am wanting to use this setup to sense people close to a project but I would like a normal resistor. Anyone got any ideas as to what kind of size/value I should be looking at?

Thanks,

Mowcius

hi! this code is fantastic!! I am actually thinking of using this for my project so thanks!

i was wondering what the coding would be if i wanted to put an LED and have it blink when the wire is touched. Im not very code-savvy, so any suggestions would be awesome!

Ok, since I posted that, I have learnt a lot about all this!

It will be easy to sense touching a wire. Use the tutorial and serial read to see what values you get when you touch the wire. Then use 'if' commands for if it is this value or higher then light up the LED.

If you need any more help then just say :smiley:

Mowcius

ok, this is going to sound a bit dumb, but i dont EXACTLY know what the coding should look like....and i have tried looking at the page that helps with coding, but i just get so nervous...

so i guess my next question would be what exactly is the right "lingo" of coding that i should enter? So working off the code here for instance:

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
}

what do i type in? and where?

Ok first thing, please just modify your post and put the code in # (code brackets - takes up less room)

Have you tried that code on your arduino? I suggest you conect up the circuit and try that code. Just copy everything from '// CapSense.pde' downwards straight into the arduino IDE and upload it.

The resistor doesn't have to be 10M, anything near will do if you don't have a 10M.

Then use the serial monitor to work out what values you get 'normally' and when you are touching it.

Then at the start of the code you need to define your LED. Use pin 13 as it has an inbuilt LED (on newer boards).

So the code should look like this at the top:

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 =  13;    // LED connected to digital pin 13

[edit]You also need to define the pin, just stick it after defining serial in setup:

void setup() {
 Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

[/edit]

Then after Serial.println( (long)fout, DEC); // Smoothed Low to High
you want to put an 'if' command.

Eg:

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

if(x > 50)
  digitalWrite(ledPin, HIGH);
else
  digitalWrite(ledPin, LOW);
delay(20) //Delay for good measure! (not strictly necessary but might as well have it)
}//Last line of code - nothing after this!

Put the 'if' value as just below the lowest value you get when you touch the wire.

There may be a stupid error in that code but it should work.
Say if it doesn't work and i'll fix it :slight_smile:

Mowcius