Added threshold for activation point of buttons

Added filters for smoothing results of sensors
This commit is contained in:
Maksym 2024-09-05 03:17:57 +02:00
parent b5cee6a623
commit e27bc0d3e0
2 changed files with 74 additions and 34 deletions

View File

@ -16,7 +16,8 @@
"iomanip": "cpp", "iomanip": "cpp",
"limits": "cpp", "limits": "cpp",
"numeric": "cpp", "numeric": "cpp",
"streambuf": "cpp" "streambuf": "cpp",
"random": "cpp"
}, },
"C_Cpp_Runner.cCompilerPath": "gcc", "C_Cpp_Runner.cCompilerPath": "gcc",
"C_Cpp_Runner.cppCompilerPath": "g++", "C_Cpp_Runner.cppCompilerPath": "g++",

View File

@ -2,14 +2,22 @@
#include <pico.h> #include <pico.h>
#include <hardware/pwm.h> #include <hardware/pwm.h>
#include <Keyboard.h> #include <Keyboard.h>
#define PORT 2 #define PORT 2
#define PORT2 3 #define PORT2 3
#define THRESHOLD 10
class HallButton class HallButton
{ {
public: public:
uint64_t firstPulseStart; uint64_t firstPulseStart;
uint64_t firstPulseLength; uint8_t counter = 0;
bool isDataReadyToRead; uint64_t firstPulseLength[3]; // value of button
int64_t value;
uint64_t _median;
bool isDataReadyToRead = false;
bool isButtonPressed = false;
uint64_t nextTogglePoint = 0; // value when to toggle state of button
HallButton(uint8_t gpioNum, char buttonOnKeyboard) HallButton(uint8_t gpioNum, char buttonOnKeyboard)
{ {
@ -21,8 +29,10 @@ public:
{ {
if (gpioState) if (gpioState)
{ {
firstPulseLength = currentTime - firstPulseStart; firstPulseLength[counter] = currentTime - firstPulseStart;
isDataReadyToRead = true; isDataReadyToRead = true;
if (++counter >= 3)
counter = 0;
} }
else else
{ {
@ -31,24 +41,71 @@ public:
} }
void HandleButton() void HandleButton()
{ {
if (!buttonPressed && firstPulseLength > 310) if (!isDataReadyToRead)
return;
_median = median(firstPulseLength[0], firstPulseLength[1], firstPulseLength[2]);
value = filtered((float)_median);
if (nextTogglePoint == 0)
nextTogglePoint = value + THRESHOLD;
if (isButtonPressed)
{ {
Keyboard.press(buttonOnKeyboard); if (value < nextTogglePoint)
buttonPressed = true;
}
else if (buttonPressed && firstPulseLength < 300)
{ {
Keyboard.release(buttonOnKeyboard); Release();
buttonPressed = false;
} }
if ((int64_t)value - (int64_t)nextTogglePoint > THRESHOLD)
nextTogglePoint = value - THRESHOLD;
}
else
{
if (value >= nextTogglePoint)
{
Press();
}
if ((int64_t)nextTogglePoint - (int64_t)value > THRESHOLD)
nextTogglePoint = value + THRESHOLD;
}
isDataReadyToRead = false;
}
uint64_t median(uint64_t a, uint64_t b, uint64_t c)
{
return (a < b) ? ((b < c) ? b : ((c < a) ? a : c)) : ((a < c) ? a : ((c < b) ? b : c));
}
float filtered(float value)
{
float _kalman_gain, _current_estimate;
_kalman_gain = _err_estimate / (_err_estimate + _err_measure);
_current_estimate = _last_estimate + _kalman_gain * (value - _last_estimate);
_err_estimate = (1.0 - _kalman_gain) * _err_estimate + fabs(_last_estimate - _current_estimate) * _q;
_last_estimate = _current_estimate;
return _current_estimate;
} }
private: private:
bool buttonPressed; float _err_measure = 15;
float _err_estimate = 15;
float _q = 0.1;
float _last_estimate = 0.0;
uint8_t gpioNum; uint8_t gpioNum;
char buttonOnKeyboard; char buttonOnKeyboard;
void Press()
{
if (isButtonPressed)
return;
Keyboard.press(buttonOnKeyboard);
isButtonPressed = true;
}
void Release()
{
if (!isButtonPressed)
return;
Keyboard.release(buttonOnKeyboard);
isButtonPressed = false;
}
}; };
HallButton btn[2] = {HallButton(PORT, 't'), HallButton(PORT2, 'y')}; HallButton btn[2] = {HallButton(PORT, 't'), HallButton(PORT2, 'y')};
void isr(uint gpio, uint32_t events) void isr(uint gpio, uint32_t events)
{ {
uint64_t currentTime = time_us_64(); uint64_t currentTime = time_us_64();
@ -66,8 +123,6 @@ void isr(uint gpio, uint32_t events)
void setup() void setup()
{ {
Keyboard.begin();
Serial.begin(115200);
gpio_init(PORT); gpio_init(PORT);
gpio_set_dir(PORT, false); gpio_set_dir(PORT, false);
gpio_pull_up(PORT); gpio_pull_up(PORT);
@ -76,30 +131,14 @@ void setup()
gpio_set_dir(PORT2, false); gpio_set_dir(PORT2, false);
gpio_pull_up(PORT2); gpio_pull_up(PORT2);
gpio_set_irq_enabled_with_callback(PORT2, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, isr); gpio_set_irq_enabled_with_callback(PORT2, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, isr);
// Serial.begin(9600);
Keyboard.begin();
} }
#define printf Serial.printf
byte counter = 0;
void printDebugInfo() void printDebugInfo()
{ {
if (counter < 1 && btn[0].isDataReadyToRead) Serial.printf("%llu,%llu,%llu,%llu,%i,", btn[0].firstPulseLength[btn[0].counter], btn[0]._median, btn[0].value, btn[0].nextTogglePoint, btn[0].isButtonPressed);
{ Serial.printf("%llu,%llu,%llu,%llu,%i\n", btn[1].firstPulseLength[btn[1].counter], btn[1]._median, btn[1].value, btn[1].nextTogglePoint, btn[1].isButtonPressed);
btn[0].isDataReadyToRead = false;
printf("BTN1: %lu", btn[0].firstPulseLength);
counter++;
}
if (btn[1].isDataReadyToRead)
{
btn[1].isDataReadyToRead = false;
if (counter > 0)
printf("\t");
printf("BTN2: %lu", btn[1].firstPulseLength);
counter++;
}
if (counter > 1)
{
printf("\n");
counter = 0;
}
} }
void loop() void loop()
{ {