mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 12:46:34 +00:00
Support rotary encoder on Shelly Dimmer
Support rotary encoder on Shelly Dimmer (#10407)
This commit is contained in:
parent
98b529ce7b
commit
d319bc8ecb
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
## [9.2.0.3]
|
## [9.2.0.3]
|
||||||
### Added
|
### Added
|
||||||
- Support for time proportioned (``#define USE_TIMEPROP``) and optional PID (``#define USE_PID``) relay control (#10412)
|
- Support for time proportioned (``#define USE_TIMEPROP``) and optional PID (``#define USE_PID``) relay control (#10412)
|
||||||
|
- Support rotary encoder on Shelly Dimmer (#10407)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
- ESP32 switch from default SPIFFS to default LittleFS file system loosing current (zigbee) files
|
- ESP32 switch from default SPIFFS to default LittleFS file system loosing current (zigbee) files
|
||||||
|
@ -76,6 +76,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
|||||||
- Support for disabling 38kHz IR modulation using ``#define IR_SEND_USE_MODULATION false`` [#10301](https://github.com/arendst/Tasmota/issues/10301)
|
- Support for disabling 38kHz IR modulation using ``#define IR_SEND_USE_MODULATION false`` [#10301](https://github.com/arendst/Tasmota/issues/10301)
|
||||||
- Support for SPI display driver for ST7789 TFT by Gerhard Mutz [#9037](https://github.com/arendst/Tasmota/issues/9037)
|
- Support for SPI display driver for ST7789 TFT by Gerhard Mutz [#9037](https://github.com/arendst/Tasmota/issues/9037)
|
||||||
- Support for time proportioned (``#define USE_TIMEPROP``) and optional PID (``#define USE_PID``) relay control [#10412](https://github.com/arendst/Tasmota/issues/10412)
|
- Support for time proportioned (``#define USE_TIMEPROP``) and optional PID (``#define USE_PID``) relay control [#10412](https://github.com/arendst/Tasmota/issues/10412)
|
||||||
|
- Support rotary encoder on Shelly Dimmer [#10407](https://github.com/arendst/Tasmota/issues/10407)
|
||||||
- Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630)
|
- Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630)
|
||||||
- SPI display driver SSD1331 Color oled by Jeroen Vermeulen [#10376](https://github.com/arendst/Tasmota/issues/10376)
|
- SPI display driver SSD1331 Color oled by Jeroen Vermeulen [#10376](https://github.com/arendst/Tasmota/issues/10376)
|
||||||
|
|
||||||
|
@ -884,7 +884,12 @@ void CmndSetoption(void)
|
|||||||
#endif
|
#endif
|
||||||
#if (defined(USE_IR_REMOTE) && defined(USE_IR_RECEIVE)) || defined(USE_IR_REMOTE_FULL)
|
#if (defined(USE_IR_REMOTE) && defined(USE_IR_RECEIVE)) || defined(USE_IR_REMOTE_FULL)
|
||||||
if (P_IR_UNKNOW_THRESHOLD == pindex) {
|
if (P_IR_UNKNOW_THRESHOLD == pindex) {
|
||||||
IrReceiveUpdateThreshold();
|
IrReceiveUpdateThreshold(); // SetOption38
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef ROTARY_V1
|
||||||
|
if (P_ROTARY_MAX_STEP == pindex) {
|
||||||
|
RotaryInitMaxSteps(); // SetOption43
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,17 +46,15 @@
|
|||||||
#define ROTARY_DEBOUNCE 10 // Debounce time in milliseconds
|
#define ROTARY_DEBOUNCE 10 // Debounce time in milliseconds
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// (0) = Mi Desk lamp (1) = Normal rotary
|
|
||||||
// ---------------------------- ----------------------
|
|
||||||
const uint8_t rotary_dimmer_increment[2] = { 100 / (ROTARY_MAX_STEPS * 3), 100 / ROTARY_MAX_STEPS }; // Dimmer 1..100 = 100
|
|
||||||
const uint8_t rotary_ct_increment[2] = { 350 / (ROTARY_MAX_STEPS * 3), 350 / ROTARY_MAX_STEPS }; // Ct 153..500 = 347
|
|
||||||
const uint8_t rotary_color_increment[2] = { 360 / (ROTARY_MAX_STEPS * 3), 360 / ROTARY_MAX_STEPS }; // Hue 0..359 = 360
|
|
||||||
const uint8_t rotary_offset = 128;
|
const uint8_t rotary_offset = 128;
|
||||||
const int8_t rotary_state_pos[16] = { 0, 1, -1, 2, -1, 0, -2, 1, 1, -2, 0, -1, 2, -1, 1, 0 };
|
const int8_t rotary_state_pos[16] = { 0, 1, -1, 2, -1, 0, -2, 1, 1, -2, 0, -1, 2, -1, 1, 0 };
|
||||||
|
|
||||||
struct ROTARY {
|
struct ROTARY {
|
||||||
uint8_t no_pullup_mask_a = 0; // Rotary A pull-up bitmask flags
|
uint8_t no_pullup_mask_a = 0; // Rotary A pull-up bitmask flags
|
||||||
uint8_t no_pullup_mask_b = 0; // Rotary B pull-up bitmask flags
|
uint8_t no_pullup_mask_b = 0; // Rotary B pull-up bitmask flags
|
||||||
|
uint8_t dimmer_increment;
|
||||||
|
uint8_t ct_increment;
|
||||||
|
uint8_t color_increment;
|
||||||
uint8_t model;
|
uint8_t model;
|
||||||
bool present;
|
bool present;
|
||||||
} Rotary;
|
} Rotary;
|
||||||
@ -132,14 +130,29 @@ void ICACHE_RAM_ATTR RotaryIsrArg(void *arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RotaryInitMaxSteps(void) {
|
||||||
|
if ((0 == Settings.param[P_ROTARY_MAX_STEP]) || (Settings.param[P_ROTARY_MAX_STEP] > 100)) {
|
||||||
|
Settings.param[P_ROTARY_MAX_STEP] = ROTARY_MAX_STEPS; // SetOption43
|
||||||
|
}
|
||||||
|
uint8_t max_steps = Settings.param[P_ROTARY_MAX_STEP];
|
||||||
|
if (!Rotary.model) { max_steps *= 3; }
|
||||||
|
Rotary.dimmer_increment = 100 / max_steps; // Dimmer 1..100 = 100
|
||||||
|
Rotary.ct_increment = 350 / max_steps; // Ct 153..500 = 347
|
||||||
|
Rotary.color_increment = 360 / max_steps; // Hue 0..359 = 360
|
||||||
|
}
|
||||||
|
|
||||||
void RotaryInit(void) {
|
void RotaryInit(void) {
|
||||||
Rotary.present = false;
|
Rotary.present = false;
|
||||||
|
|
||||||
Rotary.model = 1;
|
Rotary.model = 1;
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (MI_DESK_LAMP == TasmotaGlobal.module_type) {
|
if (MI_DESK_LAMP == TasmotaGlobal.module_type) {
|
||||||
Rotary.model = 0;
|
Rotary.model = 0;
|
||||||
}
|
}
|
||||||
#endif // ESP8266
|
#endif // ESP8266
|
||||||
|
|
||||||
|
RotaryInitMaxSteps();
|
||||||
|
|
||||||
for (uint32_t index = 0; index < MAX_ROTARIES; index++) {
|
for (uint32_t index = 0; index < MAX_ROTARIES; index++) {
|
||||||
Encoder[index].pinb = -1;
|
Encoder[index].pinb = -1;
|
||||||
if (PinUsed(GPIO_ROT1A, index) && PinUsed(GPIO_ROT1B, index)) {
|
if (PinUsed(GPIO_ROT1A, index) && PinUsed(GPIO_ROT1B, index)) {
|
||||||
@ -196,7 +209,7 @@ void RotaryHandler(void) {
|
|||||||
|
|
||||||
bool button_pressed = (Button.hold_timer[index]); // Button is pressed: set color temperature
|
bool button_pressed = (Button.hold_timer[index]); // Button is pressed: set color temperature
|
||||||
if (button_pressed) { Encoder[index].changed = true; }
|
if (button_pressed) { Encoder[index].changed = true; }
|
||||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position);
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position);
|
||||||
|
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||||
@ -204,16 +217,16 @@ void RotaryHandler(void) {
|
|||||||
if (0 == index) { // Rotary1
|
if (0 == index) { // Rotary1
|
||||||
if (button_pressed) {
|
if (button_pressed) {
|
||||||
if (second_rotary) { // Color RGB
|
if (second_rotary) { // Color RGB
|
||||||
LightColorOffset(rotary_position * rotary_color_increment[Rotary.model]);
|
LightColorOffset(rotary_position * Rotary.color_increment);
|
||||||
} else { // Color Temperature or Color RGB
|
} else { // Color Temperature or Color RGB
|
||||||
if (!LightColorTempOffset(rotary_position * rotary_ct_increment[Rotary.model])) {
|
if (!LightColorTempOffset(rotary_position * Rotary.ct_increment)) {
|
||||||
LightColorOffset(rotary_position * rotary_color_increment[Rotary.model]);
|
LightColorOffset(rotary_position * Rotary.color_increment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // Dimmer RGBCW or RGB only if second rotary
|
} else { // Dimmer RGBCW or RGB only if second rotary
|
||||||
uint32_t dimmer_index = second_rotary ? 1 : 0;
|
uint32_t dimmer_index = second_rotary ? 1 : 0;
|
||||||
if (!Settings.flag4.rotary_poweron_dimlow || TasmotaGlobal.power) { // SetOption113 - On rotary dial after power off set dimmer low
|
if (!Settings.flag4.rotary_poweron_dimlow || TasmotaGlobal.power) { // SetOption113 - On rotary dial after power off set dimmer low
|
||||||
LightDimmerOffset(dimmer_index, rotary_position * rotary_dimmer_increment[Rotary.model]);
|
LightDimmerOffset(dimmer_index, rotary_position * Rotary.dimmer_increment);
|
||||||
} else {
|
} else {
|
||||||
if (rotary_position > 0) { // Only power on if rotary increase
|
if (rotary_position > 0) { // Only power on if rotary increase
|
||||||
LightDimmerOffset(dimmer_index, -LightGetDimmer(dimmer_index) + ROTARY_START_DIM);
|
LightDimmerOffset(dimmer_index, -LightGetDimmer(dimmer_index) + ROTARY_START_DIM);
|
||||||
@ -222,9 +235,9 @@ void RotaryHandler(void) {
|
|||||||
}
|
}
|
||||||
} else { // Rotary2
|
} else { // Rotary2
|
||||||
if (button_pressed) { // Color Temperature
|
if (button_pressed) { // Color Temperature
|
||||||
LightColorTempOffset(rotary_position * rotary_ct_increment[Rotary.model]);
|
LightColorTempOffset(rotary_position * Rotary.ct_increment);
|
||||||
} else { // Dimmer CW
|
} else { // Dimmer CW
|
||||||
LightDimmerOffset(2, rotary_position * rotary_dimmer_increment[Rotary.model]);
|
LightDimmerOffset(2, rotary_position * Rotary.dimmer_increment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -233,8 +246,8 @@ void RotaryHandler(void) {
|
|||||||
if (Encoder[index].abs_position[button_pressed] < 0) {
|
if (Encoder[index].abs_position[button_pressed] < 0) {
|
||||||
Encoder[index].abs_position[button_pressed] = 0;
|
Encoder[index].abs_position[button_pressed] = 0;
|
||||||
}
|
}
|
||||||
if (Encoder[index].abs_position[button_pressed] > ROTARY_MAX_STEPS) {
|
if (Encoder[index].abs_position[button_pressed] > Settings.param[P_ROTARY_MAX_STEP]) { // SetOption43 - Rotary steps
|
||||||
Encoder[index].abs_position[button_pressed] = ROTARY_MAX_STEPS;
|
Encoder[index].abs_position[button_pressed] = Settings.param[P_ROTARY_MAX_STEP]; // SetOption43 - Rotary steps
|
||||||
}
|
}
|
||||||
Response_P(PSTR("{\"Rotary%d\":{\"Pos1\":%d,\"Pos2\":%d}}"), index +1, Encoder[index].abs_position[0], Encoder[index].abs_position[1]);
|
Response_P(PSTR("{\"Rotary%d\":{\"Pos1\":%d,\"Pos2\":%d}}"), index +1, Encoder[index].abs_position[0], Encoder[index].abs_position[1]);
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
|
@ -254,7 +254,7 @@ enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER };
|
|||||||
|
|
||||||
enum SettingsParamIndex { P_HOLD_TIME, P_MAX_POWER_RETRY, P_BACKLOG_DELAY, P_MDNS_DELAYED_START, P_BOOT_LOOP_OFFSET, P_RGB_REMAP, P_IR_UNKNOW_THRESHOLD, // SetOption32 .. SetOption38
|
enum SettingsParamIndex { P_HOLD_TIME, P_MAX_POWER_RETRY, P_BACKLOG_DELAY, P_MDNS_DELAYED_START, P_BOOT_LOOP_OFFSET, P_RGB_REMAP, P_IR_UNKNOW_THRESHOLD, // SetOption32 .. SetOption38
|
||||||
P_CSE7766_INVALID_POWER, P_HOLD_IGNORE, P_ARP_GRATUITOUS, P_OVER_TEMP, // SetOption39 .. SetOption42
|
P_CSE7766_INVALID_POWER, P_HOLD_IGNORE, P_ARP_GRATUITOUS, P_OVER_TEMP, // SetOption39 .. SetOption42
|
||||||
P_ex_DIMMER_MAX, P_ex_TUYA_VOLTAGE_ID, P_ex_TUYA_CURRENT_ID, P_ex_TUYA_POWER_ID, // SetOption43 .. SetOption46
|
P_ROTARY_MAX_STEP, P_ex_TUYA_VOLTAGE_ID, P_ex_TUYA_CURRENT_ID, P_ex_TUYA_POWER_ID, // SetOption43 .. SetOption46
|
||||||
P_ex_ENERGY_TARIFF1, P_ex_ENERGY_TARIFF2, // SetOption47 .. SetOption48
|
P_ex_ENERGY_TARIFF1, P_ex_ENERGY_TARIFF2, // SetOption47 .. SetOption48
|
||||||
P_MAX_PARAM8 }; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
|
P_MAX_PARAM8 }; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user