Tactile Plant

Use a microcontroller as a capacitive interface

A small afternoon project to make a tactile interface with a microcontroller.

A bit of context: we are in 2019, I’m currently in 5th year of engineering school, in IoT class. With a group of five, we have to make a 4 day project on the subject “a desirable useless connected object” (Well, a subject of society). Our team decided to go with a connected plant called Super Spinach 3000, but for me something was missing to make our project really desirable.

I recalled the project “Botanicus interacticus” from Disney Research Hub, allowing the user to visualize precisely enough the tactile interactions with the plant. A connected plant is good, but a connected plant that can it’s joy to be cuddled is much better !

The tram, convinced by my idea, told me to handle this part (damn).

Impedance Detection

Let’s start by displaying the raw data from an analog pin before and during a contact, with the help of the following code (File > Examples > 01: Basics > AnalogSerialRead) :

void setup() {
    Serial.begin(115200);
}

void loop() {
    Serial.println( analogRead( A1 ) );
}

The results are displayed using the Arduino IDE serial monitor.

What we are trying to do here is a simple Voltage Divider

Floating Pin

First, I simply plugged a wire in pin A1, and I watch the raw data for a while, before putting my finger of the wire. Here is an example of the raw data, at the instant of contact with the wire:

The signal looks like a sinusoidal, oscillating around 512 (1024/2) with no load, and saturated between 0 and 1023 when I touch the wire.

What is this sinusoidal ? (click to expand)

The Analog to Digital Converter (ADC) of the Arduino uses 1à bits, so the output values are between 0 and 1023.

Here we observe a sinusoidal noise with a low amplitude before I establish contact, and with a high amplitude after. This points toward an external noise to the system, received by the “antenna” created by the wire on A1 and my body.

This noise shows 5 periods over 100 milliseconds, which is 50Hz (and here you should see where this is going).

Yes, a 50Hz sinusoidal signal is from the (French) electric network ! And we can not avoid to intercept it with an antenna like installation (like we have here).

Here is the GIF :

Even if the contact with the pin is detected (the red LED is lighting up), the pin stays “loaded” for a few seconds after I take out my hand. This is not the desired behavior.

Pull up 2 M Ohms

By adding a 2 Mega Ohms resistor between our A1 pin and the Vcc (Here, 5 volts), we constrain the value at A1 and the pin reinitialisation.

The no load value is here close to 1023, and goes down to 980 when a contact is made. This time we can simply add a condition to light the LED if we go under 1000 :

//light up led when we go under 1000
digitalWrite(LED_BUILTIN, sensorValue < 1000);

(Blinks are a consequence of the sinusoidal noise and camera refresh rate)

No more loaded pin problems now, the strong impedance of the resistor also allows removing quite a bit of noise.

However, by using a simple threshold, our system becomes sensible to any kind of perturbations. This system only works because of the natural human impedance, which is a value sensible to a lot of factors (humidity and thickness of the skin, isolation from ground, …). Moreover, this system can not work reliably with a plant or another object.

To detect this kind of contact, we will keep the same circuit and add a capacitive detection.

Capacitive Detection

A capacitor is a layer of insulator between two layers of conductive materials. This component has a capacity to retain and free charges, and that’s what we will use here.

We want to charge our capacitor, and then measure the time it takes to discharge entirely (with the value cycles). This value is compared to a baseline cycleThreshold which represent our basic environment capacity, set when the system as no load, of with a potentiometer.

const int plantSensor = 4;
uint8_t cycleThreshold = 25;

void setup() {
    pinMode(plantSensor, OUTPUT);
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    //empty capacitor
    pinMode(plantSensor, OUTPUT);
    digitalWrite(plantSensor, LOW);
    delayMicroseconds(1000);

    //count commutation
    pinMode(plantSensor, INPUT);
    uint8_t cycles;
    for(cycles = 0; cycles < 256; cycles++) {
        if(digitalRead(plantSensor) == HIGH)
            break;
    }
    
    //touch detected
    digitalWrite(LED_BUILTIN, cycles > cycleThreshold);
}

This system is less sensible to noise and the output value is much more stable. Furthermore, the body natural impedance have a lot less influence on the results. I’ve made some tests with a grounded wire placed on my skin, closer and closer to the detection wire, without observing output changes (unlike the impedance detection).

Results !

Many materials can now be use as interfaces !

A banana: Banana gif

A plant: Banana gif

Our project Super Spinach 3000 and its tactile interface gave us a nice 18/20, everybody wanted to pet our plant (see the code of the whole projet). I also handled the EPaper screen to display the plant happiness (the general code quality is not my responsibility…)

On the plant GIF, we can see the LED lighting up just before my hand touches it. This is because the value of cycleThreshold is too low: the proximity of my hand is sufficient to change the capacity of our system (with a capacitor formed by my hand | the air | the plant). Interesting for a magic effect.

Notes

I’m not too sure about the long term effects of this type of interfaces on a living organism, but we can make some observations/deduction:

  • No idea of the long term effects of loading and unloading the plant (do not risk it: probably not good)
  • The wire connected in the plant will act as a cathode, and chemically attack the plant (certainly not good)
  • The wire is made of metal (copper ?), and metals are in bad end of the specter of friends of plants. In any case, piercing a hole in a plant for the wire is not a good idea from a contamination point-of-vue (definitely not good)

See also