From 64c8ec5e82fe1fad8926b5613f5cf703e29cc8fe Mon Sep 17 00:00:00 2001 From: Vovodroid Date: Tue, 13 Mar 2018 14:28:40 +0200 Subject: [PATCH 1/3] Configure sense for each direction (UP and DOWN) --- CapacitiveSensor.cpp | 107 ++++++++++++++++++++++--------------------- CapacitiveSensor.h | 11 +++-- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/CapacitiveSensor.cpp b/CapacitiveSensor.cpp index 7128416..1f676cf 100644 --- a/CapacitiveSensor.cpp +++ b/CapacitiveSensor.cpp @@ -77,7 +77,7 @@ CapacitiveSensor::CapacitiveSensor(uint8_t sendPin, uint8_t receivePin) // Public Methods ////////////////////////////////////////////////////////////// // Functions available in Wiring sketches, this library, and other libraries -long CapacitiveSensor::capacitiveSensor(uint8_t samples) +long CapacitiveSensor::capacitiveSensor(uint8_t samples, char dir) { total = 0; if (samples == 0) return 0; @@ -85,7 +85,7 @@ long CapacitiveSensor::capacitiveSensor(uint8_t samples) for (uint8_t i = 0; i < samples; i++) { // loop for samples parameter - simple lowpass filter - if (SenseOneCycle() < 0) return -2; // variable over timeout + if (SenseOneCycle(dir) < 0) return -2; // variable over timeout } // only calibrate if time is greater than CS_AutocaL_Millis and total is less than 10% of baseline @@ -122,14 +122,14 @@ long CapacitiveSensor::capacitiveSensor(uint8_t samples) } -long CapacitiveSensor::capacitiveSensorRaw(uint8_t samples) +long CapacitiveSensor::capacitiveSensorRaw(uint8_t samples, char dir) { total = 0; if (samples == 0) return 0; if (error < 0) return -1; // bad pin - this appears not to work for (uint8_t i = 0; i < samples; i++) { // loop for samples parameter - simple lowpass filter - if (SenseOneCycle() < 0) return -2; // variable over timeout + if (SenseOneCycle(dir) < 0) return -2; // variable over timeout } return total; @@ -151,53 +151,58 @@ void CapacitiveSensor::set_CS_Timeout_Millis(unsigned long timeout_millis){ // Private Methods ///////////////////////////////////////////////////////////// // Functions only available to other functions in this library -int CapacitiveSensor::SenseOneCycle(void) +int CapacitiveSensor::SenseOneCycle(char dir) { + if (dir & UP){ noInterrupts(); - DIRECT_WRITE_LOW(sReg, sBit); // sendPin Register low - DIRECT_MODE_INPUT(rReg, rBit); // receivePin to input (pullups are off) - DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT - DIRECT_WRITE_LOW(rReg, rBit); // pin is now LOW AND OUTPUT - delayMicroseconds(10); - DIRECT_MODE_INPUT(rReg, rBit); // receivePin to input (pullups are off) - DIRECT_WRITE_HIGH(sReg, sBit); // sendPin High - interrupts(); - - while ( !DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) { // while receive pin is LOW AND total is positive value - total++; - } - //Serial.print("SenseOneCycle(1): "); - //Serial.println(total); - - if (total > CS_Timeout_Millis) { - return -2; // total variable over timeout - } - - // set receive pin HIGH briefly to charge up fully - because the while loop above will exit when pin is ~ 2.5V - noInterrupts(); - DIRECT_WRITE_HIGH(rReg, rBit); - DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT - pin is now HIGH AND OUTPUT - DIRECT_WRITE_HIGH(rReg, rBit); - DIRECT_MODE_INPUT(rReg, rBit); // receivePin to INPUT (pullup is off) - DIRECT_WRITE_LOW(sReg, sBit); // sendPin LOW - interrupts(); - -#ifdef FIVE_VOLT_TOLERANCE_WORKAROUND - DIRECT_MODE_OUTPUT(rReg, rBit); - DIRECT_WRITE_LOW(rReg, rBit); - delayMicroseconds(10); - DIRECT_MODE_INPUT(rReg, rBit); // receivePin to INPUT (pullup is off) -#else - while ( DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) { // while receive pin is HIGH AND total is less than timeout - total++; - } -#endif - //Serial.print("SenseOneCycle(2): "); - //Serial.println(total); - - if (total >= CS_Timeout_Millis) { - return -2; // total variable over timeout - } else { - return 1; - } + DIRECT_WRITE_LOW(sReg, sBit); // sendPin Register low + DIRECT_MODE_INPUT(rReg, rBit); // receivePin to input (pullups are off) + DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT + DIRECT_WRITE_LOW(rReg, rBit); // pin is now LOW AND OUTPUT + delayMicroseconds(10); + DIRECT_MODE_INPUT(rReg, rBit); // receivePin to input (pullups are off) + DIRECT_WRITE_HIGH(sReg, sBit); // sendPin High + interrupts(); + + while ( !DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) { // while receive pin is LOW AND total is positive value + total++; + } + //Serial.print("SenseOneCycle(UP): "); Serial.println(total); + + + if (total > CS_Timeout_Millis) { + return -2; // total variable over timeout + } + } + + if (dir & DOWN){ + unsigned long total1 = total; + // set receive pin HIGH briefly to charge up fully - because the while loop above will exit when pin is ~ 2.5V + noInterrupts(); + DIRECT_WRITE_HIGH(rReg, rBit); + DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT - pin is now HIGH AND OUTPUT + DIRECT_WRITE_HIGH(rReg, rBit); + DIRECT_MODE_INPUT(rReg, rBit); // receivePin to INPUT (pullup is off) + DIRECT_WRITE_LOW(sReg, sBit); // sendPin LOW + interrupts(); + + #ifdef FIVE_VOLT_TOLERANCE_WORKAROUND + DIRECT_MODE_OUTPUT(rReg, rBit); + DIRECT_WRITE_LOW(rReg, rBit); + delayMicroseconds(10); + DIRECT_MODE_INPUT(rReg, rBit); // receivePin to INPUT (pullup is off) + #else + while ( DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) { // while receive pin is HIGH AND total is less than timeout + total++; + } + #endif + //Serial.print("SenseOneCycle(DN): "); Serial.println(total - total1); + + if (total >= CS_Timeout_Millis) { + return -2; // total variable over timeout + } else { + return 1; + } + }else + return 1; } diff --git a/CapacitiveSensor.h b/CapacitiveSensor.h index 78aed3e..2083ac7 100644 --- a/CapacitiveSensor.h +++ b/CapacitiveSensor.h @@ -214,6 +214,11 @@ void directWriteHigh(volatile IO_REG_TYPE *base, IO_REG_TYPE pin) #define FIVE_VOLT_TOLERANCE_WORKAROUND #endif + +#define UP 1 +#define DOWN 2 +#define BOTH (UP | DOWN) + // library interface description class CapacitiveSensor { @@ -221,8 +226,8 @@ class CapacitiveSensor public: // methods CapacitiveSensor(uint8_t sendPin, uint8_t receivePin); - long capacitiveSensorRaw(uint8_t samples); - long capacitiveSensor(uint8_t samples); + long capacitiveSensorRaw(uint8_t samples, char dir = BOTH); + long capacitiveSensor(uint8_t samples, char dir = BOTH); void set_CS_Timeout_Millis(unsigned long timeout_millis); void reset_CS_AutoCal(); void set_CS_AutocaL_Millis(unsigned long autoCal_millis); @@ -241,7 +246,7 @@ class CapacitiveSensor IO_REG_TYPE rBit; // receive pin's ports and bitmask volatile IO_REG_TYPE *rReg; // methods - int SenseOneCycle(void); + int SenseOneCycle(char dir); }; #endif From 8f7e94bc8d3f0008c8c92a117ae98b440eda13dc Mon Sep 17 00:00:00 2001 From: Aurelien BOUIN Date: Wed, 1 Dec 2021 12:41:02 +0100 Subject: [PATCH 2/3] Avoid error: call of overloaded 'abs(long unsigned int)' is ambiguous when compiling for stm32 --- CapacitiveSensor.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CapacitiveSensor.cpp b/CapacitiveSensor.cpp index 7128416..5eb780d 100644 --- a/CapacitiveSensor.cpp +++ b/CapacitiveSensor.cpp @@ -74,6 +74,16 @@ CapacitiveSensor::CapacitiveSensor(uint8_t sendPin, uint8_t receivePin) lastCal = millis(); // set millis for start } +//Avoid error: call of overloaded 'abs(long unsigned int)' is ambiguous when compiling for stm32 +unsigned long safediffabs(unsigned long one, unsigned long two) +{ + if(one > two) + { + return (one - two); + } + return (two - one); +} + // Public Methods ////////////////////////////////////////////////////////////// // Functions available in Wiring sketches, this library, and other libraries @@ -91,7 +101,7 @@ long CapacitiveSensor::capacitiveSensor(uint8_t samples) // only calibrate if time is greater than CS_AutocaL_Millis and total is less than 10% of baseline // this is an attempt to keep from calibrating when the sensor is seeing a "touched" signal - if ( (millis() - lastCal > CS_AutocaL_Millis) && abs(total - leastTotal) < (int)(.10 * (float)leastTotal) ) { + if ( (millis() - lastCal > CS_AutocaL_Millis) && safediffabs(total, leastTotal) < (int)(.10 * (float)leastTotal) ) { // Serial.println(); // debugging // Serial.println("auto-calibrate"); From f6bce37f2ce58d43d6090a6c9038cd08244335cb Mon Sep 17 00:00:00 2001 From: Aurelien BOUIN Date: Mon, 3 Jan 2022 17:47:47 +0100 Subject: [PATCH 3/3] Define USE_INPUT_PULLUP_FOR_HALF_CYCLE if setting pullup on io (default : undefined) --- CapacitiveSensor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CapacitiveSensor.cpp b/CapacitiveSensor.cpp index 60cd90e..cf19412 100644 --- a/CapacitiveSensor.cpp +++ b/CapacitiveSensor.cpp @@ -166,7 +166,9 @@ int CapacitiveSensor::SenseOneCycle(char dir) if (dir & UP){ noInterrupts(); DIRECT_WRITE_LOW(sReg, sBit); // sendPin Register low +#if USE_INPUT_PULLUP_FOR_HALF_CYCLE DIRECT_MODE_INPUT(rReg, rBit); // receivePin to input (pullups are off) +#endif /* USE_INPUT_PULLUP_FOR_HALF_CYCLE */ DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT DIRECT_WRITE_LOW(rReg, rBit); // pin is now LOW AND OUTPUT delayMicroseconds(10); @@ -189,7 +191,9 @@ int CapacitiveSensor::SenseOneCycle(char dir) unsigned long total1 = total; // set receive pin HIGH briefly to charge up fully - because the while loop above will exit when pin is ~ 2.5V noInterrupts(); +#if USE_INPUT_PULLUP_FOR_HALF_CYCLE DIRECT_WRITE_HIGH(rReg, rBit); +#endif /* USE_INPUT_PULLUP_FOR_HALF_CYCLE */ DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT - pin is now HIGH AND OUTPUT DIRECT_WRITE_HIGH(rReg, rBit); DIRECT_MODE_INPUT(rReg, rBit); // receivePin to INPUT (pullup is off)