Closed
Description
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 commentedon Jan 4, 2022
@mahesh2000 Thanks for your contribution. Your request is specific and explained into details. Did you consider sending Pull Request directly?
mahesh2000 commentedon Jan 4, 2022
@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 commentedon Jan 4, 2022
You can take a look on Contribution Guide.
Nevermind, we will take o look on your issue/proposal and consider if it's useful.
SuGlider commentedon Jan 24, 2022
@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 commentedon Jan 24, 2022
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 commentedon Jan 24, 2022
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 commentedon Jan 24, 2022
The General Touch API will be as follow (last one is your suggestion):
Touch Sensor IDF Refactoring (#6194)
update 04022022 (#16)