mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 10:46:31 +00:00
Add rotary encoder support
- Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) - Fix Mi Desk Lamp brightness control (#8748)
This commit is contained in:
parent
6853926948
commit
e52961b3b4
@ -91,3 +91,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
||||
- Add support for single wire LMT01 temperature Sensor by justifiably (#8713)
|
||||
- Add compile time interlock parameters (#8759)
|
||||
- Add compile time user template (#8766)
|
||||
- Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670)
|
||||
|
@ -8,6 +8,7 @@
|
||||
- Add support for single wire LMT01 temperature Sensor by justifiably (#8713)
|
||||
- Add compile time interlock parameters (#8759)
|
||||
- Add compile time user template (#8766)
|
||||
- Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670)
|
||||
- Fix exception or watchdog on rule re-entry (#8757)
|
||||
- Change ESP32 USER GPIO template representation decreasing template message size
|
||||
- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT
|
||||
|
@ -429,7 +429,7 @@
|
||||
// #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code)
|
||||
|
||||
// -- Optional modules ----------------------------
|
||||
//#define ROTARY_V1 // Add support for MI Desk Lamp
|
||||
#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp (+0k8 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_SONOFF_SC // Add support for Sonoff Sc (+1k1 code)
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
#ifdef USE_LIGHT
|
||||
//#define ROTARY_V1
|
||||
#ifdef ROTARY_V1
|
||||
/*********************************************************************************************\
|
||||
* Rotary support
|
||||
@ -36,49 +35,40 @@ struct ROTARY {
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception
|
||||
void update_rotary(void) ICACHE_RAM_ATTR;
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
void update_rotary(void) {
|
||||
if (Rotary.busy || !LightPowerIRAM()) { return; }
|
||||
|
||||
void update_rotary(void)
|
||||
{
|
||||
if (MI_DESK_LAMP == my_module_type) {
|
||||
if (LightPowerIRAM() && !Rotary.busy) {
|
||||
/*
|
||||
* https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h
|
||||
*/
|
||||
|
||||
uint8_t s = Rotary.state & 3;
|
||||
if (digitalRead(Pin(GPIO_ROT1A))) { s |= 4; }
|
||||
if (digitalRead(Pin(GPIO_ROT1B))) { s |= 8; }
|
||||
switch (s) {
|
||||
case 0: case 5: case 10: case 15:
|
||||
break;
|
||||
case 1: case 7: case 8: case 14:
|
||||
Rotary.position++; break;
|
||||
case 2: case 4: case 11: case 13:
|
||||
Rotary.position--; break;
|
||||
case 3: case 12:
|
||||
Rotary.position = Rotary.position + 2; break;
|
||||
default:
|
||||
Rotary.position = Rotary.position - 2; break;
|
||||
}
|
||||
Rotary.state = (s >> 2);
|
||||
}
|
||||
/*
|
||||
* https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h
|
||||
*/
|
||||
uint8_t s = Rotary.state & 3;
|
||||
if (digitalRead(Pin(GPIO_ROT1A))) { s |= 4; }
|
||||
if (digitalRead(Pin(GPIO_ROT1B))) { s |= 8; }
|
||||
switch (s) {
|
||||
case 0: case 5: case 10: case 15:
|
||||
break;
|
||||
case 1: case 7: case 8: case 14:
|
||||
Rotary.position++; break;
|
||||
case 2: case 4: case 11: case 13:
|
||||
Rotary.position--; break;
|
||||
case 3: case 12:
|
||||
Rotary.position = Rotary.position + 2; break;
|
||||
default:
|
||||
Rotary.position = Rotary.position - 2; break;
|
||||
}
|
||||
Rotary.state = (s >> 2);
|
||||
}
|
||||
|
||||
bool RotaryButtonPressed(void)
|
||||
{
|
||||
if ((MI_DESK_LAMP == my_module_type) && (Rotary.changed) && LightPower()) {
|
||||
bool RotaryButtonPressed(void) {
|
||||
if (Rotary.changed && LightPower()) {
|
||||
Rotary.changed = 0; // Color temp changed, no need to turn of the light
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RotaryInit(void)
|
||||
{
|
||||
void RotaryInit(void) {
|
||||
Rotary.present = 0;
|
||||
if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) {
|
||||
Rotary.present++;
|
||||
@ -93,57 +83,30 @@ void RotaryInit(void)
|
||||
* Rotary handler
|
||||
\*********************************************************************************************/
|
||||
|
||||
void RotaryHandler(void)
|
||||
{
|
||||
void RotaryHandler(void) {
|
||||
if (Rotary.last_position != Rotary.position) {
|
||||
Rotary.busy = true;
|
||||
int rotary_position = Rotary.position - Rotary.last_position;
|
||||
|
||||
if (MI_DESK_LAMP == my_module_type) { // Mi Desk lamp
|
||||
if (Button.hold_timer[0]) {
|
||||
Rotary.changed = 1;
|
||||
// button1 is pressed: set color temperature
|
||||
int16_t t = LightGetColorTemp();
|
||||
t = t + ((rotary_position) * 4);
|
||||
if (t < 153) {
|
||||
t = 153;
|
||||
}
|
||||
if (t > 500) {
|
||||
t = 500;
|
||||
}
|
||||
DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position);
|
||||
LightSetColorTemp((uint16_t)t);
|
||||
|
||||
// char scmnd[20];
|
||||
// snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLORTEMPERATURE " %d"), t);
|
||||
// ExecuteCommand(scmnd, SRC_SWITCH);
|
||||
} else {
|
||||
int8_t d = Settings.light_dimmer;
|
||||
d = d + rotary_position;
|
||||
if (d < 1) {
|
||||
d = 1;
|
||||
}
|
||||
if (d > 100) {
|
||||
d = 100;
|
||||
}
|
||||
DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position);
|
||||
|
||||
char scmnd[20];
|
||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER "0 %d"), d);
|
||||
ExecuteCommand(scmnd, SRC_SWITCH);
|
||||
}
|
||||
if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position);
|
||||
Rotary.changed = 1;
|
||||
LightColorTempOffset(rotary_position * 4);
|
||||
} else {
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position);
|
||||
LightDimmerOffset(rotary_position);
|
||||
}
|
||||
|
||||
Rotary.last_position = 128;
|
||||
Rotary.position = 128;
|
||||
Rotary.busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RotaryLoop(void)
|
||||
{
|
||||
void RotaryLoop(void) {
|
||||
if (Rotary.present) {
|
||||
if (TimeReached(Rotary.debounce)) {
|
||||
SetNextTimeInterval(Rotary.debounce, Settings.button_debounce); // Using button_debounce setting for this as well
|
||||
SetNextTimeInterval(Rotary.debounce, Settings.button_debounce); // Using button_debounce setting for this as well
|
||||
RotaryHandler();
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
#undef USE_DISCOVERY // Disable mDNS (+8k code or +23.5k code with core 2_5_x, +0.3k mem)
|
||||
|
||||
// -- Optional modules ----------------------------
|
||||
//#define ROTARY_V1 // Add support for MI Desk Lamp
|
||||
#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp
|
||||
#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_SONOFF_SC // Add support for Sonoff Sc (+1k1 code)
|
||||
|
@ -895,7 +895,7 @@ void LightStateClass::XyToRgb(float x, float y, uint8_t *rr, uint8_t *rg, uint8_
|
||||
0.0557f, -0.2040f, 1.0570f };
|
||||
mat3x3(rgb_factors, XYZ, rgb);
|
||||
float max = (rgb[0] > rgb[1] && rgb[0] > rgb[2]) ? rgb[0] : (rgb[1] > rgb[2]) ? rgb[1] : rgb[2];
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < 3; i++) {
|
||||
rgb[i] = rgb[i] / max; // normalize to max == 1.0
|
||||
rgb[i] = (rgb[i] <= 0.0031308f) ? 12.92f * rgb[i] : 1.055f * POW(rgb[i], (1.0f / 2.4f)) - 0.055f; // gamma
|
||||
@ -1478,12 +1478,22 @@ void LightSetBri(uint8_t device, uint8_t bri) {
|
||||
}
|
||||
}
|
||||
|
||||
void LightColorTempOffset(int32_t offset) {
|
||||
int32_t ct = LightGetColorTemp();
|
||||
if (0 == ct) { return; } // CT not supported
|
||||
ct += offset;
|
||||
if (ct < CT_MIN) { ct = CT_MIN; }
|
||||
else if (ct > CT_MAX) { ct = CT_MAX; }
|
||||
|
||||
LightSetColorTemp(ct);
|
||||
}
|
||||
|
||||
void LightSetColorTemp(uint16_t ct)
|
||||
{
|
||||
/* Color Temperature (https://developers.meethue.com/documentation/core-concepts)
|
||||
*
|
||||
* ct = 153 = 6500K = Cold = CCWW = FF00
|
||||
* ct = 600 = 2000K = Warm = CCWW = 00FF
|
||||
* ct = 153 mirek = 6500K = Cold = CCWW = FF00
|
||||
* ct = 500 mirek = 2000K = Warm = CCWW = 00FF
|
||||
*/
|
||||
// don't set CT if not supported
|
||||
if ((LST_COLDWARM != Light.subtype) && (LST_RGBCW != Light.subtype)) {
|
||||
@ -2745,6 +2755,16 @@ void CmndColorTemperature(void)
|
||||
}
|
||||
}
|
||||
|
||||
void LightDimmerOffset(int32_t offset) {
|
||||
int32_t dimmer = light_state.getDimmer() + offset;
|
||||
if (dimmer < 1) { dimmer = 1; }
|
||||
if (dimmer > 100) { dimmer = 100; }
|
||||
|
||||
XdrvMailbox.index = 0;
|
||||
XdrvMailbox.payload = dimmer;
|
||||
CmndDimmer();
|
||||
}
|
||||
|
||||
void CmndDimmer(void)
|
||||
{
|
||||
// Dimmer - Show current Dimmer state
|
||||
|
Loading…
x
Reference in New Issue
Block a user