This commit is contained in:
Wolfgang Hottgenroth 2025-01-14 17:10:05 +01:00
parent 87b2a3cec2
commit 374685e92c
Signed by: wn
GPG Key ID: 18FDFA577A8871AD
4 changed files with 139 additions and 0 deletions

View 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 &gt; (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:
![](/20180430110848869_0001.jpg)
(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-&gt;buttonPin);
#ifdef DEBUG
if (button-&gt;oldPressedState != button-&gt;pressedState) {
Serial.print("Index ");
Serial.print(button-&gt;index);
Serial.print(", state changed from ");
Serial.print(button-&gt;oldPressedState);
Serial.print(" to ");
Serial.print(button-&gt;pressedState);
Serial.println();
button-&gt;oldPressedState = button-&gt;pressedState;
}
#endif
switch (button-&gt;pressedState) {
case psHIGH:
if (buttonState == LOW) {
button-&gt;pressedState = psLOW;
button-&gt;lastStateChange = currentMicros;
}
break;
case psLOW:
if (buttonState == HIGH) {
button-&gt;pressedState = psHIGH;
button-&gt;lastStateChange = currentMicros;
} else {
if (currentMicros &gt; (button-&gt;lastStateChange + configBlock.debounce)) {
button-&gt;pressedState = psACCEPTED_LOW;
button-&gt;lastStateChange = currentMicros;
}
}
break;
case psACCEPTED_LOW:
if (buttonState == HIGH) {
button-&gt;pressedState = psSHORT;
button-&gt;lastStateChange = currentMicros;
}
if (currentMicros &gt; (button-&gt;lastStateChange + (configBlock.longPress * 1000))) {
button-&gt;pressedState = psLONG_START;
button-&gt;lastStateChange = currentMicros;
}
break;
case psSHORT:
sendMsg(button-&gt;index, "PRESS_SHORT");
button-&gt;pressedState = psHIGH;
button-&gt;lastStateChange = currentMicros;
break;
case psLONG_START:
sendMsg(button-&gt;index, "PRESS_LONG_START");
button-&gt;pressedState = psLONG_CONT;
button-&gt;lastStateChange = currentMicros;
break;
case psLONG_CONT:
if (buttonState == HIGH) {
button-&gt;pressedState = psLONG_END;
button-&gt;lastStateChange = currentMicros;
}
if (currentMicros &gt; (button-&gt;lastStateChange + (configBlock.longPressRepeat * 1000))) {
button-&gt;pressedState = psLONG_CONT_SEND;
button-&gt;lastStateChange = currentMicros;
}
break;
case psLONG_CONT_SEND:
sendMsg(button-&gt;index, "PRESS_LONG_CONT");
button-&gt;pressedState = psLONG_CONT;
button-&gt;lastStateChange = currentMicros;
break;
case psLONG_END:
sendMsg(button-&gt;index, "PRESS_LONG_END");
button-&gt;pressedState = psHIGH;
button-&gt;lastStateChange = currentMicros;
break;
default:
button-&gt;pressedState = psHIGH;
button-&gt;lastStateChange = currentMicros;
}
}
```

View File

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

View File

@ -1,5 +1,6 @@
--- ---
title: "Three Phase Inverter" title: "Three Phase Inverter"
date: "2016-10-14"
--- ---

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB