From 83a090b5a9068b8d69e2dbbdf28c5e90d7b1043b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 20 Oct 2020 15:13:12 +0200 Subject: [PATCH] Rotary driver adjusted for MiDesk if selected Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/support_rotary.ino | 198 ++++++++----------------------------- 3 files changed, 42 insertions(+), 158 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d59f76507a1a..5df12224c40b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file. - Command ``Gpios`` replaces command ``Adcs`` - Management of serial baudrate (#9554) - ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570) +- Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399) ### Fixed - Convert AdcParam parameters from versions before v9.0.0.2 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7c5f399d0dc2..cfed7f363025 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -88,6 +88,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - IRremoteESP8266 library from v2.7.10 to v2.7.11 - NeoPixelBus library from v2.5.0.09 to v2.6.0 - Management of serial baudrate (#9554) +- Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399) ### Fixed - Ledlink blink when no network connected regression from v8.3.1.4 (#9292) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 56e39ee16bc6..361a130dd95b 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -37,57 +37,30 @@ #define ROTARY_MAX_STEPS 10 // Rotary step boundary #endif -#define ROTARY_OPTION1 // Up to 4 interrupts and pulses per step -//#define ROTARY_OPTION2 // Up to 4 interrupts but 1 pulse per step -//#define ROTARY_OPTION3 // 1 interrupt and pulse per step - -#ifdef ROTARY_OPTION1 -// up to 4 pulses per step -const uint8_t rotary_dimmer_increment = 100 / (ROTARY_MAX_STEPS * 3); // Dimmer 1..100 = 100 -const uint8_t rotary_ct_increment = 350 / (ROTARY_MAX_STEPS * 3); // Ct 153..500 = 347 -const uint8_t rotary_color_increment = 360 / (ROTARY_MAX_STEPS * 3); // Hue 0..359 = 360 -#endif // ROTARY_OPTION1 - -#ifdef ROTARY_OPTION2 -// 1 pulse per step -const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 -const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 -const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 -#endif // ROTARY_OPTION2 - -#ifdef ROTARY_OPTION3 -// 1 pulse per step -const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 -const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 -const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 -const uint8_t ROTARY_DEBOUNCE = 10; // Debounce time in milliseconds -#endif // ROTARY_OPTION3 - -const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds +// (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_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds +const uint8_t ROTARY_DEBOUNCE = 10; // Debounce time in milliseconds struct ROTARY { + uint8_t model = 1; bool present = false; } Rotary; struct tEncoder { -#ifdef ROTARY_OPTION1 - volatile uint8_t state = 0; - volatile int8_t pina = -1; -#endif // ROTARY_OPTION1 -#ifdef ROTARY_OPTION2 - volatile uint16_t store; - volatile uint8_t prev_next_code; - volatile int8_t pina = -1; -#endif // ROTARY_OPTION2 -#ifdef ROTARY_OPTION3 volatile uint32_t debounce = 0; -#endif // ROTARY_OPTION3 volatile int8_t direction = 0; // Control consistent direction - volatile int8_t pinb = -1; + volatile uint8_t state = 0; volatile uint8_t position = 128; uint8_t last_position = 128; - int8_t abs_position[2] = { 0 }; uint8_t timeout = 0; // Disallow direction change within 0.5 second + int8_t abs_position[2] = { 0 }; + int8_t pina = -1; + int8_t pinb = -1; bool changed = false; volatile bool busy = false; }; @@ -117,63 +90,12 @@ bool RotaryButtonPressed(uint32_t button_index) { return false; } -void ICACHE_RAM_ATTR RotaryIsrArg(void *arg) { +void ICACHE_RAM_ATTR RotaryIsrArgMiDesk(void *arg) { tEncoder* encoder = static_cast(arg); if (encoder->busy) { return; } -#ifdef ROTARY_OPTION1 // https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h -/* - uint8_t p1val = digitalRead(encoder->pina); - uint8_t p2val = digitalRead(encoder->pinb); - uint8_t state = encoder->state & 3; - if (p1val) { state |= 4; } - if (p2val) { state |= 8; } - encoder->state = (state >> 2); - switch (state) { - case 1: case 7: case 8: case 14: - encoder->position++; - return; - case 2: case 4: case 11: case 13: - encoder->position--; - return; - case 3: case 12: - encoder->position += 2; - return; - case 6: case 9: - encoder->position -= 2; - return; - } -*/ - -/* - uint8_t p1val = digitalRead(encoder->pina); - uint8_t p2val = digitalRead(encoder->pinb); - uint8_t state = encoder->state & 3; - if (p1val) { state |= 4; } - if (p2val) { state |= 8; } - encoder->state = (state >> 2); - int direction = 0; - int multiply = 1; - switch (state) { - case 3: case 12: - multiply = 2; - case 1: case 7: case 8: case 14: - direction = 1; - break; - case 6: case 9: - multiply = 2; - case 2: case 4: case 11: case 13: - direction = -1; - break; - } - if ((0 == encoder->direction) || (direction == encoder->direction)) { - encoder->position += (direction * multiply); - encoder->direction = direction; - } -*/ - uint8_t state = encoder->state & 3; if (digitalRead(encoder->pina)) { state |= 4; } if (digitalRead(encoder->pinb)) { state |= 8; } @@ -192,58 +114,13 @@ void ICACHE_RAM_ATTR RotaryIsrArg(void *arg) { encoder->position -= 2; return; } -#endif // ROTARY_OPTION1 +} -#ifdef ROTARY_OPTION2 - // https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h -/* - const uint16_t rot_enc = 0b0110100110010110; - - uint8_t p1val = digitalRead(encoder->pinb); - uint8_t p2val = digitalRead(encoder->pina); - uint8_t t = encoder->prev_next_code; - t <<= 2; - if (p1val) { t |= 0x02; } - if (p2val) { t |= 0x01; } - t &= 0x0f; - encoder->prev_next_code = t; - - // If valid then store as 16 bit data. - if (rot_enc & (1 << t)) { - encoder->store = (encoder->store << 4) | encoder->prev_next_code; - if (encoder->store == 0xd42b) { encoder->position++; } - else if (encoder->store == 0xe817) { encoder->position--; } - else if ((encoder->store & 0xff) == 0x2b) { encoder->position--; } - else if ((encoder->store & 0xff) == 0x17) { encoder->position++; } - } -*/ - const uint16_t rot_enc = 0b0110100110010110; - - uint8_t p1val = digitalRead(encoder->pinb); - uint8_t p2val = digitalRead(encoder->pina); - uint8_t t = encoder->prev_next_code; - t <<= 2; - if (p1val) { t |= 0x02; } - if (p2val) { t |= 0x01; } - t &= 0x0f; - encoder->prev_next_code = t; - - // If valid then store as 16 bit data. - if (rot_enc & (1 << t)) { - encoder->store = (encoder->store << 4) | encoder->prev_next_code; - int direction = 0; - if (encoder->store == 0xd42b) { direction = 1; } - else if (encoder->store == 0xe817) { direction = -1; } - else if ((encoder->store & 0xff) == 0x2b) { direction = -1; } - else if ((encoder->store & 0xff) == 0x17) { direction = 1; } - if ((0 == encoder->direction) || (direction == encoder->direction)) { - encoder->position += direction; - encoder->direction = direction; - } - } -#endif // ROTARY_OPTION2 +void ICACHE_RAM_ATTR RotaryIsrArg(void *arg) { + tEncoder* encoder = static_cast(arg); + + if (encoder->busy) { return; } -#ifdef ROTARY_OPTION3 // Theo Arends uint32_t time = millis(); if ((encoder->debounce < time) || (encoder->debounce > time + ROTARY_DEBOUNCE)) { @@ -254,24 +131,29 @@ void ICACHE_RAM_ATTR RotaryIsrArg(void *arg) { } encoder->debounce = time + ROTARY_DEBOUNCE; // Experimental debounce } -#endif // ROTARY_OPTION3 } void RotaryInit(void) { Rotary.present = false; + Rotary.model = 1; +#ifdef ESP8266 + if (MI_DESK_LAMP == my_module_type) { + Rotary.model = 0; + } +#endif // ESP8266 for (uint32_t index = 0; index < MAX_ROTARIES; index++) { + Encoder[index].pinb = -1; if (PinUsed(GPIO_ROT1A, index) && PinUsed(GPIO_ROT1B, index)) { - Encoder[index].pinb = Pin(GPIO_ROT1B, index); - pinMode(Encoder[index].pinb, INPUT_PULLUP); -#ifdef ROTARY_OPTION3 - pinMode(Pin(GPIO_ROT1A, index), INPUT_PULLUP); - attachInterruptArg(Pin(GPIO_ROT1A, index), RotaryIsrArg, &Encoder[index], FALLING); -#else Encoder[index].pina = Pin(GPIO_ROT1A, index); pinMode(Encoder[index].pina, INPUT_PULLUP); - attachInterruptArg(Pin(GPIO_ROT1A, index), RotaryIsrArg, &Encoder[index], CHANGE); - attachInterruptArg(Pin(GPIO_ROT1B, index), RotaryIsrArg, &Encoder[index], CHANGE); -#endif + Encoder[index].pinb = Pin(GPIO_ROT1B, index); + pinMode(Encoder[index].pinb, INPUT_PULLUP); + if (0 == Rotary.model) { + attachInterruptArg(Encoder[index].pina, RotaryIsrArgMiDesk, &Encoder[index], CHANGE); + attachInterruptArg(Encoder[index].pinb, RotaryIsrArgMiDesk, &Encoder[index], CHANGE); + } else { + attachInterruptArg(Encoder[index].pina, RotaryIsrArg, &Encoder[index], FALLING); + } } Rotary.present |= (Encoder[index].pinb > -1); } @@ -320,20 +202,20 @@ void RotaryHandler(void) { if (0 == index) { // Rotary1 if (button_pressed) { if (second_rotary) { // Color RGB - LightColorOffset(rotary_position * rotary_color_increment); + LightColorOffset(rotary_position * rotary_color_increment[Rotary.model]); } else { // Color Temperature or Color RGB - if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { - LightColorOffset(rotary_position * rotary_color_increment); + if (!LightColorTempOffset(rotary_position * rotary_ct_increment[Rotary.model])) { + LightColorOffset(rotary_position * rotary_color_increment[Rotary.model]); } } } else { // Dimmer RGBCW or RGB only if second rotary - LightDimmerOffset(second_rotary ? 1 : 0, rotary_position * rotary_dimmer_increment); + LightDimmerOffset(second_rotary ? 1 : 0, rotary_position * rotary_dimmer_increment[Rotary.model]); } } else { // Rotary2 if (button_pressed) { // Color Temperature - LightColorTempOffset(rotary_position * rotary_ct_increment); + LightColorTempOffset(rotary_position * rotary_ct_increment[Rotary.model]); } else { // Dimmer CW - LightDimmerOffset(2, rotary_position * rotary_dimmer_increment); + LightDimmerOffset(2, rotary_position * rotary_dimmer_increment[Rotary.model]); } } } else {