mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 20:56:35 +00:00
Add SO98 to control user rotary support
This commit is contained in:
parent
8e80bc8f80
commit
0cc1dd957b
@ -29,7 +29,7 @@
|
|||||||
| USE_HOTPLUG | - | - | - | - | - | - | - |
|
| USE_HOTPLUG | - | - | - | - | - | - | - |
|
||||||
| | | | | | | | |
|
| | | | | | | | |
|
||||||
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks
|
||||||
| ROTARY_V1 | - | - | - | - | - | - | - |
|
| ROTARY_V1 | - | - | x | - | x | - | - |
|
||||||
| USE_SONOFF_RF | - | - | x | x | x | - | - |
|
| USE_SONOFF_RF | - | - | x | x | x | - | - |
|
||||||
| USE_RF_FLASH | - | - | x | x | x | - | - |
|
| USE_RF_FLASH | - | - | x | x | x | - | - |
|
||||||
| USE_SONOFF_SC | - | - | x | x | x | - | - |
|
| USE_SONOFF_SC | - | - | x | x | x | - | - |
|
||||||
|
@ -66,6 +66,8 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||||||
- Add command ``Rule0`` to change global rule parameters
|
- Add command ``Rule0`` to change global rule parameters
|
||||||
- Add command ``Time 4`` to display timestamp using milliseconds (#8537)
|
- Add command ``Time 4`` to display timestamp using milliseconds (#8537)
|
||||||
- Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616)
|
- Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616)
|
||||||
|
- Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1)
|
||||||
|
- Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0)
|
||||||
- Add command ``Module2`` to configure fallback module on fast reboot (#8464)
|
- Add command ``Module2`` to configure fallback module on fast reboot (#8464)
|
||||||
- Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491)
|
- Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491)
|
||||||
- Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3``
|
- Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3``
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
### 8.3.1.6 20200617
|
### 8.3.1.6 20200617
|
||||||
|
|
||||||
- Add command ``Module2`` to configure fallback module on fast reboot (#8464)
|
- Add command ``Module2`` to configure fallback module on fast reboot (#8464)
|
||||||
|
- Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1)
|
||||||
|
- Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0)
|
||||||
- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff
|
- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff
|
||||||
- Add library to be used for decoding Teleinfo (French Metering Smart Meter)
|
- Add library to be used for decoding Teleinfo (French Metering Smart Meter)
|
||||||
- Add support for single wire LMT01 temperature Sensor by justifiably (#8713)
|
- Add support for single wire LMT01 temperature Sensor by justifiably (#8713)
|
||||||
|
@ -430,6 +430,7 @@
|
|||||||
|
|
||||||
// -- Optional modules ----------------------------
|
// -- Optional modules ----------------------------
|
||||||
#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp (+0k8 code)
|
#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp (+0k8 code)
|
||||||
|
#define ROTARY_MAX_STEPS 10 // Rotary step boundary
|
||||||
#define USE_SONOFF_RF // Add support for Sonoff Rf Bridge (+3k2 code)
|
#define USE_SONOFF_RF // Add support for Sonoff Rf Bridge (+3k2 code)
|
||||||
#define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+2k7 code)
|
#define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+2k7 code)
|
||||||
#define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code)
|
#define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code)
|
||||||
|
@ -115,9 +115,9 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||||||
uint32_t compress_rules_cpu : 1; // bit 11 (v8.2.0.6) - SetOption93 - Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick
|
uint32_t compress_rules_cpu : 1; // bit 11 (v8.2.0.6) - SetOption93 - Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick
|
||||||
uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855
|
uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855
|
||||||
uint32_t network_wifi : 1; // bit 13 (v8.3.1.3) - CMND_WIFI
|
uint32_t network_wifi : 1; // bit 13 (v8.3.1.3) - CMND_WIFI
|
||||||
uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) = CMND_ETHERNET
|
uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) - CMND_ETHERNET
|
||||||
uint32_t tuyamcu_baudrate : 1; // bit 15 (v8.3.1.6) - SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200)
|
uint32_t tuyamcu_baudrate : 1; // bit 15 (v8.3.1.6) - SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200)
|
||||||
uint32_t spare16 : 1;
|
uint32_t rotary_uses_rules : 1; // bit 16 (v8.3.1.6) - SetOption98 - Use rules instead of light control
|
||||||
uint32_t spare17 : 1;
|
uint32_t spare17 : 1;
|
||||||
uint32_t spare18 : 1;
|
uint32_t spare18 : 1;
|
||||||
uint32_t spare19 : 1;
|
uint32_t spare19 : 1;
|
||||||
|
@ -302,7 +302,7 @@ void ButtonHandler(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(USE_LIGHT) && defined(ROTARY_V1)
|
#ifdef ROTARY_V1
|
||||||
if (!((0 == button_index) && RotaryButtonPressed())) {
|
if (!((0 == button_index) && RotaryButtonPressed())) {
|
||||||
#endif
|
#endif
|
||||||
if (!Settings.flag3.mqtt_buttons && single_press && SendKey(KEY_BUTTON, button_index + Button.press_counter[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
if (!Settings.flag3.mqtt_buttons && single_press && SendKey(KEY_BUTTON, button_index + Button.press_counter[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||||
@ -344,7 +344,7 @@ void ButtonHandler(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(USE_LIGHT) && defined(ROTARY_V1)
|
#ifdef ROTARY_V1
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Button.press_counter[button_index] = 0;
|
Button.press_counter[button_index] = 0;
|
||||||
|
@ -17,35 +17,72 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_LIGHT
|
|
||||||
#ifdef ROTARY_V1
|
#ifdef ROTARY_V1
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Rotary support
|
* Rotary support
|
||||||
|
*
|
||||||
|
* Supports full range in 10 steps of the Rotary Encoder:
|
||||||
|
* - Light Dimmer
|
||||||
|
* - Light Color for RGB lights when Button1 pressed
|
||||||
|
* - Light Color Temperature for CW lights when Button1 pressed
|
||||||
|
*
|
||||||
|
* _______ _______
|
||||||
|
* GPIO_ROT1A ______| |_______| |______ GPIO_ROT1A
|
||||||
|
* negative <-- _______ _______ __ --> positive
|
||||||
|
* GPIO_ROT1B __| |_______| |_______| GPIO_ROT1B
|
||||||
|
*
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define ROTARY_OPTION1
|
#ifndef ROTARY_MAX_STEPS
|
||||||
//#define ROTARY_OPTION2
|
#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
|
#ifdef ROTARY_OPTION1
|
||||||
const int8_t rotary_dimmer_increment = 1;
|
// up to 4 pulses per step
|
||||||
const int8_t rotary_ct_increment = 2;
|
const uint8_t rotary_dimmer_increment = 100 / (ROTARY_MAX_STEPS * 3); // Dimmer 1..100 = 100
|
||||||
const int8_t rotary_color_increment = 4;
|
const uint8_t rotary_ct_increment = 350 / (ROTARY_MAX_STEPS * 3); // Ct 153..500 = 347
|
||||||
#endif
|
const uint8_t rotary_color_increment = 360 / (ROTARY_MAX_STEPS * 3); // Hue 0..359 = 360
|
||||||
|
#endif // ROTARY_OPTION1
|
||||||
|
|
||||||
#ifdef ROTARY_OPTION2
|
#ifdef ROTARY_OPTION2
|
||||||
const int8_t rotary_dimmer_increment = 2;
|
// 1 pulse per step
|
||||||
const int8_t rotary_ct_increment = 8;
|
const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100
|
||||||
const int8_t rotary_color_increment = 8;
|
const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347
|
||||||
#endif
|
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
|
||||||
|
#endif // ROTARY_OPTION3
|
||||||
|
|
||||||
|
const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds
|
||||||
|
|
||||||
struct ROTARY {
|
struct ROTARY {
|
||||||
uint8_t present = 0;
|
#ifdef ROTARY_OPTION1
|
||||||
uint8_t state = 0;
|
uint8_t state = 0;
|
||||||
uint8_t prevNextCode;
|
#endif // ROTARY_OPTION1
|
||||||
|
#ifdef ROTARY_OPTION2
|
||||||
uint16_t store;
|
uint16_t store;
|
||||||
int8_t position = 128;
|
uint8_t prev_next_code;
|
||||||
int8_t last_position = 128;
|
#endif // ROTARY_OPTION2
|
||||||
uint8_t changed = 0;
|
#ifdef ROTARY_OPTION3
|
||||||
|
uint32_t debounce = 0;
|
||||||
|
#endif // ROTARY_OPTION3
|
||||||
|
int8_t abs_position1 = 0;
|
||||||
|
int8_t abs_position2 = 0;
|
||||||
|
int8_t direction = 0; // Control consistent direction
|
||||||
|
uint8_t present = 0;
|
||||||
|
uint8_t position = 128;
|
||||||
|
uint8_t last_position = 128;
|
||||||
|
uint8_t timeout = 0; // Disallow direction change within 0.5 second
|
||||||
|
bool changed = false;
|
||||||
bool busy = false;
|
bool busy = false;
|
||||||
} Rotary;
|
} Rotary;
|
||||||
|
|
||||||
@ -53,10 +90,18 @@ struct ROTARY {
|
|||||||
|
|
||||||
void update_rotary(void) ICACHE_RAM_ATTR;
|
void update_rotary(void) ICACHE_RAM_ATTR;
|
||||||
void update_rotary(void) {
|
void update_rotary(void) {
|
||||||
if (Rotary.busy || !LightPowerIRAM()) { return; }
|
if (Rotary.busy) { return; }
|
||||||
|
bool powered_on = (power);
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||||
|
powered_on = (LightPowerIRAM());
|
||||||
|
}
|
||||||
|
#endif // USE_LIGHT
|
||||||
|
if (!powered_on) { return; }
|
||||||
|
|
||||||
#ifdef ROTARY_OPTION1
|
#ifdef ROTARY_OPTION1
|
||||||
// https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h
|
// https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h
|
||||||
|
/*
|
||||||
uint8_t p1val = digitalRead(Pin(GPIO_ROT1A));
|
uint8_t p1val = digitalRead(Pin(GPIO_ROT1A));
|
||||||
uint8_t p2val = digitalRead(Pin(GPIO_ROT1B));
|
uint8_t p2val = digitalRead(Pin(GPIO_ROT1B));
|
||||||
uint8_t state = Rotary.state & 3;
|
uint8_t state = Rotary.state & 3;
|
||||||
@ -77,35 +122,105 @@ void update_rotary(void) {
|
|||||||
Rotary.position -= 2;
|
Rotary.position -= 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
*/
|
||||||
|
uint8_t p1val = digitalRead(Pin(GPIO_ROT1A));
|
||||||
|
uint8_t p2val = digitalRead(Pin(GPIO_ROT1B));
|
||||||
|
uint8_t state = Rotary.state & 3;
|
||||||
|
if (p1val) { state |= 4; }
|
||||||
|
if (p2val) { state |= 8; }
|
||||||
|
Rotary.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 == Rotary.direction) || (direction == Rotary.direction)) {
|
||||||
|
Rotary.position += (direction * multiply);
|
||||||
|
Rotary.direction = direction;
|
||||||
|
}
|
||||||
|
#endif // ROTARY_OPTION1
|
||||||
|
|
||||||
#ifdef ROTARY_OPTION2
|
#ifdef ROTARY_OPTION2
|
||||||
// https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h
|
// https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h
|
||||||
|
/*
|
||||||
const uint16_t rot_enc = 0b0110100110010110;
|
const uint16_t rot_enc = 0b0110100110010110;
|
||||||
|
|
||||||
uint8_t p1val = digitalRead(Pin(GPIO_ROT1B));
|
uint8_t p1val = digitalRead(Pin(GPIO_ROT1B));
|
||||||
uint8_t p2val = digitalRead(Pin(GPIO_ROT1A));
|
uint8_t p2val = digitalRead(Pin(GPIO_ROT1A));
|
||||||
uint8_t t = Rotary.prevNextCode;
|
uint8_t t = Rotary.prev_next_code;
|
||||||
t <<= 2;
|
t <<= 2;
|
||||||
if (p1val) { t |= 0x02; }
|
if (p1val) { t |= 0x02; }
|
||||||
if (p2val) { t |= 0x01; }
|
if (p2val) { t |= 0x01; }
|
||||||
t &= 0x0f;
|
t &= 0x0f;
|
||||||
Rotary.prevNextCode = t;
|
Rotary.prev_next_code = t;
|
||||||
|
|
||||||
// If valid then store as 16 bit data.
|
// If valid then store as 16 bit data.
|
||||||
if (rot_enc & (1 << t)) {
|
if (rot_enc & (1 << t)) {
|
||||||
Rotary.store = (Rotary.store << 4) | Rotary.prevNextCode;
|
Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code;
|
||||||
if (Rotary.store == 0xd42b) { Rotary.position++; }
|
if (Rotary.store == 0xd42b) { Rotary.position++; }
|
||||||
else if (Rotary.store == 0xe817) { Rotary.position--; }
|
else if (Rotary.store == 0xe817) { Rotary.position--; }
|
||||||
else if ((Rotary.store & 0xff) == 0x2b) { Rotary.position--; }
|
else if ((Rotary.store & 0xff) == 0x2b) { Rotary.position--; }
|
||||||
else if ((Rotary.store & 0xff) == 0x17) { Rotary.position++; }
|
else if ((Rotary.store & 0xff) == 0x17) { Rotary.position++; }
|
||||||
}
|
}
|
||||||
#endif
|
*/
|
||||||
|
const uint16_t rot_enc = 0b0110100110010110;
|
||||||
|
|
||||||
|
uint8_t p1val = digitalRead(Pin(GPIO_ROT1B));
|
||||||
|
uint8_t p2val = digitalRead(Pin(GPIO_ROT1A));
|
||||||
|
uint8_t t = Rotary.prev_next_code;
|
||||||
|
t <<= 2;
|
||||||
|
if (p1val) { t |= 0x02; }
|
||||||
|
if (p2val) { t |= 0x01; }
|
||||||
|
t &= 0x0f;
|
||||||
|
Rotary.prev_next_code = t;
|
||||||
|
|
||||||
|
// If valid then store as 16 bit data.
|
||||||
|
if (rot_enc & (1 << t)) {
|
||||||
|
Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code;
|
||||||
|
int direction = 0;
|
||||||
|
if (Rotary.store == 0xd42b) { direction = 1; }
|
||||||
|
else if (Rotary.store == 0xe817) { direction = -1; }
|
||||||
|
else if ((Rotary.store & 0xff) == 0x2b) { direction = -1; }
|
||||||
|
else if ((Rotary.store & 0xff) == 0x17) { direction = 1; }
|
||||||
|
if ((0 == Rotary.direction) || (direction == Rotary.direction)) {
|
||||||
|
Rotary.position += direction;
|
||||||
|
Rotary.direction = direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ROTARY_OPTION2
|
||||||
|
|
||||||
|
#ifdef ROTARY_OPTION3
|
||||||
|
// Theo Arends
|
||||||
|
uint32_t time = micros();
|
||||||
|
if (Rotary.debounce < time) {
|
||||||
|
int direction = (digitalRead(Pin(GPIO_ROT1B))) ? 1 : -1;
|
||||||
|
if ((0 == Rotary.direction) || (direction == Rotary.direction)) {
|
||||||
|
Rotary.position += direction;
|
||||||
|
Rotary.direction = direction;
|
||||||
|
}
|
||||||
|
Rotary.debounce = time +20; // Experimental debounce
|
||||||
|
}
|
||||||
|
#endif // ROTARY_OPTION3
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RotaryButtonPressed(void) {
|
bool RotaryButtonPressed(void) {
|
||||||
if (Rotary.changed && LightPower()) {
|
bool powered_on = (power);
|
||||||
Rotary.changed = 0; // Color temp changed, no need to turn of the light
|
#ifdef USE_LIGHT
|
||||||
|
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||||
|
powered_on = LightPower();
|
||||||
|
}
|
||||||
|
#endif // USE_LIGHT
|
||||||
|
if (Rotary.changed && powered_on) {
|
||||||
|
Rotary.changed = false; // Color (temp) changed, no need to turn of the light
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -116,9 +231,13 @@ void RotaryInit(void) {
|
|||||||
if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) {
|
if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) {
|
||||||
Rotary.present++;
|
Rotary.present++;
|
||||||
pinMode(Pin(GPIO_ROT1A), INPUT_PULLUP);
|
pinMode(Pin(GPIO_ROT1A), INPUT_PULLUP);
|
||||||
attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1A)), update_rotary, CHANGE);
|
|
||||||
pinMode(Pin(GPIO_ROT1B), INPUT_PULLUP);
|
pinMode(Pin(GPIO_ROT1B), INPUT_PULLUP);
|
||||||
attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1B)), update_rotary, CHANGE);
|
#ifdef ROTARY_OPTION3
|
||||||
|
attachInterrupt(Pin(GPIO_ROT1A), update_rotary, RISING);
|
||||||
|
#else
|
||||||
|
attachInterrupt(Pin(GPIO_ROT1A), update_rotary, CHANGE);
|
||||||
|
attachInterrupt(Pin(GPIO_ROT1B), update_rotary, CHANGE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,31 +246,56 @@ void RotaryInit(void) {
|
|||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
void RotaryHandler(void) {
|
void RotaryHandler(void) {
|
||||||
|
if (Rotary.timeout) {
|
||||||
|
Rotary.timeout--;
|
||||||
|
if (!Rotary.timeout) {
|
||||||
|
Rotary.direction = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Rotary.last_position == Rotary.position) { return; }
|
if (Rotary.last_position == Rotary.position) { return; }
|
||||||
|
|
||||||
Rotary.busy = true;
|
Rotary.busy = true;
|
||||||
|
|
||||||
int8_t rotary_position = Rotary.position - Rotary.last_position;
|
Rotary.timeout = ROTARY_TIMEOUT; // Prevent fast direction changes within 0.5 second
|
||||||
Rotary.last_position = 128;
|
|
||||||
Rotary.position = 128;
|
int rotary_position = Rotary.position - Rotary.last_position;
|
||||||
|
|
||||||
if (Settings.save_data && (save_data_counter < 2)) {
|
if (Settings.save_data && (save_data_counter < 2)) {
|
||||||
save_data_counter = 2; // Postpone flash writes while rotary is turned
|
save_data_counter = 2; // Postpone flash writes while rotary is turned
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature
|
bool button_pressed = (Button.hold_timer[0]); // Button1 is pressed: set color temperature
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: CT/Color position %d"), rotary_position);
|
if (button_pressed) { Rotary.changed = true; }
|
||||||
Rotary.changed = 1;
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position);
|
||||||
if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { // Ct 153..500 = (500 - 153) / 8 = 43 steps
|
|
||||||
LightColorOffset(rotary_position * rotary_color_increment); // Hue 0..359 = 360 / 8 = 45 steps
|
#ifdef USE_LIGHT
|
||||||
|
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||||
|
if (button_pressed) {
|
||||||
|
if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) {
|
||||||
|
LightColorOffset(rotary_position * rotary_color_increment);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Dimmer position %d"), rotary_position);
|
LightDimmerOffset(rotary_position * rotary_dimmer_increment);
|
||||||
LightDimmerOffset(rotary_position * rotary_dimmer_increment); // Dimmer 1..100 = 100 / 2 = 50 steps
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#endif // USE_LIGHT
|
||||||
|
if (button_pressed) {
|
||||||
|
Rotary.abs_position2 += rotary_position;
|
||||||
|
if (Rotary.abs_position2 < 0) { Rotary.abs_position2 = 0; }
|
||||||
|
if (Rotary.abs_position2 > ROTARY_MAX_STEPS) { Rotary.abs_position2 = ROTARY_MAX_STEPS; }
|
||||||
|
} else {
|
||||||
|
Rotary.abs_position1 += rotary_position;
|
||||||
|
if (Rotary.abs_position1 < 0) { Rotary.abs_position1 = 0; }
|
||||||
|
if (Rotary.abs_position1 > ROTARY_MAX_STEPS) { Rotary.abs_position1 = ROTARY_MAX_STEPS; }
|
||||||
|
}
|
||||||
|
Response_P(PSTR("{\"Rotary1\":{\"Pos1\":%d,\"Pos2\":%d}}"), Rotary.abs_position1, Rotary.abs_position2);
|
||||||
|
XdrvRulesProcess();
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
}
|
||||||
|
#endif // USE_LIGHT
|
||||||
|
|
||||||
|
Rotary.last_position = 128;
|
||||||
|
Rotary.position = 128;
|
||||||
Rotary.busy = false;
|
Rotary.busy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ROTARY_V1
|
#endif // ROTARY_V1
|
||||||
#endif // USE_LIGHT
|
|
||||||
|
@ -372,11 +372,9 @@ void loop(void) {
|
|||||||
|
|
||||||
if (TimeReached(state_50msecond)) {
|
if (TimeReached(state_50msecond)) {
|
||||||
SetNextTimeInterval(state_50msecond, 50);
|
SetNextTimeInterval(state_50msecond, 50);
|
||||||
#ifdef USE_LIGHT
|
|
||||||
#ifdef ROTARY_V1
|
#ifdef ROTARY_V1
|
||||||
RotaryHandler();
|
RotaryHandler();
|
||||||
#endif // ROTARY_V1
|
#endif // ROTARY_V1
|
||||||
#endif // USE_LIGHT
|
|
||||||
XdrvCall(FUNC_EVERY_50_MSECOND);
|
XdrvCall(FUNC_EVERY_50_MSECOND);
|
||||||
XsnsCall(FUNC_EVERY_50_MSECOND);
|
XsnsCall(FUNC_EVERY_50_MSECOND);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user