Capacitive sensor, swipe and turning on/off LED

Hi all,

I was reading and looking for solutions a lot but unsuccesfully. I'm trying to create simple capacitive swipe with three sensors. Let's say that I manage to get it work but not in case as I want it.
So if I want to turn on the LED I need to perform very slow movement over each sensor. I want to perform that faster.

Did I defined any wrong timing or is just whole code wrong?

I also tried to change values of MaxInterval higher/lower but there is not so much difference.

I think that reading of sensor is quick enough but counting not.

Thank you for support.

#include <CapacitiveSensor.h>
CapacitiveSensor cs_4_8 = CapacitiveSensor(4,8); // 1M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_4_10 = CapacitiveSensor(4,10); // 1M resistor between pins 2 & 10, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_4_9 = CapacitiveSensor(4,9); // 1M resistor between pins 3 & 9, pin 8 is sensor pin, add a wire and or foil

unsigned int SensorValue = 0;     
unsigned int counter_sensor1 = 0;     
unsigned int counter_sensor2 = 0;  
unsigned int counter_sensor3 = 0;  
unsigned int previous_sensor = 0; 
unsigned long MaxInterval= 100;
unsigned long previous_Sensor_Millis = 0;


void setup()
{
cs_4_8.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example
cs_4_10.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example
cs_4_9.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example

Serial.begin(9600);
pinMode(13,OUTPUT);
}


  
void loop()
{

long currentMillis = millis();
long sensor1 = cs_4_8.capacitiveSensor(30);
long sensor2 = cs_4_9.capacitiveSensor(30);
long sensor3 = cs_4_10.capacitiveSensor(30);

Serial.print("Sensor1: "); // print sensor output
Serial.println(sensor1); // print sensor output
Serial.print("Sensor2: "); // print sensor output
Serial.println(sensor2); // print sensor output
Serial.print("Sensor3: "); // print sensor output
Serial.println(sensor3); // print sensor output
Serial.print("SensorValue: "); // print sensor output
Serial.println(SensorValue);


Serial.print("                      counter1: ");
Serial.println(counter_sensor1);
Serial.print("                                       counter2: ");
Serial.println(counter_sensor2);
Serial.print("                                                        counter3: ");
Serial.println(counter_sensor3);

/* Three capacitive sensors, check if first sensor is greater then threshold and increase counter1, same for sensor2 and sensor3 */
if ((unsigned long) currentMillis - previous_Sensor_Millis >= MaxInterval)
  { 

  if(sensor1 > 8000 )
    {
      counter_sensor1++;
    }

    else 
        {
          counter1(); /*if sensor1 is not greater then threshold call function counter1()*/
        }
      
  if(sensor2 >8000)
    {
      counter_sensor2++;
    }

     else 
         {
           counter2();   
         }
    
   if(sensor3 > 8000)
     {
       counter_sensor3++;
     }
     else 
         {
           counter3();
         }
   
previous_Sensor_Millis = currentMillis;
  } 
}
 
/* If counter_sensor1 is greater than 1 (and lower then some value, example 4000) check previous pressed sensor and if is zero(=start) we are swiping up than set value of previous sensor on 1)*/
/* If previous is =2 than we are swiping down (in other direction) and turn off LED*/
/* Else counter_sensor1 is placed on 0 (in case when we don't hold sensor)*/
void counter1()
 {
       if(counter_sensor1 >1 && counter_sensor1 < 4000){
          if (previous_sensor == 0)
            {
              previous_sensor = 1;
            }
          if (previous_sensor == 2)
            {
              previous_sensor = 0;
              digitalWrite(13, LOW);
            } 
       }
       counter_sensor1=0;
 }


void counter2()
 {
       if(counter_sensor2 >1 && counter_sensor2 < 4000){
          if (previous_sensor == 1 || previous_sensor == 3)
            {
              previous_sensor = 2;
            }
          } 
          counter_sensor2=0;
 }

/* If counter_sensor3 is greater than 1 (and lower then some value, example 4000) check previous pressed sensor and if is zero(=start of other direction) we are swiping down than set value of previous sensor on 3)*/ 
/* If previous is =2 than we are swiping up and turn on LED*/

void counter3()
 {
   if(counter_sensor3 >1 && counter_sensor3 < 4000){
          if (previous_sensor == 0)
            {
              previous_sensor = 3;
            }
          if (previous_sensor == 2)
            {
              previous_sensor = 0;
              digitalWrite(13, HIGH);
            } 
       }
       counter_sensor3=0;
  }

I don't understand why you are counting anything. You need to record when a sensor reads above the threshold.

At the end of loop(), determine how many of the sensors have times that are above the threshold. If enough, compare the order of the times to determine the direction.

PaulS to be honest I don't know why I am counting :slight_smile: I'm not expert in programming so this is basicly my "learning". I'm reseraching this on web for long time but can't bring up code together.

So as I understood instead of:

if(sensor1 > 8000 )
{
counter_sensor1++;
}

I just need to "record" this step which is above value threshold (not the time but value of "capacitance reading") in some variable example as:

if(sensor1 > 8000 )
{
SensorValue = 1;
}
else {SensorValue = 0);

Or you mean to record time itsel?...but don't know how to be honest..

If is not a problem I would be greatful if you correct my code (or am I asking too much :slight_smile: )

Or you mean to record time itsel?...but don't know how to be honest..

Yes, you need to record the time that sensor value went above the threshold (not just is above the threshold.

The millis() and micros() functions are useful. Which one depends on just how fast you are.

Some time spend studying the state change detection example would be time well spent, too.

I checked your proposal of recording time that sensor went above the threshold.
I hope that I implement it right, currently somehow works. But still I need ti improve to have quicker swipe across sensors. To turn LED on (first swipe) it needs to be slow and swipe in other direction can be quicker and works. So this swipe of turning LED on is too slow.

Did I place statement "previous_Sensor_Millis = currentMillis;" on correct place?

I want after first swipe turn value of sensors time back to 0 (sensor01_time, sensor02_time, sensor03_time) then perform swipe in other direction and place values on 0, but doesn't work if I implement those values sensor01_time=0 (and others). Can you might help me where I messed it up?

#include <CapacitiveSensor.h>
CapacitiveSensor cs_4_8 = CapacitiveSensor(4,8); // 1M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_4_10 = CapacitiveSensor(4,10); // 1M resistor between pins 2 & 10, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor cs_4_9 = CapacitiveSensor(4,9); // 1M resistor between pins 3 & 9, pin 8 is sensor pin, add a wire and or foil


long previous_Sensor_Millis = 0;
long MaxInterval= 10;
long sensor01_time=0;
long sensor02_time=0;
long sensor03_time=0;

void setup()
{
cs_4_8.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example
cs_4_10.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example
cs_4_9.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example

Serial.begin(9600);
pinMode(13,OUTPUT);
}
void loop()
{

long currentMillis = millis();

long sensor1 = cs_4_8.capacitiveSensor(50);
long sensor2 = cs_4_9.capacitiveSensor(50);
long sensor3 = cs_4_10.capacitiveSensor(50);



if ((unsigned long) currentMillis - previous_Sensor_Millis >= MaxInterval) { 
if(sensor1 > 9000 && sensor2 < 5000 && sensor3 < 5000)

{
  sensor01_time = currentMillis;
}

else if(sensor2 > 9000 && sensor1 < 5000 && sensor3 < 5000)
{
  sensor02_time = currentMillis;
}

else if(sensor3 > 9000 && sensor2 < 5000 && sensor1 < 5000)
{
 sensor03_time = currentMillis;
}

previous_Sensor_Millis = currentMillis;


if (sensor01_time != 0){
    if (sensor03_time > sensor02_time &&  sensor02_time > sensor01_time &&  sensor03_time > sensor01_time) 
      {
       digitalWrite(13, HIGH); 
       /* sensor01_time = 0;     // Turn all sensor times to 0. DOESN'T WORK!
          sensor02_time = 0;     
          sensor03_time = 0; */
      }  
 }
   
      
       
if (sensor03_time != 0){
    if (sensor01_time > sensor02_time &&  sensor01_time > sensor03_time &&  sensor02_time > sensor03_time) 
      {
       digitalWrite(13, LOW);
        /* sensor01_time = 0;     // Turn all sensor times to 0. DOESN'T WORK!
          sensor02_time = 0;     
          sensor03_time = 0; */
      }
   }
   

 }


Serial.print("Sensor1: "); // print sensor output
Serial.println(sensor01_time); // print sensor output
Serial.print("Sensor2: "); // print sensor output
Serial.println(sensor02_time); // print sensor output
Serial.print("Sensor3: "); // print sensor output
Serial.println(sensor03_time); // print sensor output
Serial.print("Current: "); // print sensor output
Serial.println(currentMillis); // print sensor output




}

Get Millis out of the name of all your time variables. The fact that the time is in milliseconds is not really relevant.

That leaves previous_Sensor as the name of the variable, which, of course, tells us nothing.

You most definitely need a better name.

You want to compare the times when all three swipe times is non-zero, not when one of them is non-zero.

I agree bettter names are needed :slight_smile:

Meanwhile I corrected also first if sentence when comparing non-zero times of all sensors.
LED turns on, but when I want to put sensor0x_time back to 0 LED is off directly.

Only if I put some delay(x) between digitalwrite and sensor0x_time = 0. But if I want to avoid delays is there any other way to do it?

if (sensor01_time != 0 && sensor02_time !=0 && sensor03_time !=0 ){
    if (sensor03_time > sensor02_time &&  sensor02_time > sensor01_time &&  sensor03_time > sensor01_time) 
      {
       digitalWrite(13, HIGH); 
        //delay(10);
        sensor01_time = 0;     // Turn all sensor times to 0. DOESN'T WORK!
        sensor02_time = 0;     
        sensor03_time = 0; 
      }

is there any other way to do it?

Use the technique illustrated in the blink without delay example.

Some time after you turn the LED on, you want to turn it off and reset the times.

Sorry maybe I explained wrong, I want that LED stays on until opposite swipe occur but also want to reset the times. Reason is because I want to implement another function, example while only sensor is tapped twice I want to turn some other LED on. Currently only LEDs are as output, at the end I will change LEDs with some analog circuits.