Rotary driver adjusted for MiDesk if selected

Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399)
This commit is contained in:
Theo Arends 2020-10-20 15:13:12 +02:00
parent 500fb147c4
commit 83a090b5a9
3 changed files with 40 additions and 156 deletions

View File

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

View File

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

View File

@ -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
// (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
#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
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<tEncoder*>(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;
void ICACHE_RAM_ATTR RotaryIsrArg(void *arg) {
tEncoder* encoder = static_cast<tEncoder*>(arg);
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 (encoder->busy) { return; }
// 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
#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 {