mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Add support for Linkind dimmer
Add support for Linkind dimmer as GPIO ``Option A6`` (#14004)
This commit is contained in:
parent
ab01d479ee
commit
d6fc62e376
@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file.
|
||||
- Solax X1 modbus RTS support and offline status (#14305)
|
||||
- DDP schemes for light and WS2812 (#14017)
|
||||
- ESP32 single binary firmware (#14239)
|
||||
- ESP32 support for USE_PWM_DIMMER as GPIO ``Option E1``
|
||||
- Support for Linkind dimmer as GPIO ``Option A6`` (#14004)
|
||||
|
||||
### Changed
|
||||
- PubSubClient library from v2.8.12 to v2.8.13
|
||||
|
@ -105,6 +105,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||
- Command ``SSerialConfig <serialconfig>`` to change Serial Bridge configuration
|
||||
- Command ``SspmMap 2,1,..`` to map Sonoff SPM scanned module to physical module [#14281](https://github.com/arendst/Tasmota/issues/14281)
|
||||
- PWM Dimmer two button support [#13993](https://github.com/arendst/Tasmota/issues/13993)
|
||||
- Support for Linkind dimmer as GPIO ``Option A6`` [#14004](https://github.com/arendst/Tasmota/issues/14004)
|
||||
- DDP schemes for light and WS2812 [#14017](https://github.com/arendst/Tasmota/issues/14017)
|
||||
- Device Group Send full status item [#14045](https://github.com/arendst/Tasmota/issues/14045)
|
||||
- Support for MAX7219 Dot Matrix displays [#14091](https://github.com/arendst/Tasmota/issues/14091)
|
||||
@ -114,6 +115,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||
- ESP32 single binary firmware [#14239](https://github.com/arendst/Tasmota/issues/14239)
|
||||
- ESP32 support for TuyaMcu
|
||||
- ESP32 Berry features
|
||||
- ESP32 support for USE_PWM_DIMMER as GPIO ``Option E1``
|
||||
|
||||
### Breaking Changed
|
||||
|
||||
|
@ -1523,6 +1523,11 @@ void ModuleDefault(uint32_t module)
|
||||
void SetModuleType(void)
|
||||
{
|
||||
TasmotaGlobal.module_type = (USER_MODULE == Settings->module) ? Settings->user_template_base : Settings->module;
|
||||
#ifdef ESP32
|
||||
if (TasmotaGlobal.emulated_module_type) {
|
||||
TasmotaGlobal.module_type = TasmotaGlobal.emulated_module_type;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FlashPin(uint32_t pin)
|
||||
|
@ -1781,6 +1781,11 @@ void GpioInit(void)
|
||||
mpin -= (AGPIO(GPIO_KEY1_INV_NP) - AGPIO(GPIO_KEY1));
|
||||
}
|
||||
#ifdef ESP32
|
||||
else if ((mpin >= AGPIO(GPIO_OPTION_E)) && (mpin < (AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E))) {
|
||||
TasmotaGlobal.emulated_module_type = pgm_read_byte(kModuleEmulationList + (mpin - AGPIO(GPIO_OPTION_A)));
|
||||
SetModuleType();
|
||||
mpin = GPIO_NONE;
|
||||
}
|
||||
else if ((mpin >= AGPIO(GPIO_SWT1_PD)) && (mpin < (AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES))) {
|
||||
SwitchPulldownFlag(mpin - AGPIO(GPIO_SWT1_PD));
|
||||
mpin -= (AGPIO(GPIO_SWT1_PD) - AGPIO(GPIO_SWT1));
|
||||
|
@ -181,6 +181,7 @@ struct TasmotaGlobal_t {
|
||||
uint8_t syslog_level; // Current copy of Settings->syslog_level
|
||||
uint8_t templog_level; // Temporary log level to be used by HTTP cm and Telegram
|
||||
uint8_t module_type; // Current copy of Settings->module or user template type
|
||||
uint8_t emulated_module_type; // Emulated module type as requested by ESP32
|
||||
uint8_t last_source; // Last command source
|
||||
uint8_t shutters_present; // Number of actual define shutters
|
||||
uint8_t discovery_counter; // Delayed discovery counter
|
||||
|
@ -391,7 +391,7 @@
|
||||
#undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer
|
||||
//#define USE_HOTPLUG // Add support for sensor HotPlug
|
||||
//#undef USE_DEVICE_GROUPS // Disable support for device groups (+5k6 code)
|
||||
#undef USE_PWM_DIMMER // Disable support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code)
|
||||
//#undef USE_PWM_DIMMER // Disable support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code)
|
||||
#undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm (+4k5 code)
|
||||
#undef USE_SONOFF_D1 // Disable support for Sonoff D1 Dimmer (+0k7 code)
|
||||
#undef USE_SHELLY_DIMMER // Disable support for Shelly Dimmer (+3k code)
|
||||
|
@ -133,7 +133,6 @@ String EthernetMacAddress(void);
|
||||
#undef FIRMWARE_MINIMAL // Minimal is not supported as not needed
|
||||
|
||||
// Hardware has no ESP32
|
||||
#undef USE_PWM_DIMMER
|
||||
#undef USE_EXS_DIMMER
|
||||
#undef USE_ARMTRONIX_DIMMERS
|
||||
#undef USE_SONOFF_RF
|
||||
|
@ -178,6 +178,7 @@ enum UserSelectablePins {
|
||||
GPIO_HEARTBEAT, GPIO_HEARTBEAT_INV,
|
||||
GPIO_SHIFT595_SRCLK, GPIO_SHIFT595_RCLK, GPIO_SHIFT595_OE, GPIO_SHIFT595_SER, // 74x595 Shift register
|
||||
GPIO_SOLAXX1_RTS, // Solax Inverter Serial interface
|
||||
GPIO_OPTION_E, // Emulated module
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
enum ProgramSelectablePins {
|
||||
@ -185,7 +186,7 @@ enum ProgramSelectablePins {
|
||||
GPIO_USER, // User configurable needs to be 2047
|
||||
GPIO_MAX };
|
||||
|
||||
#define MAX_OPTIONS_A 5 // Increase if more bits are used from GpioOptionABits
|
||||
#define MAX_OPTIONS_A 6 // Increase if more bits are used from GpioOptionABits
|
||||
|
||||
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
|
||||
uint32_t data; // Allow bit manipulation using SetOption
|
||||
@ -195,7 +196,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t udisplay_driver : 1; // bit 2 (v9.3.1.2) - Option_A3 - (Display) Universal display driver
|
||||
uint32_t enable_ccloader : 1; // bit 3 (v9.4.0.5) - Option_A4 - (Zigbee) Enable CCLoader using Zigbee Rx/Tx/Rst Gpios
|
||||
uint32_t rotary_mi_desk : 1; // bit 4 (v9.5.0.5) - Option_A5 - (Rotary) Enable Mi Desk emulation
|
||||
uint32_t spare05 : 1; // bit 5
|
||||
uint32_t linkind_support : 1; // bit 5 (v2022.01.1) - Option_A6 - (Light) LinkInd support
|
||||
uint32_t spare06 : 1; // bit 6
|
||||
uint32_t spare07 : 1; // bit 7
|
||||
uint32_t spare08 : 1; // bit 8
|
||||
@ -225,6 +226,23 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
};
|
||||
} GpioOptionABits;
|
||||
|
||||
enum SupportedEmulationModules {
|
||||
SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH,
|
||||
SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS_DUMMY, SONOFF_DEV, H801,
|
||||
SONOFF_SC, SONOFF_BN, SONOFF_4CHPRO, HUAFAN_SS, SONOFF_BRIDGE, SONOFF_B1, AILIGHT, SONOFF_T11, SONOFF_T12, SONOFF_T13,
|
||||
SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06,
|
||||
SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH,
|
||||
OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4,
|
||||
OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1,
|
||||
SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, SONOFF_ZB_BRIDGE,
|
||||
MAXMODULE_EMULATION };
|
||||
|
||||
#define MAX_OPTIONS_E 1 // Increase if more emulated modules are supported from kModuleEmulationList
|
||||
|
||||
const uint8_t kModuleEmulationList[] PROGMEM = {
|
||||
PWM_DIMMER // (v2022.01.1) - Option_E1 - (Light) USE_PWM_DIMMER support
|
||||
};
|
||||
|
||||
// Text in webpage Module Parameters and commands GPIOS and GPIO
|
||||
const char kSensorNames[] PROGMEM =
|
||||
D_SENSOR_NONE "|"
|
||||
@ -376,6 +394,7 @@ const char kSensorNames[] PROGMEM =
|
||||
D_SENSOR_HEARTBEAT "|" D_SENSOR_HEARTBEAT "_i|"
|
||||
D_GPIO_SHIFT595_SRCLK "|" D_GPIO_SHIFT595_RCLK "|" D_GPIO_SHIFT595_OE "|" D_GPIO_SHIFT595_SER "|"
|
||||
D_SENSOR_SOLAXX1_RTS "|"
|
||||
D_SENSOR_OPTION " E|"
|
||||
;
|
||||
|
||||
const char kSensorNamesFixed[] PROGMEM =
|
||||
@ -390,6 +409,9 @@ const char kSensorNamesFixed[] PROGMEM =
|
||||
const uint16_t kGpioNiceList[] PROGMEM = {
|
||||
GPIO_NONE, // Not used
|
||||
AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A, // Device specific options
|
||||
#ifdef ESP32
|
||||
AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E, // Device module emulation
|
||||
#endif
|
||||
AGPIO(GPIO_KEY1) + MAX_KEYS, // Buttons
|
||||
AGPIO(GPIO_KEY1_NP) + MAX_KEYS,
|
||||
#ifdef ESP32
|
||||
@ -1143,8 +1165,8 @@ typedef struct MYTMPLT {
|
||||
|
||||
#define USER_MODULE 255
|
||||
|
||||
// Supported hardware modules
|
||||
enum SupportedModules {
|
||||
// Supported ESP8266 hardware modules
|
||||
enum SupportedModulesESP8266 {
|
||||
SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH,
|
||||
SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS, SONOFF_DEV, H801,
|
||||
SONOFF_SC, SONOFF_BN, SONOFF_4CHPRO, HUAFAN_SS, SONOFF_BRIDGE, SONOFF_B1, AILIGHT, SONOFF_T11, SONOFF_T12, SONOFF_T13,
|
||||
@ -2556,7 +2578,7 @@ const mytmplt8285 kModules8285[TMP_MAXMODULE_8266 - TMP_WEMOS] PROGMEM = {
|
||||
#define USER_MODULE 255
|
||||
|
||||
// Supported hardware modules
|
||||
enum SupportedModules {
|
||||
enum SupportedModulesESP32C3 {
|
||||
WEMOS,
|
||||
MAXMODULE };
|
||||
|
||||
@ -2570,7 +2592,7 @@ const char kModuleNames[] PROGMEM =
|
||||
"ESP32C3|"
|
||||
;
|
||||
|
||||
// !!! Update this list in the same order as SupportedModules !!!
|
||||
// !!! Update this list in the same order as SupportedModulesESP32C3 !!!
|
||||
const mytmplt kModules[] PROGMEM = {
|
||||
{ // Generic ESP32C3 device
|
||||
AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, XTAL_32K_P
|
||||
@ -2606,13 +2628,13 @@ const mytmplt kModules[] PROGMEM = {
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
|
||||
/********************************************************************************************\
|
||||
* ESP32-C3 Module templates
|
||||
* ESP32-S2 Module templates
|
||||
\********************************************************************************************/
|
||||
|
||||
#define USER_MODULE 255
|
||||
|
||||
// Supported hardware modules
|
||||
enum SupportedModules {
|
||||
enum SupportedModulesESP32S2 {
|
||||
WEMOS,
|
||||
MAXMODULE };
|
||||
|
||||
@ -2626,7 +2648,7 @@ const char kModuleNames[] PROGMEM =
|
||||
"ESP32S2|"
|
||||
;
|
||||
|
||||
// !!! Update this list in the same order as SupportedModules !!!
|
||||
// !!! Update this list in the same order as SupportedModulesESP32S2 !!!
|
||||
const mytmplt kModules[] PROGMEM = {
|
||||
{ // Generic ESP32C3 device
|
||||
AGPIO(GPIO_USER), // 0 IO GPIO0, RTC_GPIO0, Strapping
|
||||
@ -2692,7 +2714,7 @@ const mytmplt kModules[] PROGMEM = {
|
||||
#define USER_MODULE 255
|
||||
|
||||
// Supported hardware modules
|
||||
enum SupportedModules {
|
||||
enum SupportedModulesESP32 {
|
||||
WEMOS,
|
||||
ESP32_CAM_AITHINKER,
|
||||
ODROID_GO,
|
||||
@ -2748,7 +2770,7 @@ const char kModuleNames[] PROGMEM =
|
||||
#endif // USE_M5STACK_CORE2
|
||||
;
|
||||
|
||||
// !!! Update this list in the same order as SupportedModules !!!
|
||||
// !!! Update this list in the same order as SupportedModulesESP32 !!!
|
||||
const mytmplt kModules[] PROGMEM = {
|
||||
{ // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32)
|
||||
AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
|
||||
|
@ -1060,11 +1060,9 @@ bool LightModuleInit(void)
|
||||
}
|
||||
#endif // ESP8266
|
||||
#ifdef USE_PWM_DIMMER
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
else if (PWM_DIMMER == TasmotaGlobal.module_type) {
|
||||
TasmotaGlobal.light_type = Settings->pwm_dimmer_cfg.pwm_count + 1;
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
#endif // USE_PWM_DIMMER
|
||||
|
||||
if (TasmotaGlobal.light_type > LT_BASIC) {
|
||||
@ -2091,6 +2089,15 @@ void LightSetOutputs(const uint16_t *cur_col_10) {
|
||||
if (TasmotaGlobal.light_type < LT_PWM6) { // only for direct PWM lights, not for Tuya, Armtronix...
|
||||
#ifdef USE_PWM_DIMMER
|
||||
uint16_t max_col = 0;
|
||||
#ifdef USE_I2C
|
||||
if (TasmotaGlobal.gpio_optiona.linkind_support) { // Option_A6
|
||||
uint8_t val = change10to8(cur_col_10[Light.pwm_offset] > 0 ? changeUIntScale(cur_col_10[Light.pwm_offset], 0, Settings->pwm_range, Light.pwm_min, Light.pwm_max) : 0);
|
||||
max_col = val;
|
||||
uint16_t chk = 65403 - val;
|
||||
uint8_t buf[] = { 0x09, 0x50, 0x01, val, 0x00, 0x00, (uint8_t)(chk >> 8), (uint8_t)(chk & 0xff) };
|
||||
I2cWriteBuffer(0x50, 0x2A, buf, sizeof(buf));
|
||||
} else
|
||||
#endif // USE_I2C
|
||||
#endif // USE_PWM_DIMMER
|
||||
for (uint32_t i = 0; i < (Light.subtype - Light.pwm_offset); i++) {
|
||||
uint16_t cur_col = cur_col_10[i + Light.pwm_offset];
|
||||
|
@ -29,6 +29,9 @@
|
||||
* https://www.amazon.com/dp/B07K67D43J
|
||||
* https://www.amazon.com/dp/B07TTGFWFM
|
||||
*
|
||||
* Template for Linkind device
|
||||
* {"NAME":"ESP32-Linkind","GPIO":[6213,8448,0,0,640,0,0,0,0,288,0,0,0,0,0,0,0,608,0,0,0,544,0,0,0,0,0,0,33,32,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_35 35
|
||||
@ -126,7 +129,11 @@ void PWMModulePreInit(void)
|
||||
device_group_count = button_count;
|
||||
|
||||
// If no relay or PWM is defined, all buttons control remote devices.
|
||||
if (!PinUsed(GPIO_REL1) && !PinUsed(GPIO_PWM1)) {
|
||||
if (!PinUsed(GPIO_REL1) && !PinUsed(GPIO_PWM1)
|
||||
#ifdef USE_I2C
|
||||
&& !PinUsed(GPIO_I2C_SCL)
|
||||
#endif // USE_I2C
|
||||
) {
|
||||
first_device_group_is_local = false;
|
||||
|
||||
// Back out the changes made in the light module under the assumtion we have a relay or PWM.
|
||||
@ -165,13 +172,16 @@ void PWMDimmerSetBrightnessLeds(int32_t bri)
|
||||
bri = ((bri == -2 && Settings->flag4.led_timeout) || !Light.power ? 0 : light_state.getBri());
|
||||
if (!bri || !Settings->flag4.led_timeout) led_timeout_seconds = 0;
|
||||
}
|
||||
uint32_t step = 256 / (leds + 1);
|
||||
|
||||
// Turn the LED's on/off.
|
||||
uint32_t level = 0;
|
||||
uint32_t step = 256 / (leds + 1);
|
||||
int32_t level = 0;
|
||||
if (TasmotaGlobal.gpio_optiona.linkind_support) {
|
||||
step = 256 / leds;
|
||||
level = -step;
|
||||
}
|
||||
led = -1;
|
||||
mask = 0;
|
||||
uint16_t pwm_led_bri = 0;
|
||||
for (uint32_t count = 0; count < leds; count++) {
|
||||
level += step;
|
||||
for (;;) {
|
||||
@ -180,8 +190,12 @@ void PWMDimmerSetBrightnessLeds(int32_t bri)
|
||||
if (!mask) mask = 1;
|
||||
if (Settings->ledmask & mask) break;
|
||||
}
|
||||
pwm_led_bri = changeUIntScale((bri > level ? bri - level : 0), 0, step, 0, Settings->pwm_range);
|
||||
analogWrite(Pin(GPIO_LED1, led), bitRead(TasmotaGlobal.led_inverted, led) ? Settings->pwm_range - pwm_led_bri : pwm_led_bri);
|
||||
if (TasmotaGlobal.gpio_optiona.linkind_support) {
|
||||
SetLedPowerIdx(led, bri > level);
|
||||
} else {
|
||||
uint16_t pwm_led_bri = changeUIntScale((bri > level ? bri - level : 0), 0, step, 0, Settings->pwm_range);
|
||||
analogWrite(Pin(GPIO_LED1, led), bitRead(TasmotaGlobal.led_inverted, led) ? Settings->pwm_range - pwm_led_bri : pwm_led_bri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -450,15 +464,13 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
|
||||
if (invert_power_button_bri_direction) {
|
||||
invert_power_button_bri_direction = false;
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
if (active_remote_pwm_dimmer)
|
||||
if (active_remote_pwm_dimmer) {
|
||||
active_remote_pwm_dimmer->power_button_increases_bri ^= 1;
|
||||
else
|
||||
} else
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
power_button_increases_bri ^= 1;
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
dgr_item = DGR_ITEM_FLAGS;
|
||||
state_updated = true;
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user