Add virtual Buttons & Switches in Digtian driver (#18223)

* add support for virtual buttons or switches

* remove DINGTIAN key from SENSOR when using buttons-switches
This commit is contained in:
Barbudor 2023-03-19 20:19:48 +01:00 committed by GitHub
parent 115105bf7c
commit 948a82d75e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 24 deletions

View File

@ -978,6 +978,11 @@
//#define USE_HX711 // Add support for HX711 load cell (+1k5 code) //#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
// #define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code) // #define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code)
//#define USE_DINGTIAN_RELAY // Add support for the Dingian board using 74'595 et 74'165 shift registers
// #define DINGTIAN_INPUTS_INVERTED // Invert input states (Hi => OFF, Low => ON)
// #define DINGTIAN_USE_AS_BUTTON // Inputs as Tasmota's virtual Buttons
// #define DINGTIAN_USE_AS_SWITCH // Inputs as Tasmota's virtual Switches
// Select none or only one of the below defines // Select none or only one of the below defines
//#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code) //#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code)
//#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code) //#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code)

View File

@ -22,6 +22,14 @@
#define XDRV_90 90 #define XDRV_90 90
/********************************************************************************************************
* Check defines
*/
#if defined(DINGTIAN_USE_AS_BUTTON) && defined(DINGTIAN_USE_AS_SWITCH)
#error DINGTIAN - Only one of DINGTIAN_USE_AS_BUTTON or DINGTIAN_USE_AS_SWITCH should be defined
#endif
/******************************************************************************************************** /********************************************************************************************************
* Global private data * Global private data
*/ */
@ -31,6 +39,7 @@ struct DINGTIAN_DATA {
uint32_t last_inputs; // previous inputs state uint32_t last_inputs; // previous inputs state
uint8_t count; // number of relay and input (8 * numver of shift registers) uint8_t count; // number of relay and input (8 * numver of shift registers)
uint8_t first; // index of 1st Tasmota relay assigned to 1st Dingtian relays uint8_t first; // index of 1st Tasmota relay assigned to 1st Dingtian relays
int8_t key_offset; // index of virtual key
// pins // pins
uint8_t pin_clk, pin_sdi, pin_q7, pin_pl, pin_rck; uint8_t pin_clk, pin_sdi, pin_q7, pin_pl, pin_rck;
} *Dingtian = nullptr; } *Dingtian = nullptr;
@ -63,7 +72,11 @@ uint32_t DingtianReadWrite(uint32_t outputs)
digitalWrite(Dingtian->pin_rck, 1); // rclk pulse to load '595 into output registers digitalWrite(Dingtian->pin_rck, 1); // rclk pulse to load '595 into output registers
digitalWrite(Dingtian->pin_pl, 0); // re-enable '595 ouputs digitalWrite(Dingtian->pin_pl, 0); // re-enable '595 ouputs
#ifdef DINGTIAN_INPUTS_INVERTED
return ~inputs;
#else
return inputs; return inputs;
#endif
} }
/******************************************************************************************************** /********************************************************************************************************
@ -98,16 +111,51 @@ void DingtianInit(void) {
DINGTIAN_SET_OUTPUT(Dingtian->pin_rck, 0); DINGTIAN_SET_OUTPUT(Dingtian->pin_rck, 0);
Dingtian->first = TasmotaGlobal.devices_present; Dingtian->first = TasmotaGlobal.devices_present;
Dingtian->key_offset = -1;
UpdateDevicesPresent(Dingtian->count); UpdateDevicesPresent(Dingtian->count);
AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, TasmotaGlobal.devices_present); AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, TasmotaGlobal.devices_present);
} }
} }
} }
#if defined(DINGTIAN_USE_AS_BUTTON) || defined(DINGTIAN_USE_AS_SWITCH)
bool DingtianAddKey(void) {
if (Dingtian->key_offset < 0) {
Dingtian->key_offset = XdrvMailbox.index;
#ifdef DINGTIAN_USE_AS_BUTTON
AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian inputs: Button%d to Button%d"), Dingtian->key_offset + 1, Dingtian->key_offset + Dingtian->count);
#else
AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian inputs: Switch%d to Switch%d"), Dingtian->key_offset + 1, Dingtian->key_offset + Dingtian->count);
#endif
}
uint32_t index = XdrvMailbox.index - Dingtian->key_offset;
if (index >= Dingtian->count) {
return false;
}
XdrvMailbox.index = 0; // Default is 0 - Button will also set invert
return true;
}
#endif
/******************************************************************************************************** /********************************************************************************************************
* Driver operations * Driver operations
*/ */
#if defined(DINGTIAN_USE_AS_BUTTON) || defined(DINGTIAN_USE_AS_SWITCH)
void DingtianLoop()
{
uint32_t inputs = DingtianReadWrite(Dingtian->outputs);
Dingtian->last_inputs = inputs;
for (int i = 0 ; i < Dingtian->count ; i++, inputs>>=1) {
#ifdef DINGTIAN_USE_AS_BUTTON
ButtonSetVirtualPinState(Dingtian->key_offset +i, inputs &1);
#else
SwitchSetVirtualPinState(Dingtian->key_offset +i, inputs &1);
#endif
}
}
#else
void DingtianLoop() void DingtianLoop()
{ {
uint32_t inputs = DingtianReadWrite(Dingtian->outputs); uint32_t inputs = DingtianReadWrite(Dingtian->outputs);
@ -131,6 +179,7 @@ void DingtianLoop()
} }
} }
} }
#endif
void DingtianSetPower(void) void DingtianSetPower(void)
{ {
@ -146,9 +195,9 @@ void DingtianSetPower(void)
const char HTTP_DINGTIAN_INPUTS[] PROGMEM = "{s}DINGTIAN " D_SENSOR_INPUT "%d.." D_SENSOR_INPUT "%d{m}%s{e}"; const char HTTP_DINGTIAN_INPUTS[] PROGMEM = "{s}DINGTIAN " D_SENSOR_INPUT "%d.." D_SENSOR_INPUT "%d{m}%s{e}";
void DingtianShow(bool json) #if !defined(DINGTIAN_USE_AS_BUTTON) && !defined(DINGTIAN_USE_AS_SWITCH)
void DingtianJsonAppend(void)
{ {
if (json) {
bool first_done = false; bool first_done = false;
ResponseAppend_P(PSTR(",\"DINGTIAN\":{")); ResponseAppend_P(PSTR(",\"DINGTIAN\":{"));
for (int i = 0 ; i < Dingtian->count ; i++) { for (int i = 0 ; i < Dingtian->count ; i++) {
@ -158,8 +207,11 @@ void DingtianShow(bool json)
} }
ResponseAppend_P(PSTR("}")); ResponseAppend_P(PSTR("}"));
} }
#endif
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
else { void DingtianWebSensor(void)
{
char input_str[9]; char input_str[9];
for (int block_input = 0 ; block_input < Dingtian->count ; block_input += 8 ) { for (int block_input = 0 ; block_input < Dingtian->count ; block_input += 8 ) {
for (int i = 0 ; i < 8 ; i++ ) for (int i = 0 ; i < 8 ; i++ )
@ -169,7 +221,6 @@ void DingtianShow(bool json)
} }
} }
#endif #endif
}
/*********************************************************************************************\ /*********************************************************************************************\
@ -179,7 +230,7 @@ void DingtianShow(bool json)
bool Xdrv90(uint32_t function) { bool Xdrv90(uint32_t function) {
bool result = false; bool result = false;
if (FUNC_PRE_INIT == function) { if (FUNC_SETUP_RING2 == function) {
DingtianInit(); DingtianInit();
} else if (Dingtian) { } else if (Dingtian) {
switch (function) { switch (function) {
@ -190,14 +241,26 @@ bool Xdrv90(uint32_t function) {
//case FUNC_EVERY_250_MSECOND: //case FUNC_EVERY_250_MSECOND:
DingtianLoop(); DingtianLoop();
break; break;
#if !defined(DINGTIAN_USE_AS_BUTTON) && !defined(DINGTIAN_USE_AS_SWITCH)
case FUNC_JSON_APPEND: case FUNC_JSON_APPEND:
DingtianShow(1); DingtianJsonAppend();
break; break;
#endif
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR: case FUNC_WEB_SENSOR:
DingtianShow(0); DingtianWebSensor();
break; break;
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
#ifdef DINGTIAN_USE_AS_BUTTON
case FUNC_ADD_BUTTON:
result = DingtianAddKey();
break;
#endif
#ifdef DINGTIAN_USE_AS_SWITCH
case FUNC_ADD_SWITCH:
result = DingtianAddKey();
break;
#endif
} }
} }
return result; return result;