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:
Theo Arends 2020-06-30 16:58:36 +02:00
parent 6853926948
commit e52961b3b4
6 changed files with 61 additions and 76 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -18,7 +18,6 @@
*/
#ifdef USE_LIGHT
//#define ROTARY_V1
#ifdef ROTARY_V1
/*********************************************************************************************\
* Rotary support
@ -36,18 +35,13 @@ 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; }
@ -64,21 +58,17 @@ void update_rotary(void)
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,54 +83,27 @@ 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]) {
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;
// 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);
LightColorTempOffset(rotary_position * 4);
} else {
int8_t d = Settings.light_dimmer;
d = d + rotary_position;
if (d < 1) {
d = 1;
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position);
LightDimmerOffset(rotary_position);
}
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);
}
}
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

View File

@ -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)

View File

@ -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