New gpio handlers

This commit is contained in:
fvanroie 2020-05-25 19:45:26 +02:00
parent 97248e67fc
commit 1f47c96e19
4 changed files with 233 additions and 117 deletions

View File

@ -173,7 +173,7 @@ void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const c
uint8_t objid;
if(FindIdFromObj(obj, &pageid, &objid)) {
dispatch_obj_attribute_str(pageid, objid, attribute, data);
dispatch_send_obj_attribute_str(pageid, objid, attribute, data);
}
}
@ -301,25 +301,47 @@ void haspReconnect()
lv_obj_set_hidden(obj, true);*/
}
void haspProgress(uint8_t val, char * msg)
String progress_str((char *)0);
void haspProgressVal(uint8_t val)
{
lv_obj_t * layer = lv_disp_get_layer_sys(NULL);
lv_obj_t * bar = hasp_find_obj_from_id(255, 10);
if(val == 255) {
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
if(bar) {
lv_obj_set_hidden(bar, true);
}
} else {
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_100);
if(bar) {
lv_obj_set_hidden(bar, false);
if(layer && bar) {
if(val == 255) {
if(!lv_obj_get_hidden(bar)) {
lv_obj_set_hidden(bar, true);
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
lv_obj_set_style_local_value_str(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, "");
#if defined(ARCH_ARDUINO_ESP32) || defined(ARCH_ARDUINO_ESP8266)
progress_str.clear();
#endif
}
} else {
if(lv_obj_get_hidden(bar)) {
lv_obj_set_hidden(bar, false);
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_100);
}
lv_bar_set_value(bar, val, LV_ANIM_OFF);
lv_obj_set_style_local_value_str(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, msg);
}
lv_task_handler(); /* let the GUI do its work */
}
lv_tick_inc(30);
}
void haspProgressMsg(const char * msg)
{
lv_obj_t * bar = hasp_find_obj_from_id(255, 10);
if(bar) {
progress_str.reserve(64);
progress_str = msg;
lv_obj_set_style_local_value_str(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, progress_str.c_str());
lv_task_handler(); /* let the GUI do its work */
}
}
void haspProgressMsg(const __FlashStringHelper * msg)
{
haspProgressMsg(String(msg).c_str());
}
/**
@ -546,27 +568,34 @@ void hasp_background(uint16_t pageid, uint16_t imageid)
*/
void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
{
uint8_t eventid;
char buffer[64];
snprintf(buffer, sizeof(buffer), PSTR("HASP: "));
switch(event) {
case LV_EVENT_PRESSED:
eventid = HASP_EVENT_DOWN;
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
break;
case LV_EVENT_CLICKED:
// UP = the same object was release then was pressed and press was not lost!
eventid = HASP_EVENT_UP;
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
break;
case LV_EVENT_SHORT_CLICKED:
eventid = HASP_EVENT_SHORT;
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
break;
case LV_EVENT_LONG_PRESSED:
eventid = HASP_EVENT_LONG;
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
eventid = HASP_EVENT_HOLD;
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
break;
case LV_EVENT_PRESS_LOST:
eventid = HASP_EVENT_LOST;
memcpy_P(buffer, PSTR("LOST"), sizeof(buffer));
break;
case LV_EVENT_PRESSING:
@ -585,7 +614,7 @@ void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
Log.notice(buffer, event);
return;
default:
strcat_P(buffer, PSTR("HASP : Unknown Event % d occured"));
strcat_P(buffer, PSTR("HASP : Unknown Event occured"));
Log.warning(buffer, event);
return;
}
@ -595,7 +624,8 @@ void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
mqtt_send_state(F("wakeuptouch"), buffer);
#endif
} else {
hasp_send_obj_attribute_event(obj, buffer);
// hasp_send_obj_attribute_event(obj, buffer);
dispatch_send_object_event(current_page, (uint8_t)obj->user_data, eventid);
}
}
@ -697,6 +727,20 @@ void haspSetPage(uint8_t pageid)
}
}
void hasp_set_group_objects(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj)
{
bool state = dispatch_get_event_state(eventid);
for(uint8_t page = 0; page < HASP_NUM_PAGES; page++) {
uint8_t startid = 100 + groupid * 10; // groups start at id 100
for(uint8_t objid = startid; objid < (startid + 10); objid++) {
lv_obj_t * obj = hasp_find_obj_from_id(page, objid);
if(obj && obj != src_obj) { // skip source object, if set
lv_obj_set_state(obj, state ? LV_STATE_PRESSED | LV_STATE_CHECKED : LV_STATE_DEFAULT);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id)

View File

@ -19,7 +19,7 @@ extern "C" {
* INCLUDES
*********************/
#if HASP_USE_APP>0
#if HASP_USE_APP > 0
/*********************
* DEFINES
@ -29,6 +29,19 @@ extern "C" {
* TYPEDEFS
**********************/
enum hasp_event_t { // even = released, odd = pressed
HASP_EVENT_OFF = 0,
HASP_EVENT_ON = 1,
HASP_EVENT_UP = 2,
HASP_EVENT_DOWN = 3,
HASP_EVENT_SHORT = 4,
HASP_EVENT_LONG = 5,
HASP_EVENT_LOST = 6,
HASP_EVENT_HOLD = 7,
HASP_EVENT_DOUBLE = 8
};
enum lv_hasp_obj_type_t {
LV_HASP_BUTTON = 10,
LV_HASP_CHECKBOX = 11,
@ -51,12 +64,12 @@ enum lv_hasp_obj_type_t {
LV_HASP_IMAGE = 60,
LV_HASP_TABVIEW = 70,
LV_HASP_TABVIEW = 70,
LV_HASP_TILEVIEW = 71,
LV_HASP_CONTAINER = 90,
LV_HASP_OBJECT = 91,
LV_HASP_PAGE = 92,
LV_HASP_OBJECT = 91,
LV_HASP_PAGE = 92,
};
/**********************
@ -80,13 +93,14 @@ void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const c
void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t val);
void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color);
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload);
void hasp_set_group_objects(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj);
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id);
void haspReconnect(void);
void haspDisconnect(void);
void haspWakeUp(void);
void haspProgress(uint8_t val, char * msg);
void haspProgressVal(uint8_t val);
bool haspGetConfig(const JsonObject & settings);
bool haspSetConfig(const JsonObject & settings);
@ -106,4 +120,7 @@ void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event);
} /* extern "C" */
#endif
void haspProgressMsg(const char * msg);
void haspProgressMsg(const __FlashStringHelper * msg);
#endif /*HASP_H*/

View File

@ -7,28 +7,22 @@
#include "hasp_conf.h"
#include "hasp_gpio.h"
#include "hasp_dispatch.h"
#define HASP_NUM_GPIO_CONFIG 5
#include "hasp.h"
uint8_t gpioUsedInputCount = 0;
uint16_t gpioConfig[HASP_NUM_GPIO_CONFIG];
using namespace ace_button;
static AceButton * button[HASP_NUM_INPUTS];
struct hasp_gpio_config_t
{
const uint8_t pin;
const uint8_t group;
const uint8_t io_mode;
bool default_state;
uint8_t pin; // pin number
uint8_t group; // groupid
uint8_t type; // switch, button, ...
uint8_t gpio_function; // INPUT, OUTPUT, PULLUP, etc
};
// An array of button pins, led pins, and the led states. Cannot be const
// because ledState is mutable.
hasp_gpio_config_t gpioConfig2[HASP_NUM_GPIO_CONFIG] = {
{2, 8, INPUT, LOW}, {3, 9, OUTPUT, LOW}, {4, 10, INPUT, HIGH}, {5, 11, OUTPUT, LOW}, {6, 12, INPUT, LOW},
};
hasp_gpio_config_t gpioConfig[HASP_NUM_GPIO_CONFIG];
#if defined(ARDUINO_ARCH_ESP32)
class TouchConfig : public ButtonConfig {
@ -53,39 +47,48 @@ class TouchConfig : public ButtonConfig {
TouchConfig touchConfig();
#endif
static void gpio_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState)
static void gpio_event_handler(AceButton * button, uint8_t eventType, uint8_t buttonState)
{
uint8_t eventid;
char buffer[16];
switch(eventType) {
case 0: // AceButton::kEventPressed:
case AceButton::kEventPressed:
eventid = HASP_EVENT_DOWN;
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
break;
case 2: // AceButton::kEventClicked:
eventid = HASP_EVENT_SHORT;
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
break;
case AceButton::kEventDoubleClicked:
eventid = HASP_EVENT_DOUBLE;
memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer));
break;
case 4: // AceButton::kEventLongPressed:
case AceButton::kEventLongPressed:
eventid = HASP_EVENT_LONG;
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
break;
case 5: // AceButton::kEventRepeatPressed:
case AceButton::kEventRepeatPressed:
// return; // Fix needed for switches
eventid = HASP_EVENT_HOLD;
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
break;
case 1: // AceButton::kEventReleased:
case AceButton::kEventReleased:
eventid = HASP_EVENT_UP;
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
break;
default:
eventid = HASP_EVENT_LOST;
memcpy_P(buffer, PSTR("UNKNOWN"), sizeof(buffer));
}
dispatch_button(button->getId(), buffer);
dispatch_send_group_event(gpioConfig[button->getId()].group, eventid, true);
}
void aceButtonSetup(void)
{
ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setEventHandler(gpio_event_handler);
// Features
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
@ -110,21 +113,20 @@ void IRAM_ATTR gpioLoop(void)
}
}
void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index)
{
uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) {
button[i] = new AceButton(pin, default_state, channel);
// button[i]->init(pin, default_state, channel);
button[i] = new AceButton(pin, default_state, index);
// button[i]->init(pin, default_state, index);
if(button[i]) {
pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setEventHandler(gpio_event_handler);
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
@ -132,30 +134,30 @@ void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8
buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel,
Log.verbose(F("GPIO: Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index,
input_mode, default_state);
gpioUsedInputCount = i + 1;
return;
}
}
}
Log.error(F("GPIO: Failed to create Button%d pin %d (channel %d). All %d slots available are in use!"), i, pin,
channel, HASP_NUM_INPUTS);
Log.error(F("GPIO: Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin, index,
HASP_NUM_INPUTS);
}
void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index)
{
uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) {
button[i] = new AceButton();
button[i] = new AceButton(pin, default_state, index);
if(button[i]) {
pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setEventHandler(gpio_event_handler);
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
@ -163,83 +165,39 @@ void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state,
buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel,
Log.verbose(F("GPIO: Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index,
input_mode, default_state);
gpioUsedInputCount = i + 1;
return;
}
}
}
Log.error(F("GPIO: Failed to create Button%d pin %d (channel %d). All %d slots available are in use!"), i, pin,
channel, HASP_NUM_INPUTS);
Log.error(F("GPIO: Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin, index,
HASP_NUM_INPUTS);
}
void gpioSetup()
{
aceButtonSetup();
return;
// gpioConfig[0] = PD15 * 256 + 5 + (INPUT << 3);
// return;
#if defined(ARDUINO_ARCH_ESP8266)
gpioAddButton(D2, INPUT_PULLUP, HIGH, 1);
//pinMode(D1, OUTPUT);
gpioConfig[0] = {D2, 7, HASP_GPIO_BUTTON, INPUT_PULLUP};
gpioConfig[1] = {D1, 7, HASP_GPIO_LED, OUTPUT};
// gpioAddButton(D2, INPUT_PULLUP, HIGH, 1);
// pinMode(D1, OUTPUT);
#endif
#if defined(ARDUINO_ARCH_ESP32)
// gpioAddButton(D2, INPUT, HIGH, 1);
// pinMode(D1, OUTPUT);
// gpioConfig[0] = {D2, 0, HASP_GPIO_SWITCH, INPUT};
// gpioConfig[1] = {D1, 1, HASP_GPIO_RELAY, OUTPUT};
// gpioAddButton(D2, INPUT, HIGH, 1);
// pinMode(D1, OUTPUT);
#endif
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
uint8_t pin = (gpioConfig[i] >> 8) & 0xFF;
uint8_t channel = gpioConfig[i] & 0b111; // 3bit
uint8_t input_mode = (gpioConfig[i] >> 3) & 0b11; // 2bit gpio mode
// uint8_t input_mode = gpioConfig[i].io_mode
uint8_t gpiotype = (gpioConfig[i] >> 5) & 0b111; // 3bit
uint8_t default_state = gpioConfig[i] & 0b1; // 1bit: 0=LOW, 1=HIGH
switch(input_mode) {
case 1:
input_mode = OUTPUT;
break;
case 2:
input_mode = INPUT_PULLUP;
break;
#ifndef ARDUINO_ARCH_ESP8266
case 3:
input_mode = INPUT_PULLDOWN;
break;
#endif
default:
input_mode = INPUT;
}
switch(gpiotype) {
case HASP_GPIO_SWITCH:
case HASP_GPIO_BUTTON:
// gpioAddButton(gpioConfig[i].io_mode.pin, input_mode, gpioConfig[i].default_state,
// gpioConfig[i].group);
break;
case HASP_GPIO_RELAY:
pinMode(pin, OUTPUT);
break;
// case HASP_GPIO_LED:
case HASP_GPIO_PWM:
case HASP_GPIO_BACKLIGHT:
pinMode(pin, OUTPUT);
#if defined(ARDUINO_ARCH_ESP32)
// configure LED PWM functionalitites
ledcSetup(channel, 20000, 10);
// attach the channel to the GPIO to be controlled
ledcAttachPin(pin, channel);
#endif
break;
}
}
/*
#if defined(ARDUINO_ARCH_ESP8266)
pinMode(D1, OUTPUT);
@ -250,4 +208,88 @@ void gpioSetup()
pinMode(HASP_INPUT_PIN, INPUT);
#endif
*/
}
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
uint8_t input_mode;
switch(gpioConfig[i].gpio_function) {
case OUTPUT:
input_mode = OUTPUT;
break;
case INPUT_PULLUP:
input_mode = INPUT_PULLUP;
break;
#ifndef ARDUINO_ARCH_ESP8266
case INPUT_PULLDOWN:
input_mode = INPUT_PULLDOWN;
break;
#endif
default:
input_mode = INPUT;
}
switch(gpioConfig[i].type) {
case HASP_GPIO_SWITCH:
case HASP_GPIO_BUTTON:
gpioAddButton(gpioConfig[i].pin, input_mode, HIGH, i);
break;
case HASP_GPIO_SWITCH_INVERTED:
case HASP_GPIO_INPUT_BUTTON_INVERTED:
gpioAddButton(gpioConfig[i].pin, input_mode, LOW, i);
break;
case HASP_GPIO_RELAY:
case HASP_GPIO_RELAY_INVERTED:
case HASP_GPIO_LED:
case HASP_GPIO_LED_INVERTED:
pinMode(gpioConfig[i].pin, OUTPUT);
break;
case HASP_GPIO_PWM:
case HASP_GPIO_PWM_INVERTED:
// case HASP_GPIO_BACKLIGHT:
pinMode(gpioConfig[i].pin, OUTPUT);
#if defined(ARDUINO_ARCH_ESP32)
// configure LED PWM functionalitites
ledcSetup(gpioConfig[i].group, 20000, 10);
// attach the channel to the GPIO to be controlled
ledcAttachPin(gpioConfig[i].pin, gpioConfig[i].group);
#endif
break;
}
}
}
void gpio_set_group_outputs(uint8_t groupid, uint8_t eventid)
{
bool state = dispatch_get_event_state(eventid);
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
if(gpioConfig[i].group == groupid) {
switch(gpioConfig[i].type) {
case HASP_GPIO_RELAY:
case HASP_GPIO_LED:
digitalWrite(gpioConfig[i].pin, state ? HIGH : LOW);
break;
case HASP_GPIO_RELAY_INVERTED:
case HASP_GPIO_LED_INVERTED:
digitalWrite(gpioConfig[i].pin, state ? LOW : HIGH);
break;
#if defined(ARDUINO_ARCH_ESP32)
case HASP_GPIO_PWM:
ledcWrite(groupid, map(state, 0, 1, 0, 1023)); // ledChannel and value
break;
case HASP_GPIO_PWM_INVERTED:
ledcWrite(groupid, map(!state, 0, 1, 0, 1023)); // ledChannel and value
break;
#else
case HASP_GPIO_PWM:
analogWrite(gpioConfig[i].pin, map(state, 0, 1, 0, 1023));
break;
case HASP_GPIO_PWM_INVERTED:
analogWrite(gpioConfig[i].pin, map(!state, 0, 1, 0, 1023));
break;
#endif
default:;
}
}
}
}

View File

@ -9,14 +9,27 @@ extern "C" {
void gpioSetup(void);
void IRAM_ATTR gpioLoop(void);
void gpio_set_group_outputs(uint8_t groupid, uint8_t eventid);
enum lv_hasp_gpio_type_t {
HASP_GPIO_SWITCH = 0,
HASP_GPIO_BUTTON = 1,
HASP_GPIO_RELAY = 2,
HASP_GPIO_PWM = 3,
HASP_GPIO_BACKLIGHT = 4,
};
#define HASP_GPIO_FREE 0x00
#define HASP_GPIO_USED 0x01
#define HASP_GPIO_SWITCH 0x02
#define HASP_GPIO_SWITCH_INVERTED 0x03
#define HASP_GPIO_BUTTON 0x04
#define HASP_GPIO_INPUT_BUTTON_INVERTED 0x05
#define HASP_GPIO_COUNTER 0x06
#define HASP_GPIO_COUNTER_INVERTED 0x07
#define HASP_GPIO_ADC 0x08
#define HASP_GPIO_ADC_INVERTED 0x09
#define HASP_GPIO_RELAY 0x0A
#define HASP_GPIO_RELAY_INVERTED 0x0B
#define HASP_GPIO_LED 0x0C
#define HASP_GPIO_LED_INVERTED 0x0D
#define HASP_GPIO_PWM 0x0E
#define HASP_GPIO_PWM_INVERTED 0x0F
#define HASP_GPIO_DAC 0x10
#define HASP_GPIO_DAC_INVERTED 0x11
#define HASP_GPIO_USER 0xFF
#ifdef __cplusplus
} /* extern "C" */