I'm trying to set up a capacitive switch that triggers a relay attached to an overhead light. The capacitive switch is painted onto a wall and is based on this project from bare conductive:
http://www.bareconductive.com/make/make-a-lightswitch-with-electric-paint/
Although I started with the sketch in the tutorial, I eventually ran into problems. The tutorial sketch is based on a specific trigger - if the arduino registers a value above X, it is triggered. As spring moved into summer, the humidity made it very hard to settle on a single, absolute trigger point.
As a result, I tried to move to a floating average trigger point. Instead of triggering at X, the switch triggered at 1.3 Y, where Y is a floating average of previous readings. While this worked in theory, I'm running into trouble in practice.
Essentially what happens is that the floating average stays low (say 150) while the fairly constant reading is high (say around 400). The result is that every 350ms the light turns from off to on, or from on to off. Eventually, the floating average floats up towards the reading and light stops changing.
However, at that point the actual reading plummets, dragging the floating average down with it. Once the floating average gets low enough, the entire cycle starts again.
My suspicion is that this is an electrical problem, but I have no idea what I am missing. Does anyone have any ideas?
thanks!
#include <CapacitiveSensor.h>
#define MAINSpin 13
int lastButtonState;
int currentPinMode = 0;
int running_average = 5;
CapacitiveSensor cs_4_2 = CapacitiveSensor(4,2); // Your resistor goes between pins 4 & 2. Your pad of paint should be connected to pin 2
void setup(){
pinMode(MAINSpin, OUTPUT);
digitalWrite(MAINSpin, LOW);
cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
Serial.begin(9600);
}
void loop()
{
long reading = cs_4_2.capacitiveSensor(100); // defines reading as the reading from the sensor
Serial.println(reading);
Serial.println(" "); // prints reading value to the serial port
// new serial stuff
Serial.print("reading = " );
Serial.print(reading);
Serial.print("running_average = " );
Serial.println(running_average);
delay(2);
// start new stufff
running_average = (1 + (((0.99 * (running_average * 100)) + (0.01 * (reading * 100))) / 100)); // this generates a running average of the reading
// but it will take a few cycles to spool up
// the +1 is to make sure that the running average never hits zero, which just screws things up
// the * 100 is to avoid small numbers that get lost when rounded
if (reading > (1.3 * running_average) && millis() > 5000) { // triggered if the current reading is significantly higher than
// the running average AND the arduino has been on for more than 2 seconds
// this 2 seconds gives it time to get the average up
currentPinMode = currentPinMode + 1; // switch to the next state (there are only 2 states - on and off
if (currentPinMode >= 2) {
currentPinMode = 0;
}
delay(350); // if the conditions were met and the switch happens, this delay gives you a chance to stop touching the switch
}
// end new stuff
switch (currentPinMode) { // this is where the states are stored
case 0: // off
digitalWrite(MAINSpin, LOW);
break;
case 1: // on
digitalWrite(MAINSpin, HIGH);
break;
}
}