This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Cap sense using single pin per sensor

Hi,

  I'm using the nRF52840 dev kit for a BLE-based application.  I need to implement a capacitive touch button for detecting button presses and releases (no sliding).  I only have 1 analog input pin connected to my sensor.  I've looked at the nrf52-capsense-example project here, but it is based on SDK-12. 

  Is this still the recommended method to follow when only a single pin is connected to the touch sensor?

  Are there any issues using this method along with BLE (SoftDevice S140)?

  Is there any way to use the csense library in this configuration?

  Thanks...

Brian

Parents
  • Yes, you can use a single pin for capacitive sensing. The trick is to first use the pin to charge (or discharge, depending on whether the capacitive sensor is between pin and Gnd or pin and Vcc). Then turn the pin around to an analogue input and measure the decaying falling (rising) voltage which will be at a rate controlled by capacitance and resistance. Something like this, in this case assuming a capacitor connected to Gnd and Vcc via a charging resistor:

    #define CAPSENSE_PIN 5
      // Number of samples depends on how accurate the rising CR curve should be measured
      int16_t CapCharge[50];
    
      // Get ready to discharge the cap
      nrf_gpio_pin_clear(CAPSENSE_PIN);
      // Discharge cap
      nrf_gpio_cfg(CAPSENSE_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0S1, NRF_GPIO_PIN_NOSENSE);
      // Wait long enough for cap to discharge
      nrf_delay_us(20);
      // Turn around to analogue input to read the charging voltage
      nrf_gpio_cfg(CAPSENSE_PIN, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
      for (uint32_t i = 0; i < sizeof(CapCharge) / sizeof(CapCharge[0]); i++)
      {
        CapCharge[i] = SAADC_Measure(CAPSENSE_PIN);
        // Experiment with number of samples and delay between each, depends on CFR
        nrf_delay_us(50);
      }

    You can use SAADC pull-up (160k-ish) as a charging resistor if you want to save a component and use only a capacitor; accuracy in that case  is low but often good enough discrimination of movement. Values of C and R depend on sensitivity and response time; C is not a real capacitor in most cases, just a foil contact in the case of a touch sensor. Now that is what I'd call a zero component capacitive sensor, no C or R.

    I should add that you can just compare the voltage with a comparator instead of the SAADC, or even rely on the ill-defined logic high input level on an i/o pin in input mode feeding a timer if simple presence/absense is required, and not an more precise measurement. SAADC or comparator should be in ratiometric mode, if charging voltage is Vcc then reference should also be Vcc and not a fixed reference.

Reply
  • Yes, you can use a single pin for capacitive sensing. The trick is to first use the pin to charge (or discharge, depending on whether the capacitive sensor is between pin and Gnd or pin and Vcc). Then turn the pin around to an analogue input and measure the decaying falling (rising) voltage which will be at a rate controlled by capacitance and resistance. Something like this, in this case assuming a capacitor connected to Gnd and Vcc via a charging resistor:

    #define CAPSENSE_PIN 5
      // Number of samples depends on how accurate the rising CR curve should be measured
      int16_t CapCharge[50];
    
      // Get ready to discharge the cap
      nrf_gpio_pin_clear(CAPSENSE_PIN);
      // Discharge cap
      nrf_gpio_cfg(CAPSENSE_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0S1, NRF_GPIO_PIN_NOSENSE);
      // Wait long enough for cap to discharge
      nrf_delay_us(20);
      // Turn around to analogue input to read the charging voltage
      nrf_gpio_cfg(CAPSENSE_PIN, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
      for (uint32_t i = 0; i < sizeof(CapCharge) / sizeof(CapCharge[0]); i++)
      {
        CapCharge[i] = SAADC_Measure(CAPSENSE_PIN);
        // Experiment with number of samples and delay between each, depends on CFR
        nrf_delay_us(50);
      }

    You can use SAADC pull-up (160k-ish) as a charging resistor if you want to save a component and use only a capacitor; accuracy in that case  is low but often good enough discrimination of movement. Values of C and R depend on sensitivity and response time; C is not a real capacitor in most cases, just a foil contact in the case of a touch sensor. Now that is what I'd call a zero component capacitive sensor, no C or R.

    I should add that you can just compare the voltage with a comparator instead of the SAADC, or even rely on the ill-defined logic high input level on an i/o pin in input mode feeding a timer if simple presence/absense is required, and not an more precise measurement. SAADC or comparator should be in ratiometric mode, if charging voltage is Vcc then reference should also be Vcc and not a fixed reference.

Children
No Data
Related