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 {
uint8_t pin;
uint32_t numberKeyPresses;
KeyPress pressed;
unsigned long press_ts;
boolean doublepress;
unsigned long keydowTime;
bool doublepress;
bool isTouched;
long touchTime;
};
Button button1 = {0, 0, KP_NONE, 0, false, false, 0};
Button button2 = {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};
static int lastDisplay = 1;
@ -415,6 +412,7 @@ struct st_configitems config_list[] = {
{"oled_rst", "OLED RST (needs reboot)", 0, &sonde.config.oled_rst},
{"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},
{"touch_thresh", "Touch button threshold (needs reboot)", 0, &sonde.config.touch_thresh},
{"led_pout", "LED output port (needs reboot)", 0, &sonde.config.led_pout},
};
const static int N_CONFIG = (sizeof(config_list) / sizeof(struct st_configitems));
@ -813,30 +811,41 @@ void initTouch() {
void IRAM_ATTR touchISR() {
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;
}
}
void IRAM_ATTR touchISR2() {
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;
}
}
inline void IRAM_ATTR checkTouchButton(Button &button) {
void IRAM_ATTR checkTouchButton(Button &button) {
if (button.isTouched) {
int tmp = touchRead(button.pin & 0x7f);
// bad idea within ISR: Serial.printf("touchRead on pin %d is %d\n", button.pin, tmp);
if (tmp > 60) {
if (tmp > sonde.config.touch_thresh) {
button.isTouched = false;
// simulate key press
button.pressed = KP_SHORT;
} else {
if (my_millis() - button.touchTime > 3000) {
// long touch
// ignore for now
unsigned long elapsed = my_millis() - button.keydowTime;
if (elapsed > 1500) {
if (elapsed < 4000) {
button.pressed = KP_MID;
}
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() {
unsigned long now = my_millis();
if (digitalRead(button1.pin) == 0) { // Button down
if (now - button1.press_ts < 500) {
if (now - button1.keydowTime < 500) {
// Double press
button1.doublepress = true;
} else {
button1.doublepress = false;
}
button1.press_ts = now;
button1.keydowTime = now;
} else { //Button up
unsigned int elapsed = now - button1.press_ts;
unsigned int elapsed = now - button1.keydowTime;
if (elapsed > 1500) {
if (elapsed < 4000) {
button1.pressed = KP_MID;
@ -873,21 +881,21 @@ void IRAM_ATTR buttonISR() {
else button1.pressed = KP_SHORT;
}
button1.numberKeyPresses += 1;
button1.press_ts = now;
button1.keydowTime = now;
}
}
int getKeyPress() {
KeyPress p = button1.pressed;
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;
}
int getKey2Press() {
KeyPress p = button2.pressed;
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;
}
int hasKeyPress() {
@ -897,12 +905,11 @@ int getKeyPressEvent() {
int p = getKeyPress();
if (p == KP_NONE) {
p = getKey2Press();
if (p == KP_NONE)
if (p == KP_NONE)
return EVT_NONE;
return p+4;
return p + 4;
}
return p; /* map KP_x to EVT_KEY1_x */
/* TODO: map touch event and second button */
return p; /* map KP_x to EVT_KEY1_x / EVT_KEY2_x*/
}
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() {
#if 0
switch (getKeyPress()) {
@ -1091,13 +1109,14 @@ void loopDecoder() {
if (!event) event = sonde.timeoutEvent();
// Check if there is an action for this 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 == ACT_DISPLAY_SPECTRUM) enterMode(ST_SPECTRUM);
else if (action == ACT_DISPLAY_WIFI) enterMode(ST_WIFISCAN);
return;
Serial.printf("Loop: triggering action %s (%d) for event %s (%d)\n", action2text(action), action, EVENTNAME(event), event);
action = sonde.updateState(action);
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
@ -1727,7 +1746,7 @@ void execOTA() {
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) {
case ST_DECODER: loopDecoder(); 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_id = "devel20190524";
const char *version_id = "devel20190525";

View File

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

View File

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

View File

@ -17,6 +17,7 @@ const char *evstring[]={"NONE", "KEY1S", "KEY1D", "KEY1M", "KEY1L", "KEY2S", "KE
Sonde::Sonde() {
config.button_pin = 0;
config.button2_pin = T4 + 128; // T4 == GPIO13, should be ok for v1 and v2
config.touch_thresh = 60;
config.led_pout = 9;
// Try autodetecting board type
// 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);
} else if(strcmp(cfg,"button2_pin")==0) {
config.button2_pin = atoi(val);
} else if(strcmp(cfg,"touch_thresh")==0) {
config.touch_thresh = atoi(val);
} else if(strcmp(cfg,"led_pout")==0) {
config.led_pout = atoi(val);
} else if(strcmp(cfg,"oled_sda")==0) {
@ -195,8 +198,8 @@ void Sonde::setup() {
// Test only: setIP("123.456.789.012");
sondeList[currentSonde].lastState = -1;
sondeList[currentSonde].viewStart = millis();
// update receiver config: TODO
Serial.print("Setting up receiver on channel ");
// update receiver config
Serial.print("\nSonde::setup() on sonde index ");
Serial.println(currentSonde);
switch(sondeList[currentSonde].type) {
case STYPE_RS41:
@ -240,21 +243,23 @@ int Sonde::receiveFrame() {
uint8_t Sonde::timeoutEvent() {
uint32_t now = millis();
#if 0
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()->rxStart, disp.layout->timeouts[1],
now, sonde.si()->norxStart, disp.layout->timeouts[2]);
#endif
Serial.printf("lastState is %d\n", sonde.si()->lastState);
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;
}
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;
}
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 0;

View File

@ -52,6 +52,7 @@ struct st_rs41config {
typedef struct st_rdzconfig {
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 touch_thresh; // Threshold value (0..100) for touch input button
int led_pout; // POUT port number of LED (used as serial monitor)
int oled_sda; // OLED data pin
int oled_scl; // OLED clock pin