The capacitive sensor

capacitive sensor

Since I received my WS2812b led strip I want to use for the shelf, I didn’t stop to play with it.

But when Madame saw the rgb led strip I was testing, priorities changed.

– Let’s use it in the kitchen! And I want to be able to manually light it up.

Alright you know what it means. Let’s go working!

First try : Proximity Sensor for Arduino

I first tried to use the Proximity Sensor I bought with a Sensor Kit for Arduino. I wanted to detect the movement of a hand below the sensor.

proximity sensor

It worked well… Until the night!

As this sensor is based on infrared, it doesn’t react the same when you are in illuminated room or in the dark.

I could use a light sensor in couple with the IR sensor, to try to check a relative difference of infrared, but I decided to try something else.

Second try : Capacitive Sensor for Arduino

The sensor kit for Arduino also contained a Capacitive Sensor.

This sensor can detect any contact on the metal wire located at its end:

capacitive sensor board_capacitive sensor

But it behave weirdly as it works only for 5 seconds every 10 seconds…

On the following video, the program turn off the led on the left when the sensor send a analog signal corresponding to a detected touch, the led should be off all the time I touch the sensor:

Not really what I expected.

Here is the code I used:

#include <stdlib.h>
#include <ESP8266WiFi.h>

int LED_PIN = D0; // Output pin for the led
int CAPACITIVE_PIN = A0; // Input analog pin for the sensor
int analogValue; // Analog value of the sensor
void setup ()
{
  Serial.begin(115200); // Starts Serial
  pinMode (LED_PIN, OUTPUT) ; // define LED_PIN as output
  pinMode (CAPACITIVE_PIN, INPUT) ; // define CAPACITIVE_PIN as input
}
void loop ()
{
  delay(100); // Wait 100 millis
  analogValue = analogRead(CAPACITIVE_PIN); // Read the analog value from the sensor
  Serial.printf("analog read : %d\n", analogValue);
  if(analogValue == 1024){
    // LED on when nothing detected
    digitalWrite(LED_PIN, HIGH);
  }else {
    // LED off when touch detected
    digitalWrite(LED_PIN, LOW);
  }
}

Last try : DIY

I decided to make my own capacitive sensor. I remember many DIY projects used capacitive sensors to make capacitive gamepads, or a fruit piano.

And I found the easiest way to do it : the Capacitive Sensor Arduino Library

How it works:

The CapacitiveSensor library turns two or more Arduino pins into a capacitive sensor, which can sense the electrical capacitance of the human body. All the sensor setup requires is a medium to high value resistor and a piece of wire and a small (to large) piece of aluminum foil on the end. At its most sensitive, the sensor will start to sense a hand or body inches away from the sensor.

You just have to put a resistor between the two GPIO, and connect a wire between the receiver gpio and the resistor.

How it works :

When the send pin changes state, it will eventually change the state of the receive pin. The delay between the send pin changing and the receive pin changing is determined by an RC time constant, defined by R * C, where R is the value of the resistor and C is the capacitance at the receive pin, plus any other capacitance (e.g. human body interaction) present at the sensor (receive) pin.

The call to to the capacitiveSensor(int sample) method will return a integer that represent an arbitrary value representing the absolute capacitance. It is near of zero until you touch the foil and add your body capacitance to the circuit.

I first tried to get the result of the lib and display it with a serial output.

At this stage, the board looks like that:

circuit-capacitive-sensor circuit-capacitive-sensor

And the code is as simple as:

#include <CapacitiveSensor.h>

CapacitiveSensor capacitiveBetween0And1 = CapacitiveSensor(D0,D1);
void setup()
{
   Serial.begin(115200);
}

void loop()
{
    long capacitiveResult =  capacitiveBetween0And1.capacitiveSensor(30);
    Serial.println(capacitiveResult);
    delay(500);
}

And of course, that did not work as planned. The library returned the code -2 on each call, that means a timeout occurred while the receiving pin waited for its state to change.

As I was feeling I was going to struggle on that, I wanted to have a visual indicator of the touch detection. I added a led to know if the sensor:

circuit-capacitive-sensor-led

And the code:

#include <CapacitiveSensor.h>

int CAPACITIVE_THRESHOLD = 50;

CapacitiveSensor capacitiveBetween0And1 = CapacitiveSensor(D0,D1);
void setup()
{
   Serial.begin(115200);
   // LED PIN
   pinMode(D2, OUTPUT);
}

void loop()
{
    long capacitiveResult =  capacitiveBetween0And1.capacitiveSensor(30);
    Serial.println(capacitiveResult);

    // If we have a value we turn the led ON
    if(capacitiveResult >= CAPACITIVE_THRESHOLD){
      digitalWrite(D2, HIGH);
    }else {
      digitalWrite(D2, LOW);
    }
    delay(500);
}

I could test with ease now, the led telling me if something was happening.

After long hours of testing, I understood the resistor I used, a 1Mohm resistor as recommended in the official documentation, was causing the issue.

I plugged a 300Komh resistor in place of the 1Mohm, and finally, it worked!

I created an issue on the project github repository to update the documentation: https://github.com/PaulStoffregen/CapacitiveSensor/issues/18

Integration int iot4i

Check the complete code of the firmware in new 0.2.0 release of iot4i/firmware

You can see the details of the circuit on circuit.io :

Here is the final result in my kitchen:


Possible enhancements:

  • The capacitive sensor can sense the human body through conductive materials like wood, but the material of my shelf is not conductive. So I must touch the foil behind the plank.

Credits:

comments powered by Disqus