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
123 changes: 71 additions & 52 deletions CapacitiveSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,34 @@ 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;
if (error < 0) return -1; // bad pin


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");
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
11 changes: 8 additions & 3 deletions CapacitiveSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,20 @@ 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
{
// user-accessible "public" interface
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);
Expand All @@ -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