diff --git a/CapacitiveSensor.cpp b/CapacitiveSensor.cpp index 7128416..cf19412 100644 --- a/CapacitiveSensor.cpp +++ b/CapacitiveSensor.cpp @@ -74,10 +74,20 @@ 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 -long CapacitiveSensor::capacitiveSensor(uint8_t samples) +long CapacitiveSensor::capacitiveSensor(uint8_t samples, char dir) { total = 0; if (samples == 0) return 0; @@ -85,13 +95,13 @@ 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 // 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"); @@ -122,14 +132,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 +161,62 @@ 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 +#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); + 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(); +#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) + 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 b557a33..abbd1a6 100644 --- a/CapacitiveSensor.h +++ b/CapacitiveSensor.h @@ -392,6 +392,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 { @@ -399,8 +404,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); @@ -419,7 +424,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