Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 33 additions & 36 deletions FastCapacitiveSensor.cpp
Original file line number Diff line number Diff line change
@@ -1,64 +1,61 @@
#include "FastCapacitiveSensor.h"
#include <math.h>

FastCapacitiveSensor::FastCapacitiveSensor() {
FastCapacitiveSensor::FastCapacitiveSensor(int sendPin, int receivePin, int frequency, int breakThreshold, float exceptRatio, int adcBits) : sendPin(sendPin), receivePin(receivePin), numReads(frequency), breakThreshold(breakThreshold), exceptRatio(exceptRatio) {
adcmax = 1 << adcBits;
inputThreshold = adcmax * 0.9;
except = frequency * exceptRatio;
use = frequency - 2 * except;
}

static void swap(double* a, double* b) {
double c = *a;
static void swap(float* a, float* b) {
float c = *a;
*a = *b;
*b = c;
}

static void sort(double* array) {
int size = sizeof(array) / sizeof(double);
static void sort(float* array) {
int size = sizeof(array) / sizeof(float);
for(int i = 0;i < size;i++)
for(int j = size - 1;j > i; j--)
if(array[j] < array[j - 1])
swap(&array[j], &array[j - 1]);
}

void FastCapacitiveSensor::begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio) {
SEND = send;
RECEIVE = receive;
VOLTAGE = voltage;
FREQUENCY = frequency;
BREAKTHRESHOLD = breakthreshold;
EXCEPTRATIO = exceptratio;
void FastCapacitiveSensor::begin() {
pinMode(sendPin, OUTPUT_OPENDRAIN);
pinMode(receivePin, INPUT);
}

double FastCapacitiveSensor::touch() {
double VAL[FREQUENCY];
double INPUTTHRESHOLD = VOLTAGE * 1024 / 5 * 0.9;
unsigned long FastCapacitiveSensor::touch() {
float values[numReads];

for (int i = 0; i < FREQUENCY; i++) {
double val = 0;
unsigned long starttim;
digitalWrite(SEND, HIGH);
starttim = micros();
while (analogRead(RECEIVE) < INPUTTHRESHOLD) {
val = micros() - starttim;
if (val > BREAKTHRESHOLD) {
int tim = micros() - starttim;
int vol = analogRead(RECEIVE);
double gamma = -log(1 - vol / (INPUTTHRESHOLD / 0.9)) / tim;
val = -log(1 - 0.9) / gamma;
for (int i = 0; i < numReads; i++) {
float val = 0;
digitalWrite(sendPin, HIGH);
unsigned long starttim = micros();
while (analogRead(receivePin) < inputThreshold) {
unsigned long t1 = micros() - starttim;
if (t1 > breakThreshold) {
// for some reason it works better if we do anther read here
int v1 = analogRead(receivePin);
val = t1 * logf(1.0 - 0.9) / logf(1.0 - ((float)v1 / (float)adcmax));
break;
}
}
digitalWrite(SEND, LOW);
digitalWrite(sendPin, LOW);
delayMicroseconds(10);

if (val > 0) {
VAL[i] = val;
values[i] = val;
} else
i--;
}
sort(VAL);
double VALsum = 0;
int except = FREQUENCY * EXCEPTRATIO;
for (int i = except;i < FREQUENCY - except;i++)
VALsum += VAL[i];
int dev = FREQUENCY - 2 * except;
return VALsum / dev;
if (except > 0) {
sort(values);
}
float sum = 0;
for (int i = except;i < numReads - except;i++)
sum += values[i];
return (unsigned long)(sum / use);
}
19 changes: 10 additions & 9 deletions FastCapacitiveSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@

class FastCapacitiveSensor {
public:
FastCapacitiveSensor();
void begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio);
double touch();
FastCapacitiveSensor(int sendPin, int receivePin, int numReads, int breakThreshold, float exceptRatio, int adcBits=10);
void begin();
unsigned long touch();

private:
int FREQUENCY;
int BREAKTHRESHOLD;
double EXCEPTRATIO;
int SEND;
int RECEIVE;
double VOLTAGE;
int numReads;
int breakThreshold;
float exceptRatio;
int sendPin, receivePin;
int adcmax;
float inputThreshold;
int except, use;
};

#endif
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,39 +45,41 @@ See also example program.
#include <FastCapacitiveSensor.h>
```

### Define a class
### Define an instance

```c++
FastCapacitiveSensor sensor1;
```

### Execute begin function

```c++
sensor1.begin(A0, A1, 5.0, 10, 10, 0.2);
FastCapacitiveSensor sensor1(A0, A1, 10, 10, 0.2);
```

arguments:

```c++
void begin(sendPin, receivePin, maxVoltage, frequency, breakThreshold, excludeRatio);
void begin(sendPin, receivePin, numReads, breakThreshold, excludeRatio, adcBits);
```
sendPin is a pin that you can use the function digitalWrite on.

receivePin is read out with analogRead, so it should be an analog pin.

maxVoltage is the voltage of the sendPin. It is $V_0$.

frequency is how many times the touch function tries sensing.
numReads is how many times the touch function tries sensing.

breakThreshold is the threshold of breaking sensing. The unit is micro seconds. the touch function finish sensing on the breakThreshold time, and after that, calculate the expected time of sensing. It is $t_1$.

excludeRatio is the ratio of exclusion of sensed values. Must be larger than or the same as 0 and smaller than 0.5.

adcBits is the bit-depth of the analog-digital converter. It is by default 10, but some miccontrollers suport higher bit-depths via analogReadResolution().

### Execute begin function

```c++
sensor1.begin();
```

This will configure the pin-modes.

### Sense

```c++
sensor1.touch()
```

The return value is the sensed (or calculated) time in units of micro seconds. The type is double.
The return value is the sensed (or calculated) time in units of micro seconds. The type is `unsigned long`.
14 changes: 6 additions & 8 deletions examples/FastCapacitiveSensor/FastCapacitiveSensor.ino
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#include <FastCapacitiveSensor.h>
FastCapacitiveSensor sensor1;
FastCapacitiveSensor sensor2;
// the send pin should be a pin that can be used with the digitalWrite() function
// the receive pin MUST be an analog pin. The library uses analogRead() internally.
FastCapacitiveSensor sensor1(A0, A1, 10, 10, 0.2);
FastCapacitiveSensor sensor2(A2, A3, 10, 10, 0.2);

void setup() {
pinMode(A0, OUTPUT); // the send pin should be a pin that can be used with the digitalWrite() function
pinMode(A1, INPUT); // the receive pin MUST be an analog pin. The library uses analogRead() internally.
pinMode(A2, OUTPUT);
pinMode(A3, INPUT);
Serial.begin(9600);
sensor1.begin(A0, A1, 5.0, 10, 10, 0.2);
sensor2.begin(A2, A3, 5.0, 10, 10, 0.2);
sensor1.begin();
sensor2.begin();
}

void loop() {
Expand Down