Fully functional touch button support

This commit is contained in:
Hansi, dl9rdz 2019-05-25 10:49:26 +02:00
parent b3943aee31
commit 43807b613d
6 changed files with 71 additions and 43 deletions

View File

@ -46,17 +46,14 @@ enum KeyPress { KP_NONE = 0, KP_SHORT, KP_DOUBLE, KP_MID, KP_LONG };
struct Button { struct Button {
uint8_t pin; uint8_t pin;
uint32_t numberKeyPresses; uint32_t numberKeyPresses;
KeyPress pressed; KeyPress pressed;
unsigned long press_ts; unsigned long keydowTime;
boolean doublepress; bool doublepress;
bool isTouched; bool isTouched;
long touchTime;
}; };
Button button1 = {0, 0, KP_NONE, 0, false, false, 0}; Button button1 = {0, 0, KP_NONE, 0, false, false};
Button button2 = {0, 0, KP_NONE, 0, false, false, 0}; Button button2 = {0, 0, KP_NONE, 0, false, false};
static int lastDisplay = 1; static int lastDisplay = 1;
@ -415,6 +412,7 @@ struct st_configitems config_list[] = {
{"oled_rst", "OLED RST (needs reboot)", 0, &sonde.config.oled_rst}, {"oled_rst", "OLED RST (needs reboot)", 0, &sonde.config.oled_rst},
{"button_pin", "Button input port (needs reboot)", 0, &sonde.config.button_pin}, {"button_pin", "Button input port (needs reboot)", 0, &sonde.config.button_pin},
{"button2_pin", "Button 2 input port (needs reboot)", 0, &sonde.config.button2_pin}, {"button2_pin", "Button 2 input port (needs reboot)", 0, &sonde.config.button2_pin},
{"touch_thresh", "Touch button threshold (needs reboot)", 0, &sonde.config.touch_thresh},
{"led_pout", "LED output port (needs reboot)", 0, &sonde.config.led_pout}, {"led_pout", "LED output port (needs reboot)", 0, &sonde.config.led_pout},
}; };
const static int N_CONFIG = (sizeof(config_list) / sizeof(struct st_configitems)); const static int N_CONFIG = (sizeof(config_list) / sizeof(struct st_configitems));
@ -813,30 +811,41 @@ void initTouch() {
void IRAM_ATTR touchISR() { void IRAM_ATTR touchISR() {
if (!button1.isTouched) { if (!button1.isTouched) {
button1.touchTime = my_millis(); unsigned long now = my_millis();
if (now - button1.keydowTime < 500) button1.doublepress = true;
else button1.doublepress = false;
button1.keydowTime = now;
button1.isTouched = true; button1.isTouched = true;
} }
} }
void IRAM_ATTR touchISR2() { void IRAM_ATTR touchISR2() {
if (!button2.isTouched) { if (!button2.isTouched) {
button2.touchTime = my_millis(); unsigned long now = my_millis();
if (now - button2.keydowTime < 500) button2.doublepress = true;
else button2.doublepress = false;
button2.keydowTime = now;
button2.isTouched = true; button2.isTouched = true;
} }
} }
inline void IRAM_ATTR checkTouchButton(Button &button) { void IRAM_ATTR checkTouchButton(Button &button) {
if (button.isTouched) { if (button.isTouched) {
int tmp = touchRead(button.pin & 0x7f); int tmp = touchRead(button.pin & 0x7f);
// bad idea within ISR: Serial.printf("touchRead on pin %d is %d\n", button.pin, tmp); if (tmp > sonde.config.touch_thresh) {
if (tmp > 60) {
button.isTouched = false; button.isTouched = false;
// simulate key press unsigned long elapsed = my_millis() - button.keydowTime;
button.pressed = KP_SHORT; if (elapsed > 1500) {
} else { if (elapsed < 4000) {
if (my_millis() - button.touchTime > 3000) { button.pressed = KP_MID;
// long touch }
// ignore for now else {
button.pressed = KP_LONG;
}
} else if (button.doublepress) {
button.pressed = KP_DOUBLE;
} else {
button.pressed = KP_SHORT;
} }
} }
} }
@ -848,19 +857,18 @@ void IRAM_ATTR checkTouchStatus() {
} }
void IRAM_ATTR buttonISR() { void IRAM_ATTR buttonISR() {
unsigned long now = my_millis(); unsigned long now = my_millis();
if (digitalRead(button1.pin) == 0) { // Button down if (digitalRead(button1.pin) == 0) { // Button down
if (now - button1.press_ts < 500) { if (now - button1.keydowTime < 500) {
// Double press // Double press
button1.doublepress = true; button1.doublepress = true;
} else { } else {
button1.doublepress = false; button1.doublepress = false;
} }
button1.press_ts = now; button1.keydowTime = now;
} else { //Button up } else { //Button up
unsigned int elapsed = now - button1.press_ts; unsigned int elapsed = now - button1.keydowTime;
if (elapsed > 1500) { if (elapsed > 1500) {
if (elapsed < 4000) { if (elapsed < 4000) {
button1.pressed = KP_MID; button1.pressed = KP_MID;
@ -873,21 +881,21 @@ void IRAM_ATTR buttonISR() {
else button1.pressed = KP_SHORT; else button1.pressed = KP_SHORT;
} }
button1.numberKeyPresses += 1; button1.numberKeyPresses += 1;
button1.press_ts = now; button1.keydowTime = now;
} }
} }
int getKeyPress() { int getKeyPress() {
KeyPress p = button1.pressed; KeyPress p = button1.pressed;
button1.pressed = KP_NONE; button1.pressed = KP_NONE;
Serial.printf("button1 press: %d at %ld (%d)\n", p, button1.press_ts, button1.numberKeyPresses); //Serial.printf("button1 press: %d at %ld (%d)\n", p, button1.keydowTime, button1.numberKeyPresses);
return p; return p;
} }
int getKey2Press() { int getKey2Press() {
KeyPress p = button2.pressed; KeyPress p = button2.pressed;
button2.pressed = KP_NONE; button2.pressed = KP_NONE;
Serial.printf("button2 press: %d at %ld (%d)\n", p, button2.press_ts, button2.numberKeyPresses); //Serial.printf("button2 press: %d at %ld (%d)\n", p, button2.keydowTime, button2.numberKeyPresses);
return p; return p;
} }
int hasKeyPress() { int hasKeyPress() {
@ -897,12 +905,11 @@ int getKeyPressEvent() {
int p = getKeyPress(); int p = getKeyPress();
if (p == KP_NONE) { if (p == KP_NONE) {
p = getKey2Press(); p = getKey2Press();
if (p == KP_NONE) if (p == KP_NONE)
return EVT_NONE; return EVT_NONE;
return p+4; return p + 4;
} }
return p; /* map KP_x to EVT_KEY1_x */ return p; /* map KP_x to EVT_KEY1_x / EVT_KEY2_x*/
/* TODO: map touch event and second button */
} }
void setup() void setup()
@ -1066,6 +1073,17 @@ void enterMode(int mode) {
} }
} }
static char text[40];
static const char *action2text(int action) {
if (action == ACT_DISPLAY_DEFAULT) return "Default Display";
if (action == ACT_DISPLAY_SPECTRUM) return "Spectrum Display";
if (action == ACT_DISPLAY_WIFI) return "Wifi Scan Display";
if (action == ACT_NEXTSONDE) return "Go to next sonde";
if (action == ACT_PREVSONDE) return "presonde (not implemented)";
if (action == ACT_NONE) return "none";
snprintf(text, 40, "Display=%d", action);
return text;
}
void loopDecoder() { void loopDecoder() {
#if 0 #if 0
switch (getKeyPress()) { switch (getKeyPress()) {
@ -1091,13 +1109,14 @@ void loopDecoder() {
if (!event) event = sonde.timeoutEvent(); if (!event) event = sonde.timeoutEvent();
// Check if there is an action for this event // Check if there is an action for this event
int action = disp.layout->actions[event]; int action = disp.layout->actions[event];
Serial.printf("Loop: action is %d for event %s(%d)\n", action, EVENTNAME(event), event);
action = sonde.updateState(action);
Serial.printf("action is %d after updateState\n", action);
if (action >= 0) { if (action >= 0) {
if (action == ACT_DISPLAY_SPECTRUM) enterMode(ST_SPECTRUM); Serial.printf("Loop: triggering action %s (%d) for event %s (%d)\n", action2text(action), action, EVENTNAME(event), event);
else if (action == ACT_DISPLAY_WIFI) enterMode(ST_WIFISCAN); action = sonde.updateState(action);
return; if (action >= 0) {
if (action == ACT_DISPLAY_SPECTRUM) enterMode(ST_SPECTRUM);
else if (action == ACT_DISPLAY_WIFI) enterMode(ST_WIFISCAN);
return;
}
} }
// sonde knows the current type and frequency, and delegates to the right decoder // sonde knows the current type and frequency, and delegates to the right decoder
@ -1727,7 +1746,7 @@ void execOTA() {
void loop() { void loop() {
Serial.printf("Running main loop in state %d. free heap: %d;\n ", mainState, ESP.getFreeHeap()); Serial.printf("\nRunning main loop in state %d. free heap: %d;\n", mainState, ESP.getFreeHeap());
switch (mainState) { switch (mainState) {
case ST_DECODER: loopDecoder(); break; case ST_DECODER: loopDecoder(); break;
// handled by decoder now ...... case ST_SCANNER: loopScanner(); break; // handled by decoder now ...... case ST_SCANNER: loopScanner(); break;

View File

@ -1,2 +1,2 @@
const char *version_name = "RDZ_TTGO_SONDE"; const char *version_name = "RDZ_TTGO_SONDE";
const char *version_id = "devel20190524"; const char *version_id = "devel20190525";

View File

@ -84,6 +84,7 @@ DispEntry legacyLayout[] = {
{4, 9, FONT_SMALL, disp.drawVS}, {4, 9, FONT_SMALL, disp.drawVS},
{6, 0, FONT_LARGE, disp.drawRSSI}, {6, 0, FONT_LARGE, disp.drawRSSI},
{6, 7, 0, disp.drawQS}, {6, 7, 0, disp.drawQS},
{7, 5, 0, disp.drawIP},
{-1, -1, -1, NULL}, {-1, -1, -1, NULL},
}; };
int16_t legacyTimeouts[] = { -1, -1, 20000 }; int16_t legacyTimeouts[] = { -1, -1, 20000 };

View File

@ -5,7 +5,7 @@
#include "rsc.h" #include "rsc.h"
#include "Sonde.h" #include "Sonde.h"
#define RS41_DEBUG 1 #define RS41_DEBUG 0
#if RS41_DEBUG #if RS41_DEBUG
#define RS41_DBG(x) x #define RS41_DBG(x) x
@ -131,7 +131,9 @@ int RS41::setup()
RS41_DBG(Serial.println("Setting Packet config FAILED")); RS41_DBG(Serial.println("Setting Packet config FAILED"));
return 1; return 1;
} }
#if RS41_DEBUG
RS41_DBG(Serial.println("Setting SX1278 config for RS41 finished\n"); Serial.println()); RS41_DBG(Serial.println("Setting SX1278 config for RS41 finished\n"); Serial.println());
#endif
return 0; return 0;
} }

View File

@ -17,6 +17,7 @@ const char *evstring[]={"NONE", "KEY1S", "KEY1D", "KEY1M", "KEY1L", "KEY2S", "KE
Sonde::Sonde() { Sonde::Sonde() {
config.button_pin = 0; config.button_pin = 0;
config.button2_pin = T4 + 128; // T4 == GPIO13, should be ok for v1 and v2 config.button2_pin = T4 + 128; // T4 == GPIO13, should be ok for v1 and v2
config.touch_thresh = 60;
config.led_pout = 9; config.led_pout = 9;
// Try autodetecting board type // Try autodetecting board type
// Seems like on startup, GPIO4 is 1 on v1 boards, 0 on v2.1 boards? // Seems like on startup, GPIO4 is 1 on v1 boards, 0 on v2.1 boards?
@ -83,6 +84,8 @@ void Sonde::setConfig(const char *cfg) {
config.button_pin = atoi(val); config.button_pin = atoi(val);
} else if(strcmp(cfg,"button2_pin")==0) { } else if(strcmp(cfg,"button2_pin")==0) {
config.button2_pin = atoi(val); config.button2_pin = atoi(val);
} else if(strcmp(cfg,"touch_thresh")==0) {
config.touch_thresh = atoi(val);
} else if(strcmp(cfg,"led_pout")==0) { } else if(strcmp(cfg,"led_pout")==0) {
config.led_pout = atoi(val); config.led_pout = atoi(val);
} else if(strcmp(cfg,"oled_sda")==0) { } else if(strcmp(cfg,"oled_sda")==0) {
@ -195,8 +198,8 @@ void Sonde::setup() {
// Test only: setIP("123.456.789.012"); // Test only: setIP("123.456.789.012");
sondeList[currentSonde].lastState = -1; sondeList[currentSonde].lastState = -1;
sondeList[currentSonde].viewStart = millis(); sondeList[currentSonde].viewStart = millis();
// update receiver config: TODO // update receiver config
Serial.print("Setting up receiver on channel "); Serial.print("\nSonde::setup() on sonde index ");
Serial.println(currentSonde); Serial.println(currentSonde);
switch(sondeList[currentSonde].type) { switch(sondeList[currentSonde].type) {
case STYPE_RS41: case STYPE_RS41:
@ -240,21 +243,23 @@ int Sonde::receiveFrame() {
uint8_t Sonde::timeoutEvent() { uint8_t Sonde::timeoutEvent() {
uint32_t now = millis(); uint32_t now = millis();
#if 0
Serial.printf("Timeout check: %ld - %ld vs %ld; %ld - %ld vs %ld; %ld - %ld vs %ld\n", Serial.printf("Timeout check: %ld - %ld vs %ld; %ld - %ld vs %ld; %ld - %ld vs %ld\n",
now, sonde.si()->viewStart, disp.layout->timeouts[0], now, sonde.si()->viewStart, disp.layout->timeouts[0],
now, sonde.si()->rxStart, disp.layout->timeouts[1], now, sonde.si()->rxStart, disp.layout->timeouts[1],
now, sonde.si()->norxStart, disp.layout->timeouts[2]); now, sonde.si()->norxStart, disp.layout->timeouts[2]);
#endif
Serial.printf("lastState is %d\n", sonde.si()->lastState); Serial.printf("lastState is %d\n", sonde.si()->lastState);
if(disp.layout->timeouts[0]>=0 && now - sonde.si()->viewStart >= disp.layout->timeouts[0]) { if(disp.layout->timeouts[0]>=0 && now - sonde.si()->viewStart >= disp.layout->timeouts[0]) {
Serial.println("View timeout"); Serial.println("View timer expired");
return EVT_VIEWTO; return EVT_VIEWTO;
} }
if(sonde.si()->lastState==1 && disp.layout->timeouts[1]>=0 && now - sonde.si()->rxStart >= disp.layout->timeouts[1]) { if(sonde.si()->lastState==1 && disp.layout->timeouts[1]>=0 && now - sonde.si()->rxStart >= disp.layout->timeouts[1]) {
Serial.println("RX timeout"); Serial.println("RX timer expired");
return EVT_RXTO; return EVT_RXTO;
} }
if(sonde.si()->lastState==0 && disp.layout->timeouts[2]>=0 && now - sonde.si()->norxStart >= disp.layout->timeouts[2]) { if(sonde.si()->lastState==0 && disp.layout->timeouts[2]>=0 && now - sonde.si()->norxStart >= disp.layout->timeouts[2]) {
Serial.println("No RX timeout"); Serial.println("NORX timer expired");
return EVT_NORXTO; return EVT_NORXTO;
} }
return 0; return 0;

View File

@ -52,6 +52,7 @@ struct st_rs41config {
typedef struct st_rdzconfig { typedef struct st_rdzconfig {
int button_pin; // PIN port number menu button (+128 for touch mode) int button_pin; // PIN port number menu button (+128 for touch mode)
int button2_pin; // PIN port number menu button (+128 for touch mode) int button2_pin; // PIN port number menu button (+128 for touch mode)
int touch_thresh; // Threshold value (0..100) for touch input button
int led_pout; // POUT port number of LED (used as serial monitor) int led_pout; // POUT port number of LED (used as serial monitor)
int oled_sda; // OLED data pin int oled_sda; // OLED data pin
int oled_scl; // OLED clock pin int oled_scl; // OLED clock pin