mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Add second rotary support
Add second rotary support default used for CW light control when first rotary is used for RGB light control (#8864)
This commit is contained in:
parent
96d37ec535
commit
84ee6393a5
@ -34,207 +34,98 @@
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifndef ROTARY_MAX_STEPS
|
||||
#define ROTARY_MAX_STEPS 10 // Rotary step boundary
|
||||
#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
|
||||
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
|
||||
|
||||
#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
|
||||
const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds
|
||||
|
||||
struct ROTARY {
|
||||
#ifdef ROTARY_OPTION1
|
||||
uint8_t state = 0;
|
||||
#endif // ROTARY_OPTION1
|
||||
#ifdef ROTARY_OPTION2
|
||||
uint16_t store;
|
||||
uint8_t prev_next_code;
|
||||
#endif // ROTARY_OPTION2
|
||||
#ifdef ROTARY_OPTION3
|
||||
bool present = false;
|
||||
} Rotary;
|
||||
|
||||
struct ENCODER {
|
||||
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;
|
||||
int8_t direction = 0; // Control consistent direction
|
||||
int8_t pin = -1;
|
||||
uint8_t position = 128;
|
||||
uint8_t last_position = 128;
|
||||
uint8_t timeout = 0; // Disallow direction change within 0.5 second
|
||||
uint8_t timeout = 0; // Disallow direction change within 0.5 second
|
||||
bool changed = false;
|
||||
bool busy = false;
|
||||
} Rotary;
|
||||
} Encoder[MAX_ROTARIES];
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void update_rotary(void) ICACHE_RAM_ATTR;
|
||||
void update_rotary(void) {
|
||||
if (Rotary.busy) { return; }
|
||||
void ICACHE_RAM_ATTR RotaryIsr(uint32_t index) {
|
||||
if (Encoder[index].busy) { return; }
|
||||
|
||||
#ifdef ROTARY_OPTION1
|
||||
// https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h
|
||||
/*
|
||||
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);
|
||||
switch (state) {
|
||||
case 1: case 7: case 8: case 14:
|
||||
Rotary.position++;
|
||||
return;
|
||||
case 2: case 4: case 11: case 13:
|
||||
Rotary.position--;
|
||||
return;
|
||||
case 3: case 12:
|
||||
Rotary.position += 2;
|
||||
return;
|
||||
case 6: case 9:
|
||||
Rotary.position -= 2;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
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
|
||||
// https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h
|
||||
/*
|
||||
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;
|
||||
if (Rotary.store == 0xd42b) { Rotary.position++; }
|
||||
else if (Rotary.store == 0xe817) { Rotary.position--; }
|
||||
else if ((Rotary.store & 0xff) == 0x2b) { Rotary.position--; }
|
||||
else if ((Rotary.store & 0xff) == 0x17) { Rotary.position++; }
|
||||
}
|
||||
*/
|
||||
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;
|
||||
if (Encoder[index].debounce < time) {
|
||||
int direction = (digitalRead(Encoder[index].pin)) ? -1 : 1;
|
||||
if ((0 == Encoder[index].direction) || (direction == Encoder[index].direction)) {
|
||||
Encoder[index].position += direction;
|
||||
Encoder[index].direction = direction;
|
||||
}
|
||||
Rotary.debounce = time +20; // Experimental debounce
|
||||
Encoder[index].debounce = time +50; // Experimental debounce in microseconds
|
||||
}
|
||||
#endif // ROTARY_OPTION3
|
||||
}
|
||||
|
||||
//bool RotaryButtonPressed(void) {
|
||||
void ICACHE_RAM_ATTR RotaryIsr1(void) {
|
||||
RotaryIsr(0);
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR RotaryIsr2(void) {
|
||||
RotaryIsr(1);
|
||||
}
|
||||
|
||||
bool RotaryButtonPressed(uint32_t button_index) {
|
||||
if (!Rotary.present) { return false; }
|
||||
if (0 != button_index) { return false; }
|
||||
|
||||
bool powered_on = (power);
|
||||
for (uint32_t index = 0; index < MAX_ROTARIES; index++) {
|
||||
if (-1 == Encoder[index].pin) { continue; }
|
||||
if (index != button_index) { continue; }
|
||||
|
||||
bool powered_on = (power);
|
||||
#ifdef USE_LIGHT
|
||||
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||
powered_on = LightPower();
|
||||
}
|
||||
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;
|
||||
if (Encoder[index].changed && powered_on) {
|
||||
Encoder[index].changed = false; // Color (temp) changed, no need to turn of the light
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RotaryInit(void) {
|
||||
Rotary.present = 0;
|
||||
if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) {
|
||||
Rotary.present++;
|
||||
pinMode(Pin(GPIO_ROT1A), INPUT_PULLUP);
|
||||
pinMode(Pin(GPIO_ROT1B), INPUT_PULLUP);
|
||||
#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
|
||||
Rotary.present = false;
|
||||
for (uint32_t index = 0; index < MAX_ROTARIES; index++) {
|
||||
#ifdef ESP8266
|
||||
uint32_t idx = index *2;
|
||||
#else // ESP32
|
||||
uint32_t idx = index;
|
||||
#endif // ESP8266 or ESP32
|
||||
if (PinUsed(GPIO_ROT1A, idx) && PinUsed(GPIO_ROT1B, idx)) {
|
||||
Encoder[index].pin = Pin(GPIO_ROT1B, idx);
|
||||
pinMode(Encoder[index].pin, INPUT_PULLUP);
|
||||
pinMode(Pin(GPIO_ROT1A, idx), INPUT_PULLUP);
|
||||
if (0 == index) {
|
||||
attachInterrupt(Pin(GPIO_ROT1A, idx), RotaryIsr1, FALLING);
|
||||
} else {
|
||||
attachInterrupt(Pin(GPIO_ROT1A, idx), RotaryIsr2, FALLING);
|
||||
}
|
||||
}
|
||||
Rotary.present |= (Encoder[index].pin > -1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,63 +136,80 @@ void RotaryInit(void) {
|
||||
void RotaryHandler(void) {
|
||||
if (!Rotary.present) { return; }
|
||||
|
||||
if (Rotary.timeout) {
|
||||
Rotary.timeout--;
|
||||
if (!Rotary.timeout) {
|
||||
Rotary.direction = 0;
|
||||
for (uint32_t index = 0; index < MAX_ROTARIES; index++) {
|
||||
if (-1 == Encoder[index].pin) { continue; }
|
||||
|
||||
if (Encoder[index].timeout) {
|
||||
Encoder[index].timeout--;
|
||||
if (!Encoder[index].timeout) {
|
||||
#ifdef USE_LIGHT
|
||||
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||
LightState(0);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_DIMMER));
|
||||
XdrvRulesProcess();
|
||||
}
|
||||
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||
ResponseLightState(0);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_STATE));
|
||||
XdrvRulesProcess();
|
||||
}
|
||||
#endif // USE_LIGHT
|
||||
Encoder[index].direction = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Rotary.last_position == Rotary.position) { return; }
|
||||
Rotary.busy = true;
|
||||
if (Encoder[index].last_position == Encoder[index].position) { continue; }
|
||||
Encoder[index].busy = true;
|
||||
|
||||
Rotary.timeout = ROTARY_TIMEOUT; // Prevent fast direction changes within 0.5 second
|
||||
Encoder[index].timeout = ROTARY_TIMEOUT; // Prevent fast direction changes within 0.5 second
|
||||
|
||||
int rotary_position = Rotary.position - Rotary.last_position;
|
||||
int rotary_position = Encoder[index].position - Encoder[index].last_position;
|
||||
|
||||
if (Settings.save_data && (save_data_counter < 2)) {
|
||||
save_data_counter = 2; // Postpone flash writes while rotary is turned
|
||||
}
|
||||
if (Settings.save_data && (save_data_counter < 2)) {
|
||||
save_data_counter = 2; // Postpone flash writes while rotary is turned
|
||||
}
|
||||
|
||||
bool button_pressed = (Button.hold_timer[0]); // Button1 is pressed: set color temperature
|
||||
if (button_pressed) { Rotary.changed = true; }
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position);
|
||||
bool button_pressed = (Button.hold_timer[index]); // Button is pressed: set color temperature
|
||||
if (button_pressed) { Encoder[index].changed = true; }
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position);
|
||||
|
||||
#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);
|
||||
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||
bool second_rotary = (Encoder[1].pin > -1);
|
||||
if (0 == index) { // Rotary1
|
||||
if (button_pressed) {
|
||||
if (second_rotary) { // Color RGB
|
||||
LightColorOffset(rotary_position * rotary_color_increment);
|
||||
} else { // Color Temperature or Color RGB
|
||||
if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) {
|
||||
LightColorOffset(rotary_position * rotary_color_increment);
|
||||
}
|
||||
}
|
||||
} else { // Dimmer RGBCW or RGB only if second rotary
|
||||
LightDimmerOffset(second_rotary ? 1 : 0, rotary_position * rotary_dimmer_increment);
|
||||
}
|
||||
} else { // Rotary2
|
||||
if (button_pressed) { // Color Temperature
|
||||
LightColorTempOffset(rotary_position * rotary_ct_increment);
|
||||
} else { // Dimmer CW
|
||||
LightDimmerOffset(2, rotary_position * rotary_dimmer_increment);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LightDimmerOffset(rotary_position * rotary_dimmer_increment);
|
||||
}
|
||||
} 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();
|
||||
if (button_pressed) {
|
||||
Encoder[index].abs_position2 += rotary_position;
|
||||
if (Encoder[index].abs_position2 < 0) { Encoder[index].abs_position2 = 0; }
|
||||
if (Encoder[index].abs_position2 > ROTARY_MAX_STEPS) { Encoder[index].abs_position2 = ROTARY_MAX_STEPS; }
|
||||
} else {
|
||||
Encoder[index].abs_position1 += rotary_position;
|
||||
if (Encoder[index].abs_position1 < 0) { Encoder[index].abs_position1 = 0; }
|
||||
if (Encoder[index].abs_position1 > ROTARY_MAX_STEPS) { Encoder[index].abs_position1 = ROTARY_MAX_STEPS; }
|
||||
}
|
||||
Response_P(PSTR("{\"Rotary%d\":{\"Pos1\":%d,\"Pos2\":%d}}"), index +1, Encoder[index].abs_position1, Encoder[index].abs_position2);
|
||||
XdrvRulesProcess();
|
||||
#ifdef USE_LIGHT
|
||||
}
|
||||
}
|
||||
#endif // USE_LIGHT
|
||||
|
||||
Rotary.last_position = 128;
|
||||
Rotary.position = 128;
|
||||
Rotary.busy = false;
|
||||
Encoder[index].last_position = 128;
|
||||
Encoder[index].position = 128;
|
||||
Encoder[index].busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ROTARY_V1
|
||||
|
@ -663,7 +663,7 @@ void MqttShowState(void)
|
||||
for (uint32_t i = 1; i <= devices_present; i++) {
|
||||
#ifdef USE_LIGHT
|
||||
if ((LightDevice()) && (i >= LightDevice())) {
|
||||
if (i == LightDevice()) { LightState(1); } // call it only once
|
||||
if (i == LightDevice()) { ResponseLightState(1); } // call it only once
|
||||
} else {
|
||||
#endif
|
||||
ResponseAppend_P(PSTR(",\"%s\":\"%s\""), GetPowerDevice(stemp1, i, sizeof(stemp1), Settings.flag.device_index_enable), // SetOption26 - Switch between POWER or POWER1
|
||||
|
@ -84,6 +84,7 @@ const uint8_t MAX_GROUP_TOPICS = 4; // Max number of Group Topics
|
||||
const uint8_t MAX_DEV_GROUP_NAMES = 4; // Max number of Device Group names
|
||||
|
||||
const uint8_t MAX_HUE_DEVICES = 15; // Max number of Philips Hue device per emulation
|
||||
const uint8_t MAX_ROTARIES = 2; // Max number of Rotary Encoders
|
||||
|
||||
const char MQTT_TOKEN_PREFIX[] PROGMEM = "%prefix%"; // To be substituted by mqtt_prefix[x]
|
||||
const char MQTT_TOKEN_TOPIC[] PROGMEM = "%topic%"; // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic
|
||||
|
@ -373,6 +373,12 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
||||
GPIO_SWT7_NP,
|
||||
GPIO_SWT8,
|
||||
GPIO_SWT8_NP,
|
||||
#ifdef ROTARY_V1
|
||||
GPIO_ROT1A, // Rotary switch1 A Pin
|
||||
GPIO_ROT1B, // Rotary switch1 B Pin
|
||||
GPIO_ROT2A, // Rotary switch2 A Pin
|
||||
GPIO_ROT2B, // Rotary switch2 B Pin
|
||||
#endif
|
||||
GPIO_REL1, // Relays
|
||||
GPIO_REL1_INV,
|
||||
GPIO_REL2,
|
||||
@ -665,12 +671,6 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
||||
GPIO_MAX31855CLK, // MAX31855 Serial interface
|
||||
GPIO_MAX31855DO, // MAX31855 Serial interface
|
||||
#endif
|
||||
#ifdef ROTARY_V1
|
||||
GPIO_ROT1A, // Rotary switch1 A Pin
|
||||
GPIO_ROT1B, // Rotary switch1 B Pin
|
||||
GPIO_ROT2A, // Rotary switch2 A Pin
|
||||
GPIO_ROT2B, // Rotary switch2 B Pin
|
||||
#endif
|
||||
#ifdef USE_HRE
|
||||
GPIO_HRE_CLOCK,
|
||||
GPIO_HRE_DATA,
|
||||
|
@ -88,7 +88,10 @@ enum UserSelectablePins {
|
||||
GPIO_CSE7766_TX, GPIO_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2)
|
||||
GPIO_ARIRFRCV, GPIO_ARIRFSEL, // Arilux RF Receive input
|
||||
GPIO_TXD, GPIO_RXD, // Serial interface
|
||||
GPIO_ROT1A, GPIO_ROT1B, GPIO_ROT2A, GPIO_ROT2B, // Rotary switch
|
||||
GPIO_ROT1A, GPIO_ROT1B, // Rotary switch
|
||||
|
||||
GPIO_SPARE1, GPIO_SPARE2, // Spare GPIOs
|
||||
|
||||
GPIO_HRE_CLOCK, GPIO_HRE_DATA, // HR-E Water Meter
|
||||
GPIO_ADE7953_IRQ, // ADE7953 IRQ
|
||||
GPIO_SOLAXX1_TX, GPIO_SOLAXX1_RX, // Solax Inverter Serial interface
|
||||
@ -188,7 +191,10 @@ const char kSensorNames[] PROGMEM =
|
||||
D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|"
|
||||
D_SENSOR_ARIRFRCV "|" D_SENSOR_ARIRFSEL "|"
|
||||
D_SENSOR_TXD "|" D_SENSOR_RXD "|"
|
||||
D_SENSOR_ROTARY "_1a|" D_SENSOR_ROTARY "_1b|" D_SENSOR_ROTARY "_2a|" D_SENSOR_ROTARY "_2b|"
|
||||
D_SENSOR_ROTARY "_a|" D_SENSOR_ROTARY "_b|"
|
||||
|
||||
"Spare1|Spare2|"
|
||||
|
||||
D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|"
|
||||
D_SENSOR_ADE7953_IRQ "|"
|
||||
D_SENSOR_SOLAXX1_TX "|" D_SENSOR_SOLAXX1_RX "|"
|
||||
@ -245,6 +251,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
||||
AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button
|
||||
AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches
|
||||
AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES,
|
||||
#ifdef ROTARY_V1
|
||||
AGPIO(GPIO_ROT1A) + MAX_ROTARIES, // Rotary A Pin
|
||||
AGPIO(GPIO_ROT1B) + MAX_ROTARIES, // Rotary B Pin
|
||||
#endif
|
||||
AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays
|
||||
AGPIO(GPIO_REL1_INV) + MAX_RELAYS,
|
||||
AGPIO(GPIO_LED1) + MAX_LEDS, // Leds
|
||||
@ -508,12 +518,6 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
||||
AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface
|
||||
AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface
|
||||
#endif
|
||||
#ifdef ROTARY_V1
|
||||
AGPIO(GPIO_ROT1A), // Rotary switch1 A Pin
|
||||
AGPIO(GPIO_ROT1B), // Rotary switch1 B Pin
|
||||
AGPIO(GPIO_ROT2A), // Rotary switch2 A Pin
|
||||
AGPIO(GPIO_ROT2B), // Rotary switch2 B Pin
|
||||
#endif
|
||||
#ifdef USE_HRE
|
||||
AGPIO(GPIO_HRE_CLOCK),
|
||||
AGPIO(GPIO_HRE_DATA),
|
||||
|
@ -314,16 +314,6 @@ power_t LightPower(void)
|
||||
return Light.power; // Make external
|
||||
}
|
||||
|
||||
// IRAM variant for rotary
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception
|
||||
power_t LightPowerIRAM(void) ICACHE_RAM_ATTR;
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
|
||||
power_t LightPowerIRAM(void)
|
||||
{
|
||||
return Light.power; // Make external
|
||||
}
|
||||
|
||||
uint8_t LightDevice(void)
|
||||
{
|
||||
return Light.device; // Make external
|
||||
@ -1568,7 +1558,7 @@ void LightPowerOn(void)
|
||||
}
|
||||
}
|
||||
|
||||
void LightState(uint8_t append)
|
||||
void ResponseLightState(uint8_t append)
|
||||
{
|
||||
char scolor[LIGHT_COLOR_SIZE];
|
||||
char scommand[33];
|
||||
@ -1718,7 +1708,7 @@ void LightPreparePower(power_t channels = 0xFFFFFFFF) { // 1 = only RGB, 2 =
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "LightPreparePower End power=%d Light.power=%d", power, Light.power);
|
||||
#endif
|
||||
Light.power = power >> (Light.device - 1); // reset next state, works also with unlinked RGB/CT
|
||||
LightState(0);
|
||||
ResponseLightState(0);
|
||||
}
|
||||
|
||||
#ifdef USE_LIGHT_PALETTE
|
||||
@ -1886,7 +1876,7 @@ void LightAnimate(void)
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_CMND_WAKEUP));
|
||||
*/
|
||||
Response_P(PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\""));
|
||||
LightState(1);
|
||||
ResponseLightState(1);
|
||||
ResponseJsonEnd();
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_WAKEUP));
|
||||
XdrvRulesProcess();
|
||||
@ -2689,7 +2679,7 @@ void CmndHsbColor(void)
|
||||
light_controller.changeHSB(HSB[0], HSB[1], HSB[2]);
|
||||
LightPreparePower(1);
|
||||
} else {
|
||||
LightState(0);
|
||||
ResponseLightState(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2774,12 +2764,12 @@ void CmndColorTemperature(void)
|
||||
}
|
||||
}
|
||||
|
||||
void LightDimmerOffset(int32_t offset) {
|
||||
int32_t dimmer = light_state.getDimmer() + offset;
|
||||
if (dimmer < 1) { dimmer = 1; }
|
||||
void LightDimmerOffset(uint32_t index, int32_t offset) {
|
||||
int32_t dimmer = light_state.getDimmer(index) + offset;
|
||||
if (dimmer < 1) { dimmer = Settings.flag3.slider_dimmer_stay_on; } // SetOption77 - Do not power off if slider moved to far left
|
||||
if (dimmer > 100) { dimmer = 100; }
|
||||
|
||||
XdrvMailbox.index = 0;
|
||||
XdrvMailbox.index = index;
|
||||
XdrvMailbox.payload = dimmer;
|
||||
CmndDimmer();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user