Skip to content

Allow trigger to be above or below threshold #6095

Closed
@mahesh2000

Description

@mahesh2000

Related area

ESP32 touch pins

Hardware specification

ESP32

Is your feature request related to a problem?

Please allow trigger to be above or below threshold. Right now, only values smaller than the threshold will trigger. The code below will solve the problem.

Describe the solution you'd like

Essentially, the following code changes will do it:

// 24: SENS_TOUCH_OUT_SEL 1: the touch pad is considered touched when the value of the counter is greater than the threshold, 0: the touch pad is considered touched when the value of the counter is less than the threshold. (R/W)
if (threshold_above == 1) {	// trigger when touch reading is BELOW the threshold
	CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
} else	{// trigger when touch reading is ABOVE the threshold
	SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
}

How to use:

  setThresholdDirection(0); // trigger if threshold below value. 0 = false, 1 = true
  touchAttachInterrupt(T0, callback, Threshold);  //Setup interrupt on Touch Pad 0 (GPIO4)

In detail:

add to cores\esp32\esp32-hal-touch.h the following:


/**
 * set if trigger will be when value goes above or below threshold. 
 */
void setThresholdDirection(uint8_t above);

Change cores\esp32\esp32-hal-touch.c as follows:

/**
 * above = 0 means false, = anything else means true.
 */
uint32_t threshold_above = 1;

/**
 * above = 0 means anything below threshold will trigger, anything else means threshold ABOVE will trigger.
 */
void __setThresholdDirection(uint8_t above) {
  if (above == 0) {
    threshold_above = 0;
  } else
    threshold_above = 1;
}

void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold)
{
    int8_t pad = digitalPinToTouchChannel(pin);
    if(pad < 0){
        return;
    }

    pinMode(pin, ANALOG);

    __touchInit();

    __touchInterruptHandlers[pad] = userFunc;

    //clear touch force ,select the Touch mode is Timer
    CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);

    // 24: SENS_TOUCH_OUT_SEL 1: the touch pad is considered touched when the value of the counter is greater than the threshold, 0: the touch pad is considered touched when the value of the counter is less than the threshold. (R/W)
    if (threshold_above == 1) { // trigger when touch reading is BELOW the threshold
      CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
    } else  {// trigger when touch reading is ABOVE the threshold
      SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
    }
    //Intr will give ,when SET0 < threshold
    SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_1EN);
    //Enable Rtc Touch Module Intr,the Interrupt need Rtc out  Enable
    SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA);

    //set threshold
    uint8_t shift = (pad & 1) ? SENS_TOUCH_OUT_TH1_S : SENS_TOUCH_OUT_TH0_S;
    SET_PERI_REG_BITS((SENS_SAR_TOUCH_THRES1_REG + (pad / 2) * 4), SENS_TOUCH_OUT_TH0, threshold, shift);

    uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
    WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
                      & ~(RTC_IO_TOUCH_PAD0_DAC_M))
                      | (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
                      | RTC_IO_TOUCH_PAD0_TIE_OPT_M   //Enable Tie,Init Level
                      | RTC_IO_TOUCH_PAD0_START_M     //Enable Touch Pad IO
                      | RTC_IO_TOUCH_PAD0_XPD_M);     //Enable Touch Pad Power on

    //Enable Digital rtc control :work mode and out mode
    SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG,
                      (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)) | \
                      (1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | \
                      (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S)));
}

extern void setThresholdDirection(uint8_t) __attribute__ ((weak, alias("__setThresholdDirection")));

Describe alternatives you've considered

Tried setting the SENS_TOUCH_OUT_SEL value separately but it was quite messy.

Additional context

No response

Activity

VojtechBartoska

VojtechBartoska commented on Jan 4, 2022

@VojtechBartoska
Contributor

@mahesh2000 Thanks for your contribution. Your request is specific and explained into details. Did you consider sending Pull Request directly?

mahesh2000

mahesh2000 commented on Jan 4, 2022

@mahesh2000
Author

@mahesh2000 Thanks for your contribution. Your request is specific and explained into details. Did you consider sending Pull Request directly?

@VojtechBartoska, I don't quite know how to do that and I'm not so sure whether this is useful enough for anyone else.

VojtechBartoska

VojtechBartoska commented on Jan 4, 2022

@VojtechBartoska
Contributor

You can take a look on Contribution Guide.

Nevermind, we will take o look on your issue/proposal and consider if it's useful.

self-assigned this
on Jan 7, 2022
SuGlider

SuGlider commented on Jan 24, 2022

@SuGlider
Collaborator

@mahesh2000
Please help me to understand your suggestion.
ESP32 works by calculating a threshold that will identify when a pin is touched.

In normal operation, let's say, the value read on the pin is 100.
When touched it will go to 10, for instance.
Thus we set a threshold of 40, in order to identify when it goes below this value and we know it is touched.

It will never go over 100, because it is the upper limit.
What would be the practical usage of the feature you propose?
Let me know how would you use this new feature.
Thanks!

mahesh2000

mahesh2000 commented on Jan 24, 2022

@mahesh2000
Author

Hi, one use case of this feature is to detect when a trigger button on a joystick is released, rather than polling the pin. The ESP32 provides this functionality already, so it's not difficult to expose it in the API. I don't need a change to the library myself anymore because I've modified its files for my own use.

Hope this helps.

SuGlider

SuGlider commented on Jan 24, 2022

@SuGlider
Collaborator

Thanks @mahesh2000
One thing to notice is that, in order to make it work as intended, the application would need to change "the direction" and the threshold every time the ISR is activated.

Is this behavior that you are looking for?

Another relevant fact is that we are about to publish a new code for the Touch Library.
Everything will be IDF 4.4 based.
Maybe we could provide some example that helps in this matter using IDF calls.

SuGlider

SuGlider commented on Jan 24, 2022

@SuGlider
Collaborator

The General Touch API will be as follow (last one is your suggestion):

/*
 * Set cycles that measurement operation takes
 * The result from touchRead, threshold and detection
 * accuracy depend on these values. Defaults are
 * 0x1000 for measure and 0x1000 for sleep.
 * With default values touchRead takes 0.5ms
 * */
void touchSetCycles(uint16_t measure, uint16_t sleep);

/*
 * Read touch pad (values close to 0 mean touch detected)
 * You can use this method to chose a good threshold value
 * to use as value for touchAttachInterrupt
 * */
uint32_t touchRead(uint8_t pin);

/*
 * Set function to be called if touch pad value falls (ESP32)
 * below the given threshold / rises (ESP32-S2/S3) by given increment (threshold). 
 * Use touchRead to determine a proper threshold between touched and untouched state
 * */
void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint32_t threshold);
void touchAttachInterruptArg(uint8_t pin, void (*userFunc)(void*), void *arg, uint32_t threshold);
void touchDetachInterrupt(uint8_t pin);

/*
 * Specific functions to ESP32 
 * Tells the dirver if it shall activate the ISR if the sensor is Lower or Higher than the Threshold
 * Default if Lower.
 **/
void touchInterruptSetThresholdDirection(bool mustbeLower);
added a commit that references this issue on Feb 3, 2022
0ea485e
added a commit that references this issue on Feb 4, 2022
2be27a3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @mahesh2000@SuGlider@VojtechBartoska

    Issue actions

      Allow trigger to be above or below threshold · Issue #6095 · espressif/arduino-esp32