blog
This commit is contained in:
parent
87b2a3cec2
commit
374685e92c
137
content/content/blog/debouncing.md
Normal file
137
content/content/blog/debouncing.md
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
---
|
||||||
|
title: "Yet Another Debouncing Method"
|
||||||
|
date: "2018-04-30"
|
||||||
|
---
|
||||||
|
|
||||||
|
You can find several approaches for debouncing mechanical switches on the Internet, some work better, some not so good.
|
||||||
|
|
||||||
|
One common approach is to ignore events in an ISR when they come too fast:<
|
||||||
|
|
||||||
|
```
|
||||||
|
void count() {
|
||||||
|
static uint32_t lastEvent = 0;
|
||||||
|
uint32_t currentEvent = micros();
|
||||||
|
if (currentEvent > (lastEvent + configBlock.debounce)) {
|
||||||
|
lastEvent = currentEvent;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(REED_PIN, INPUT_PULLUP);
|
||||||
|
attachInterrupt(REED_PIN, count, FALLING);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This works very good when only the tipping of a switch is relevant.
|
||||||
|
|
||||||
|
When also the time the button was pressed is relevant and when it is especially necessary to distinguish between a short and a long press this approach doesn't work anymore.
|
||||||
|
|
||||||
|
Since I couldn't remember the approaches I read about earlier I've sketched this state machine:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
(The double-lined states are action-states which send out the related information.)
|
||||||
|
|
||||||
|
At least for me, this approach is working very reliable so far, I'm quite happy with it.
|
||||||
|
|
||||||
|
```
|
||||||
|
enum tPressedState { psHIGH, psLOW, psACCEPTED_LOW, psLONG_START, psLONG_CONT, psLONG_CONT_SEND, psLONG_END, psSHORT, psINVALID };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t index;
|
||||||
|
uint8_t buttonPin;
|
||||||
|
tPressedState pressedState;
|
||||||
|
tPressedState oldPressedState;
|
||||||
|
uint32_t lastStateChange;
|
||||||
|
} tButton;
|
||||||
|
|
||||||
|
tButton buttons[] = {
|
||||||
|
{ 1, SWITCH_1, psHIGH, psINVALID, 0 },
|
||||||
|
{ 2, SWITCH_2, psHIGH, psINVALID, 0 },
|
||||||
|
{ 3, SWITCH_3, psHIGH, psINVALID, 0 },
|
||||||
|
{ 0, 0, psINVALID, psINVALID, 0 } // END MARKER
|
||||||
|
};
|
||||||
|
|
||||||
|
static void buttonHandler(tButton *button) {
|
||||||
|
uint32_t currentMicros = micros();
|
||||||
|
uint8_t buttonState = digitalRead(button->buttonPin);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (button->oldPressedState != button->pressedState) {
|
||||||
|
Serial.print("Index ");
|
||||||
|
Serial.print(button->index);
|
||||||
|
Serial.print(", state changed from ");
|
||||||
|
Serial.print(button->oldPressedState);
|
||||||
|
Serial.print(" to ");
|
||||||
|
Serial.print(button->pressedState);
|
||||||
|
Serial.println();
|
||||||
|
button->oldPressedState = button->pressedState;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (button->pressedState) {
|
||||||
|
case psHIGH:
|
||||||
|
if (buttonState == LOW) {
|
||||||
|
button->pressedState = psLOW;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case psLOW:
|
||||||
|
if (buttonState == HIGH) {
|
||||||
|
button->pressedState = psHIGH;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
} else {
|
||||||
|
if (currentMicros > (button->lastStateChange + configBlock.debounce)) {
|
||||||
|
button->pressedState = psACCEPTED_LOW;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case psACCEPTED_LOW:
|
||||||
|
if (buttonState == HIGH) {
|
||||||
|
button->pressedState = psSHORT;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
}
|
||||||
|
if (currentMicros > (button->lastStateChange + (configBlock.longPress * 1000))) {
|
||||||
|
button->pressedState = psLONG_START;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case psSHORT:
|
||||||
|
sendMsg(button->index, "PRESS_SHORT");
|
||||||
|
button->pressedState = psHIGH;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
break;
|
||||||
|
case psLONG_START:
|
||||||
|
sendMsg(button->index, "PRESS_LONG_START");
|
||||||
|
button->pressedState = psLONG_CONT;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
break;
|
||||||
|
case psLONG_CONT:
|
||||||
|
if (buttonState == HIGH) {
|
||||||
|
button->pressedState = psLONG_END;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
}
|
||||||
|
if (currentMicros > (button->lastStateChange + (configBlock.longPressRepeat * 1000))) {
|
||||||
|
button->pressedState = psLONG_CONT_SEND;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case psLONG_CONT_SEND:
|
||||||
|
sendMsg(button->index, "PRESS_LONG_CONT");
|
||||||
|
button->pressedState = psLONG_CONT;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
break;
|
||||||
|
case psLONG_END:
|
||||||
|
sendMsg(button->index, "PRESS_LONG_END");
|
||||||
|
button->pressedState = psHIGH;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
button->pressedState = psHIGH;
|
||||||
|
button->lastStateChange = currentMicros;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: "Three Phase Inverter - Second Service"
|
title: "Three Phase Inverter - Second Service"
|
||||||
|
date: "2016-12-19"
|
||||||
---
|
---
|
||||||
|
|
||||||
I wrote in October about my first try to build a simple three phase inverter, see [here]({{< ref "three-phase-inverter.md" >}}). In the first try I used four MSP430 microcontroller, one for the PWM of each phase and one to coordinate the phase shift of the three phases.
|
I wrote in October about my first try to build a simple three phase inverter, see [here]({{< ref "three-phase-inverter.md" >}}). In the first try I used four MSP430 microcontroller, one for the PWM of each phase and one to coordinate the phase shift of the three phases.
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: "Three Phase Inverter"
|
title: "Three Phase Inverter"
|
||||||
|
date: "2016-10-14"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
BIN
content/static/20180430110848869_0001.jpg
Normal file
BIN
content/static/20180430110848869_0001.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 378 KiB |
Loading…
x
Reference in New Issue
Block a user