From e8e8da664bf91fa3b1e231b840750dfb4a1e3f08 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Tue, 29 Apr 2025 21:40:25 +0200 Subject: [PATCH 1/7] Allow to configure the bit-depth of the adc. The wiring library supports analogReadResolution() to e.g. specify 12 bits for some MCUs. --- FastCapacitiveSensor.cpp | 5 +++-- FastCapacitiveSensor.h | 3 ++- README.md | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/FastCapacitiveSensor.cpp b/FastCapacitiveSensor.cpp index 0b0e6f2..258ee68 100644 --- a/FastCapacitiveSensor.cpp +++ b/FastCapacitiveSensor.cpp @@ -18,18 +18,19 @@ static void sort(double* array) { swap(&array[j], &array[j - 1]); } -void FastCapacitiveSensor::begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio) { +void FastCapacitiveSensor::begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio, int adcBits) { SEND = send; RECEIVE = receive; VOLTAGE = voltage; FREQUENCY = frequency; BREAKTHRESHOLD = breakthreshold; EXCEPTRATIO = exceptratio; + ADCMAX = 1 << adcBits; } double FastCapacitiveSensor::touch() { double VAL[FREQUENCY]; - double INPUTTHRESHOLD = VOLTAGE * 1024 / 5 * 0.9; + double INPUTTHRESHOLD = VOLTAGE * ADCMAX / 5 * 0.9; for (int i = 0; i < FREQUENCY; i++) { double val = 0; diff --git a/FastCapacitiveSensor.h b/FastCapacitiveSensor.h index 5b102b4..0173c1e 100644 --- a/FastCapacitiveSensor.h +++ b/FastCapacitiveSensor.h @@ -6,7 +6,7 @@ class FastCapacitiveSensor { public: FastCapacitiveSensor(); - void begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio); + void begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio, int adcBits=10); double touch(); private: @@ -16,6 +16,7 @@ class FastCapacitiveSensor { int SEND; int RECEIVE; double VOLTAGE; + int ADCMAX; }; #endif \ No newline at end of file diff --git a/README.md b/README.md index f62089a..d4ffcc4 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ sensor1.begin(A0, A1, 5.0, 10, 10, 0.2); arguments: ```c++ -void begin(sendPin, receivePin, maxVoltage, frequency, breakThreshold, excludeRatio); +void begin(sendPin, receivePin, maxVoltage, frequency, breakThreshold, excludeRatio, adcBits); ``` sendPin is a pin that you can use the function digitalWrite on. @@ -74,6 +74,8 @@ breakThreshold is the threshold of breaking sensing. The unit is micro seconds. 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(). + ### Sense ```c++ From 2f366de5351cddd2ac039fa59fadb14382acf0bf Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Wed, 30 Apr 2025 23:57:40 +0200 Subject: [PATCH 2/7] Simplify the code * drop voltage param - this is not needed * rename the variables to match the readme * add more class member to extract static values --- FastCapacitiveSensor.cpp | 26 +++++++++++--------------- FastCapacitiveSensor.h | 5 +++-- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/FastCapacitiveSensor.cpp b/FastCapacitiveSensor.cpp index 258ee68..aa3b87c 100644 --- a/FastCapacitiveSensor.cpp +++ b/FastCapacitiveSensor.cpp @@ -18,32 +18,30 @@ static void sort(double* array) { swap(&array[j], &array[j - 1]); } -void FastCapacitiveSensor::begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio, int adcBits) { +void FastCapacitiveSensor::begin(int send, int receive, int frequency, int breakthreshold, double exceptratio, int adcBits) { SEND = send; RECEIVE = receive; - VOLTAGE = voltage; FREQUENCY = frequency; BREAKTHRESHOLD = breakthreshold; EXCEPTRATIO = exceptratio; ADCMAX = 1 << adcBits; + INPUTTHRESHOLD = ADCMAX * 0.9; + EXCEPT = FREQUENCY * EXCEPTRATIO; + USE = FREQUENCY - 2 * EXCEPT; } double FastCapacitiveSensor::touch() { double VAL[FREQUENCY]; - double INPUTTHRESHOLD = VOLTAGE * ADCMAX / 5 * 0.9; for (int i = 0; i < FREQUENCY; i++) { double val = 0; - unsigned long starttim; digitalWrite(SEND, HIGH); - starttim = micros(); + unsigned long 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; + unsigned long t1 = micros() - starttim; + if (t1 > BREAKTHRESHOLD) { + int v1 = analogRead(RECEIVE); + val = t1 * log(1.0 - 0.9) / log(1.0 - ((double)v1 / (double)ADCMAX)); break; } } @@ -57,9 +55,7 @@ double FastCapacitiveSensor::touch() { } sort(VAL); double VALsum = 0; - int except = FREQUENCY * EXCEPTRATIO; - for (int i = except;i < FREQUENCY - except;i++) + for (int i = EXCEPT;i < FREQUENCY - EXCEPT;i++) VALsum += VAL[i]; - int dev = FREQUENCY - 2 * except; - return VALsum / dev; + return VALsum / USE; } \ No newline at end of file diff --git a/FastCapacitiveSensor.h b/FastCapacitiveSensor.h index 0173c1e..3f69bbd 100644 --- a/FastCapacitiveSensor.h +++ b/FastCapacitiveSensor.h @@ -6,7 +6,7 @@ class FastCapacitiveSensor { public: FastCapacitiveSensor(); - void begin(int send, int receive, double voltage, int frequency, int breakthreshold, double exceptratio, int adcBits=10); + void begin(int send, int receive, int frequency, int breakthreshold, double exceptratio, int adcBits=10); double touch(); private: @@ -15,8 +15,9 @@ class FastCapacitiveSensor { double EXCEPTRATIO; int SEND; int RECEIVE; - double VOLTAGE; int ADCMAX; + double INPUTTHRESHOLD; + int EXCEPT, USE; }; #endif \ No newline at end of file From 47890b10f63d925352e281e0a6edaaa912a90cf9 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 1 May 2025 00:07:28 +0200 Subject: [PATCH 3/7] Don't sort if we don't exclude. --- FastCapacitiveSensor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FastCapacitiveSensor.cpp b/FastCapacitiveSensor.cpp index aa3b87c..1a43674 100644 --- a/FastCapacitiveSensor.cpp +++ b/FastCapacitiveSensor.cpp @@ -53,7 +53,9 @@ double FastCapacitiveSensor::touch() { } else i--; } - sort(VAL); + if (EXCEPT > 0) { + sort(VAL); + } double VALsum = 0; for (int i = EXCEPT;i < FREQUENCY - EXCEPT;i++) VALsum += VAL[i]; From dba8fe4ad0a8f1d0984f936ce8e66a1e9f311bf6 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 1 May 2025 18:12:25 +0200 Subject: [PATCH 4/7] Cleanup API. * configure the instance via constructor * configure pins in begin() * align variable names with README * avoid all caps --- FastCapacitiveSensor.cpp | 49 +++++++++++++++++++--------------------- FastCapacitiveSensor.h | 19 ++++++++-------- README.md | 24 ++++++++++---------- 3 files changed, 44 insertions(+), 48 deletions(-) diff --git a/FastCapacitiveSensor.cpp b/FastCapacitiveSensor.cpp index 1a43674..59babb2 100644 --- a/FastCapacitiveSensor.cpp +++ b/FastCapacitiveSensor.cpp @@ -1,7 +1,11 @@ #include "FastCapacitiveSensor.h" #include -FastCapacitiveSensor::FastCapacitiveSensor() { +FastCapacitiveSensor::FastCapacitiveSensor(int sendPin, int receivePin, int frequency, int breakThreshold, double 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) { @@ -18,46 +22,39 @@ static void sort(double* array) { swap(&array[j], &array[j - 1]); } -void FastCapacitiveSensor::begin(int send, int receive, int frequency, int breakthreshold, double exceptratio, int adcBits) { - SEND = send; - RECEIVE = receive; - FREQUENCY = frequency; - BREAKTHRESHOLD = breakthreshold; - EXCEPTRATIO = exceptratio; - ADCMAX = 1 << adcBits; - INPUTTHRESHOLD = ADCMAX * 0.9; - EXCEPT = FREQUENCY * EXCEPTRATIO; - USE = FREQUENCY - 2 * EXCEPT; +void FastCapacitiveSensor::begin() { + pinMode(sendPin, OUTPUT_OPENDRAIN); + pinMode(receivePin, INPUT); } double FastCapacitiveSensor::touch() { - double VAL[FREQUENCY]; + double values[numReads]; - for (int i = 0; i < FREQUENCY; i++) { + for (int i = 0; i < numReads; i++) { double val = 0; - digitalWrite(SEND, HIGH); + digitalWrite(sendPin, HIGH); unsigned long starttim = micros(); - while (analogRead(RECEIVE) < INPUTTHRESHOLD) { + while (analogRead(receivePin) < inputThreshold) { unsigned long t1 = micros() - starttim; - if (t1 > BREAKTHRESHOLD) { - int v1 = analogRead(RECEIVE); - val = t1 * log(1.0 - 0.9) / log(1.0 - ((double)v1 / (double)ADCMAX)); + if (t1 > breakThreshold) { + int v1 = analogRead(receivePin); + val = t1 * log(1.0 - 0.9) / log(1.0 - ((double)v1 / (double)adcmax)); break; } } - digitalWrite(SEND, LOW); + digitalWrite(sendPin, LOW); delayMicroseconds(10); if (val > 0) { - VAL[i] = val; + values[i] = val; } else i--; } - if (EXCEPT > 0) { - sort(VAL); + if (except > 0) { + sort(values); } - double VALsum = 0; - for (int i = EXCEPT;i < FREQUENCY - EXCEPT;i++) - VALsum += VAL[i]; - return VALsum / USE; + double sum = 0; + for (int i = except;i < numReads - except;i++) + sum += values[i]; + return sum / use; } \ No newline at end of file diff --git a/FastCapacitiveSensor.h b/FastCapacitiveSensor.h index 3f69bbd..c26b447 100644 --- a/FastCapacitiveSensor.h +++ b/FastCapacitiveSensor.h @@ -5,19 +5,18 @@ class FastCapacitiveSensor { public: - FastCapacitiveSensor(); - void begin(int send, int receive, int frequency, int breakthreshold, double exceptratio, int adcBits=10); + FastCapacitiveSensor(int sendPin, int receivePin, int numReads, int breakThreshold, double exceptRatio, int adcBits=10); + void begin(); double touch(); private: - int FREQUENCY; - int BREAKTHRESHOLD; - double EXCEPTRATIO; - int SEND; - int RECEIVE; - int ADCMAX; - double INPUTTHRESHOLD; - int EXCEPT, USE; + int numReads; + int breakThreshold; + double exceptRatio; + int sendPin, receivePin; + int adcmax; + double inputThreshold; + int except, use; }; #endif \ No newline at end of file diff --git a/README.md b/README.md index d4ffcc4..378fc71 100644 --- a/README.md +++ b/README.md @@ -45,30 +45,22 @@ See also example program. #include ``` -### 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, adcBits); +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$. @@ -76,6 +68,14 @@ excludeRatio is the ratio of exclusion of sensed values. Must be larger than or 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++ From 8633022030307f9fe8ee3f6cbbfce9075c70866d Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 1 May 2025 18:21:06 +0200 Subject: [PATCH 5/7] Another API revamp. * change all math to float, this is sufficient and faster. * check return value of touch() to unsingled long to align with e.g. millis() --- FastCapacitiveSensor.cpp | 22 +++++++++++----------- FastCapacitiveSensor.h | 8 ++++---- README.md | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/FastCapacitiveSensor.cpp b/FastCapacitiveSensor.cpp index 59babb2..909f5b4 100644 --- a/FastCapacitiveSensor.cpp +++ b/FastCapacitiveSensor.cpp @@ -1,21 +1,21 @@ #include "FastCapacitiveSensor.h" #include -FastCapacitiveSensor::FastCapacitiveSensor(int sendPin, int receivePin, int frequency, int breakThreshold, double exceptRatio, int adcBits) : sendPin(sendPin), receivePin(receivePin), numReads(frequency), breakThreshold(breakThreshold), exceptRatio(exceptRatio) { +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]) @@ -27,18 +27,18 @@ void FastCapacitiveSensor::begin() { pinMode(receivePin, INPUT); } -double FastCapacitiveSensor::touch() { - double values[numReads]; +unsigned long FastCapacitiveSensor::touch() { + float values[numReads]; for (int i = 0; i < numReads; i++) { - double val = 0; + float val = 0; digitalWrite(sendPin, HIGH); unsigned long starttim = micros(); while (analogRead(receivePin) < inputThreshold) { unsigned long t1 = micros() - starttim; if (t1 > breakThreshold) { int v1 = analogRead(receivePin); - val = t1 * log(1.0 - 0.9) / log(1.0 - ((double)v1 / (double)adcmax)); + val = t1 * logf(1.0 - 0.9) / logf(1.0 - ((float)v1 / (float)adcmax)); break; } } @@ -53,8 +53,8 @@ double FastCapacitiveSensor::touch() { if (except > 0) { sort(values); } - double sum = 0; + float sum = 0; for (int i = except;i < numReads - except;i++) sum += values[i]; - return sum / use; + return (unsigned long)(sum / use); } \ No newline at end of file diff --git a/FastCapacitiveSensor.h b/FastCapacitiveSensor.h index c26b447..777b2a3 100644 --- a/FastCapacitiveSensor.h +++ b/FastCapacitiveSensor.h @@ -5,17 +5,17 @@ class FastCapacitiveSensor { public: - FastCapacitiveSensor(int sendPin, int receivePin, int numReads, int breakThreshold, double exceptRatio, int adcBits=10); + FastCapacitiveSensor(int sendPin, int receivePin, int numReads, int breakThreshold, float exceptRatio, int adcBits=10); void begin(); - double touch(); + unsigned long touch(); private: int numReads; int breakThreshold; - double exceptRatio; + float exceptRatio; int sendPin, receivePin; int adcmax; - double inputThreshold; + float inputThreshold; int except, use; }; diff --git a/README.md b/README.md index 378fc71..279f4ff 100644 --- a/README.md +++ b/README.md @@ -82,4 +82,4 @@ This will configure the pin-modes. 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`. From ec926f64fe0e8ed456073e1b0146aea79474d9fc Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 1 May 2025 19:07:55 +0200 Subject: [PATCH 6/7] Add a comment for the double read. --- FastCapacitiveSensor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/FastCapacitiveSensor.cpp b/FastCapacitiveSensor.cpp index 909f5b4..b65b8e0 100644 --- a/FastCapacitiveSensor.cpp +++ b/FastCapacitiveSensor.cpp @@ -37,6 +37,7 @@ unsigned long FastCapacitiveSensor::touch() { 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; From 3f27224b623dc3b21e59396f78c993b2d3e5a1c1 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 1 May 2025 19:10:44 +0200 Subject: [PATCH 7/7] Update example sketch. --- .../FastCapacitiveSensor/FastCapacitiveSensor.ino | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/FastCapacitiveSensor/FastCapacitiveSensor.ino b/examples/FastCapacitiveSensor/FastCapacitiveSensor.ino index 6ba83f5..4ef64b6 100644 --- a/examples/FastCapacitiveSensor/FastCapacitiveSensor.ino +++ b/examples/FastCapacitiveSensor/FastCapacitiveSensor.ino @@ -1,15 +1,13 @@ #include -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() {