Skip to content

Instantly share code, notes, and snippets.

@andysheen
Last active February 26, 2019 09:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andysheen/b187ffe3bde57e5828074286f701c49d to your computer and use it in GitHub Desktop.
Save andysheen/b187ffe3bde57e5828074286f701c49d to your computer and use it in GitHub Desktop.
int led1 = 10;
int led2 = 9;
int cap1_threshold = 2;
int cap2_threshold = 2;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
Serial.begin(115200);
}
void loop() {
int cap1 = readCapacitivePin(3);
int cap2 = readCapacitivePin(4);
if (cap1 > cap1_threshold) {
digitalWrite(led1, 1);
} else {
digitalWrite(led1, 0);
}
if (cap2 > cap2_threshold) {
digitalWrite(led2, cap2);
} else {
digitalWrite(led2, 0);
}
Serial.println(cap1);
Serial.println();
Serial.println(cap2);
Serial.println();
delay(50);
}
uint8_t readCapacitivePin(int pinToMeasure) {
// Variables used to translate from Arduino to AVR pin naming
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
// Here we translate the input pin number from
// Arduino pin number to the AVR PORT, PIN, DDR,
// and which bit of those registers we care about.
byte bitmask;
port = portOutputRegister(digitalPinToPort(pinToMeasure));
ddr = portModeRegister(digitalPinToPort(pinToMeasure));
bitmask = digitalPinToBitMask(pinToMeasure);
pin = portInputRegister(digitalPinToPort(pinToMeasure));
// Discharge the pin first by setting it low and output
*port &= ~(bitmask);
*ddr |= bitmask;
delay(1);
uint8_t SREG_old = SREG; //back up the AVR Status Register
// Prevent the timer IRQ from disturbing our measurement
noInterrupts();
// Make the pin an input with the internal pull-up on
*ddr &= ~(bitmask);
*port |= bitmask;
// Now see how long the pin to get pulled up. This manual unrolling of the loop
// decreases the number of hardware cycles between each read of the pin,
// thus increasing sensitivity.
uint8_t cycles = 17;
if (*pin & bitmask) {
cycles = 0;
}
else if (*pin & bitmask) {
cycles = 1;
}
else if (*pin & bitmask) {
cycles = 2;
}
else if (*pin & bitmask) {
cycles = 3;
}
else if (*pin & bitmask) {
cycles = 4;
}
else if (*pin & bitmask) {
cycles = 5;
}
else if (*pin & bitmask) {
cycles = 6;
}
else if (*pin & bitmask) {
cycles = 7;
}
else if (*pin & bitmask) {
cycles = 8;
}
else if (*pin & bitmask) {
cycles = 9;
}
else if (*pin & bitmask) {
cycles = 10;
}
else if (*pin & bitmask) {
cycles = 11;
}
else if (*pin & bitmask) {
cycles = 12;
}
else if (*pin & bitmask) {
cycles = 13;
}
else if (*pin & bitmask) {
cycles = 14;
}
else if (*pin & bitmask) {
cycles = 15;
}
else if (*pin & bitmask) {
cycles = 16;
}
// End of timing-critical section; turn interrupts back on if they were on before, or leave them off if they were off before
SREG = SREG_old;
// Discharge the pin again by setting it low and output
// It's important to leave the pins low if you want to
// be able to touch more than 1 sensor at a time - if
// the sensor is left pulled high, when you touch
// two sensors, your body will transfer the charge between
// sensors.
*port &= ~(bitmask);
*ddr |= bitmask;
return cycles;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment