Open trullock opened 1 month ago
Hi @trullock,
This is how I might approach that:
#define TOUCH_DETECT_HOLD_TIMEOUT_MS 5000 /* If the touchpad is held for this long, assume a false reading and exit. */
#define TOUCH_DETECT_IDLE_TIMEOUT_MS 1000 /* Timeout between consecutive touches. If the next touch doesn't arrive in this time after the last release, then exit. */
#define TOUCH_DETECT_DEBOUNCE_MS 50 /* Touch readings may be noisy as the user's finger settles on the pad. Delay for this duration when a touch or release event occurs. */
#define TOUCH_DETECT_THRESHOLD 3000 /* Value from the touch sensor to interpret as a touch (<) vs release (>=) */
#define TOUCH_DETECT_COUNT 5 /* Number of touches required to wake SoC. */
enum {
LBL_NEW_TOUCH_DETECTED,
LBL_WAIT_RELEASE,
LBL_RELEASED,
LBL_WAIT_NEXT_TOUCH,
LBL_WAKE,
LBL_HALT,
};
const ulp_insn_t program[] = {
// The stage register will be used to keep count of the number of touches. Reset counter to 0.
I_STAGE_RST(),
// Check if touched. Go straight back to sleep if not.
M_TOUCH_BEGIN(),
M_TOUCH_WAIT_DONE(),
I_TOUCH_GET_GPIO_VALUE(GPIO_NUM_2),
M_BGE(LBL_HALT, TOUCH_DETECT_THRESHOLD),
M_LABEL(LBL_NEW_TOUCH_DETECTED),
/* TOUCHED */
// Increment the counter. If it has reached TOUCH_DETECT_COUNT then wake the SoC.
I_STAGE_INC(1),
M_BSGE(LBL_WAKE, TOUCH_DETECT_COUNT),
M_DELAY_MS_20_60000(TOUCH_DETECT_DEBOUNCE_MS), // Careful to avoid macros that might clobber the stage register. This one uses R0 so it's ok to use.
// This block waits for a release event or hold timeout.
M_UPDATE_TICKS(),
I_RD_TICKS(TOUCH_DETECT_HOLD_TIMEOUT_MS),
I_MOVR(R1, R0),
M_LABEL(LBL_WAIT_RELEASE),
M_TOUCH_BEGIN(),
M_TOUCH_WAIT_DONE(),
I_TOUCH_GET_GPIO_VALUE(GPIO_NUM_2),
M_BGE(LBL_RELEASED, TOUCH_DETECT_THRESHOLD),
M_UPDATE_TICKS(),
I_RD_TICKS(TOUCH_DETECT_HOLD_TIMEOUT_MS),
I_SUBR(R0, R0, R1),
M_BGE(LBL_HALT, hulp_ms_to_ulp_ticks((TOUCH_DETECT_HOLD_TIMEOUT_MS))),
M_BX(LBL_WAIT_RELEASE),
M_LABEL(LBL_RELEASED),
/* RELEASED */
M_DELAY_MS_20_60000(TOUCH_DETECT_DEBOUNCE_MS),
// And this block waits for the next touch event or idle timeout.
M_UPDATE_TICKS(),
I_RD_TICKS(TOUCH_DETECT_IDLE_TIMEOUT_MS),
I_MOVR(R1, R0),
M_LABEL(LBL_WAIT_NEXT_TOUCH),
M_TOUCH_BEGIN(),
M_TOUCH_WAIT_DONE(),
I_TOUCH_GET_GPIO_VALUE(GPIO_NUM_2),
M_BL(LBL_NEW_TOUCH_DETECTED, TOUCH_DETECT_THRESHOLD),
M_UPDATE_TICKS(),
I_RD_TICKS(TOUCH_DETECT_IDLE_TIMEOUT_MS),
I_SUBR(R0, R0, R1),
M_BGE(LBL_HALT, hulp_ms_to_ulp_ticks((TOUCH_DETECT_IDLE_TIMEOUT_MS))),
M_BX(LBL_WAIT_NEXT_TOUCH),
M_LABEL(LBL_WAKE),
I_WAKE(),
M_LABEL(LBL_HALT),
I_HALT(),
};
It's not tested, optimised, etc but should get you pretty close to what you want.
This is absolutely spot on, thank you so much for your generous help.
Thanks for this awesome library
I've got stuck with one problem, I'm hoping you can help me
I want to use capacitive touch to wake up from sleep, which I've implemented below. This all works great.
However, the nature of my project is that the physical touch event might be accidental, so I want to make it so the wake-up-touch-logic is smarter and looks for a more definitely deliberate touch interaction.
For example, I want to make it so the user has to touch the pin 5 times where each touch is within a second of the previous touch.
I've been looking at the button debouncing example as this code is probably very similar to what I need but I'm just not used to working at such a low level that I can't figure out the exact code :(
here's where I've got to that works and makes sense:
Thanks very much