Сильно не пинайте, давно не развлекался и уже всё забыл. Управляю люком авто в двух направлениях. сам люк двигается. Но встал в тупик на элементарном.
вырезал основное:
#define BUTTON1F 2
#define BUTTON1R 4
#define BUTTON_LONG_PRESS_TIME 800 //время длинного нажатия кнопки
#define STABILB 20 // время стабилизации дребезга контактов кнопок
bool isRun1 = false; // статус - мотор в движении
uint32_t testTime; // эмуляция мотора
//физическое состояние кнопки
enum ButtonResult {
buttonNotPress, //если кнопка не нажата
button_shortPress, //код короткого нажатия
button_longPress //код длинного нажатия
};
struct ButtonConfiguration {
//состояние кнопки
enum ButtonResult curent;
//отпускание кнопки
bool depressed;
//блокировка состояния
bool lock;
//номер входа, к которому подключена кнопка
uint8_t pin;
//для измерения длительности нажатия
uint32_t pressingTime;
};
//--------------------------------------------------
//для хранения параметров кнопки
struct ButtonConfiguration button1F = {
.curent = buttonNotPress,
.depressed = false,
.lock = false,
.pin = BUTTON1F,
.pressingTime = 0
};
struct ButtonConfiguration button1R = {
.curent = buttonNotPress,
.depressed = false,
.lock = false,
.pin = BUTTON1R,
.pressingTime = 0
};
void setup() {
// входы кнопок
pinMode(BUTTON1F, INPUT_PULLUP);
pinMode(BUTTON1R, INPUT_PULLUP);
//отладка
Serial.begin(9600);
}
void ButtonCheck(struct ButtonConfiguration &button) {
bool btnState = !digitalRead(button.pin); // читаем состояние пина и переворачиваем
//если кнопка нажата
if (btnState && button.curent == buttonNotPress && millis() - button.pressingTime > STABILB)
{
button.curent = button_shortPress;
button.pressingTime = millis();
}
//если кнопка не нажата
if (!btnState && button.curent != buttonNotPress && millis() - button.pressingTime > STABILB)
{
button.curent = buttonNotPress;
button.pressingTime = millis();
}
// если нажата долго
if (btnState && button.curent == button_shortPress && millis() - button.pressingTime > BUTTON_LONG_PRESS_TIME)
{
button.curent = button_longPress;
//button->pressingTime = millis();
}
if(isRun1)
{
if ((button.depressed == false) && (button.curent == buttonNotPress))
{
Serial.print("test\tRun=");
Serial.print(isRun1);
Serial.print("\tbuttoncurent=");
Serial.print(button.curent);
Serial.print("\t1R=");
Serial.print(button1R.curent);
Serial.print("\t1F=");
Serial.print(button1F.curent);
Serial.print("\tdepressed=");
Serial.print(button.depressed);
Serial.print("\tb=");
Serial.println(!digitalRead(button.pin));
button.depressed = true;
}
}
}
void loop() {
// читаем состояние кнопок
ButtonCheck(button1F);
ButtonCheck(button1R);
if (button1F.curent == button_shortPress)
{
if(!isRun1) Serial.println("run_front");
isRun1 = true;
testTime = millis();
}
else if (button1R.curent == button_shortPress)
{
if(!isRun1) Serial.println("run_rear");
isRun1 = true;
testTime = millis();
}
if (isRun1 && millis() - testTime > 5000)
{
Serial.println("run_stop");
isRun1 = false;
button1R.depressed = false;
button1F.depressed = false;
}
}
выхлоп от сюда
18:20:22.195 -> run_rear
18:20:22.195 -> test Run=1 buttoncurent=0 1R=1 1F=0 depressed=0 b=0
18:20:23.093 -> test Run=1 buttoncurent=0 1R=0 1F=0 depressed=0 b=0
18:20:28.113 -> run_stop
18:20:32.154 -> run_front
18:20:32.154 -> test Run=1 buttoncurent=0 1R=0 1F=1 depressed=0 b=0
18:20:32.828 -> test Run=1 buttoncurent=0 1R=0 1F=0 depressed=0 b=0
18:20:37.842 -> run_stop
видно, что кнопки отрабатывают верно. Нужен статус отпущенной кнопки во время движения. в связи чем пытаюсь реализовать со строки 75. И не понимаю что происходит:
почему попадаю туда два раза( при нажатии и отпускании)?
2)почему всегда возврат 0 в строке 82?
Первый раз Вы попадаете туда при нажатии в контексте “другой” (не нажатой) кнопки, а второй раз при отпускании в контексте “своей” кнопки. Я добавил кнопкам имена и поставил вывод имён, сами посмотрите (я заменил Ваши табуляции пробелами, на моём мониторе с табуляциями напряг).
Потому что при нажатии Вы печатаете это добро в контексте “другой” не нажатой кнопки, а при отпускании - в контексте своей, но уже отпущенной, т.е. когда там уже восстановилось в “нот пресс”.
Код с именами кнопок
#define BUTTON1F 2
#define BUTTON1R 4
#define BUTTON_LONG_PRESS_TIME 800 //время длинного нажатия кнопки
#define STABILB 20 // время стабилизации дребезга контактов кнопок
bool isRun1 = false; // статус - мотор в движении
uint32_t testTime; // эмуляция мотора
//физическое состояние кнопки
enum ButtonResult {
buttonNotPress, //если кнопка не нажата
button_shortPress, //код короткого нажатия
button_longPress //код длинного нажатия
};
struct ButtonConfiguration {
const char * name;
//состояние кнопки
enum ButtonResult curent;
//отпускание кнопки
bool depressed;
//блокировка состояния
bool lock;
//номер входа, к которому подключена кнопка
uint8_t pin;
//для измерения длительности нажатия
uint32_t pressingTime;
};
//--------------------------------------------------
//для хранения параметров кнопки
struct ButtonConfiguration button1F = {
.name = "BTN_F",
.curent = buttonNotPress,
.depressed = false,
.lock = false,
.pin = BUTTON1F,
.pressingTime = 0
};
struct ButtonConfiguration button1R = {
.name = "BTN_R",
.curent = buttonNotPress,
.depressed = false,
.lock = false,
.pin = BUTTON1R,
.pressingTime = 0
};
void setup() {
// входы кнопок
pinMode(BUTTON1F, INPUT_PULLUP);
pinMode(BUTTON1R, INPUT_PULLUP);
//отладка
Serial.begin(9600);
}
void ButtonCheck(struct ButtonConfiguration &button) {
bool btnState = !digitalRead(button.pin); // читаем состояние пина и переворачиваем
//если кнопка нажата
if (btnState && button.curent == buttonNotPress && millis() - button.pressingTime > STABILB)
{
button.curent = button_shortPress;
button.pressingTime = millis();
}
//если кнопка не нажата
if (!btnState && button.curent != buttonNotPress && millis() - button.pressingTime > STABILB)
{
button.curent = buttonNotPress;
button.pressingTime = millis();
}
// если нажата долго
if (btnState && button.curent == button_shortPress && millis() - button.pressingTime > BUTTON_LONG_PRESS_TIME)
{
button.curent = button_longPress;
//button->pressingTime = millis();
}
if(isRun1)
{
if ((button.depressed == false) && (button.curent == buttonNotPress))
{
Serial.print(button.name);
Serial.print(": ");
Serial.print("test Run=");
Serial.print(isRun1);
Serial.print(" buttoncurent=");
Serial.print(button.curent);
Serial.print(" 1R=");
Serial.print(button1R.curent);
Serial.print(" 1F=");
Serial.print(button1F.curent);
Serial.print(" depressed=");
Serial.print(button.depressed);
Serial.print(" b=");
Serial.println(!digitalRead(button.pin));
button.depressed = true;
}
}
}
void loop() {
// читаем состояние кнопок
ButtonCheck(button1F);
ButtonCheck(button1R);
if (button1F.curent == button_shortPress)
{
if(!isRun1) Serial.println("run_front");
isRun1 = true;
testTime = millis();
}
else if (button1R.curent == button_shortPress)
{
if(!isRun1) Serial.println("run_rear");
isRun1 = true;
testTime = millis();
}
if (isRun1 && millis() - testTime > 5000)
{
Serial.println("run_stop");
isRun1 = false;
button1R.depressed = false;
button1F.depressed = false;
}
}
Спасибо большое, осознал.
Идеально работающие кнопки я делал в таймерном прерывании, причем дребезг убирался только при замыкании, тк у разомкнутой дребезга быть не может. Первое замыкание - сработка; ждем отпускания с таймером. Тогда кнопки быстрые.
nik182
17.Октябрь.2024 21:05:24
5
А какая разница? Замыкание размыкание подпружиненного контакта с механической точки зрения процессы похожие. И дребезг похож.
Когда кнопка отпущена всегда 1. Когда нажата контакт может пропадать. В этом разница.
SAB
22.Январь.2025 01:56:14
7
При размыкании копки дребезг такой же, а может ещё и хуже чем при замыкании в плане возникновения обратной эдс, если коммутируется индуктивная нагрузка. Следуя вашей логике в замкнутом состоянии всегда 0, что совершенно не связано с дребезгом.
Моя логика проверена годами, « Первое замыкание - сработка; ждем отпускания с таймером.» я же написал.
То есть: мы НЕ ждем надежного замыкания, сразу выдаем чо ЕстьНажатие.
А вот потом ждем размыкания: Если замкнуто - сброс таймера отжатия, ждем дальше.