ARDUINO Помогите с обработчиком кнопок

VanGelmont

✩✩✩✩✩✩✩
11 Окт 2023
5
0
Здравствуйте, я пытаюсь сделать функцию обработчика кнопок (btn),но она корректно работает только когда к ней обращается не больше чем одна переменная(при двух переменных флаги не выставляются) подскажите почему так и как это исправить пожалуйста

тут работает верно:
int teach_Btn = 12;
int inp = 13;

int nb;
bool flag;
uint32_t btnTimer = 0;

void setup()
{
   pinMode(teach_Btn, INPUT_PULLUP);
   pinMode(13, INPUT_PULLUP);
   pinMode(2, OUTPUT);
   Serial.begin(9600);
}

bool btn(int nb_btn)
{

   if (!digitalRead(nb_btn) && !flag && millis() - btnTimer > 100)
   {
      flag = true;
      btnTimer = millis();
      return true;
   }
   if (digitalRead(nb_btn) && flag && millis() - btnTimer > 100)
   {
      flag = false;
      btnTimer = millis();
   }
   return false;
}
void loop()
{
  
   /*
    if(btn(teach_Btn) == true){
      
         nb = 0;
   }
   */
   digitalWrite(2,LOW);
   if (btn(inp) == true)
   {
      nb++;
      Serial.println(nb);
      digitalWrite(2,HIGH); 
   }     
}
а тут нет:
int teach_Btn = 12;
int inp = 13;

int nb;
bool flag;
uint32_t btnTimer = 0;

void setup()
{
   pinMode(teach_Btn, INPUT_PULLUP);
   pinMode(13, INPUT_PULLUP);
   pinMode(2, OUTPUT);
   Serial.begin(9600);
}

bool btn(int nb_btn)
{

   if (!digitalRead(nb_btn) && !flag && millis() - btnTimer > 100)
   {
      flag = true;
      btnTimer = millis();
      return true;
   }
   if (digitalRead(nb_btn) && flag && millis() - btnTimer > 100)
   {
      flag = false;
      btnTimer = millis();
   }
   return false;
}
void loop()
{
  
  
    if(btn(teach_Btn) == true){
      
         nb = 0;
   }
  
   digitalWrite(2,LOW);
   if (btn(inp) == true)
   {
      nb++;
      Serial.println(nb);
      digitalWrite(2,HIGH); 
   }     
}
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,277
1,303
Москва
А что вернет функция btn если тамер не отсчитал 100мс ?
А почему в цикле loop 2 раза значение из функции btn сравнивается с true ?
 

VanGelmont

✩✩✩✩✩✩✩
11 Окт 2023
5
0
А что вернет функция btn если тамер не отсчитал 100мс ?
"false" она возвращает

А почему в цикле loop 2 раза значение из функции btn сравнивается с true ?
А как по другому опросить две разные кнопки?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,277
1,303
Москва
Фальш, а должна ли она это делать?
А как по другому опросить две разные кнопки?
Да, я не туда посмотрел. Но у получается что разные кнопки опрашиваются по одному таймеру : btnTimer = millis(); Соответственно когда сработала одна кнопка, вторая уже не опрашивается.
 

VanGelmont

✩✩✩✩✩✩✩
11 Окт 2023
5
0
Фальш, а должна ли она это делать?
ну там же два if, оба с условием >100 "return false" идёт сразу после второго if, соответственно оба условия неверны и функция возвращает false
Да, я не туда посмотрел. Но у получается что разные кнопки опрашиваются по одному таймеру : btnTimer = millis(); Соответственно когда сработала одна кнопка, вторая уже не опрашивается.
ну пусть, проблема заключается в том что функция не выставляет флаги, а одновременная обработка мне не нужна
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,277
1,303
Москва
Ок. Как должна работать эта функция ?

ну пусть, проблема заключается в том что функция не выставляет флаги, а одновременная обработка мне не нужна
Проблема в том, что если сработала одна кнопка, то вторая не будет работать. Т.е. теоретически может получиться вариант когда будет работать только одна кнопка, или скажем 10 000 раз будет работать кнопка 1, а потом 10 000 раз кнопка два. Так устроит ?

Добавлю. Второе условие получается бессмысленное в функции btn, т.к. что оно выполняется, что нет - выдавать будет false

Если хочется опрашивать по таймеру кнопки, то тогда лучше сделать так:
если прошло боьше 100 мс, то :
опросить кнопку 1.
опросить кнопку 2.
запомнить новое.

а в функции опроса кнопок убрать таймеры.
И еще учесть, что флаг как устанавливается так и сбрасывается любой из кнопок. Т.е. можно установить одной, а сбросить другой.
 
Изменено:

VanGelmont

✩✩✩✩✩✩✩
11 Окт 2023
5
0
Ок. Как должна работать эта функция ?
Принять номер пина кнопки
Если А.кнопка нажата
Б.флаг опущен
В. С прошлого нажатия прошло более 100мс
То
1.поднять флаг
2.сбросить таймер
3. Вернуть 1

Если А.кнопка отпущена
Б.флаг выставлен
В. С прошлого нажатия прошло более 100мс
То
1.опустить флаг
2.сбросить таймер
3. Вернуть 0
Проблема в том, что если сработала одна кнопка, то вторая не будет работать. Т.е. теоретически может получиться вариант когда будет работать только одна кнопка, или скажем 10 000 раз будет работать кнопка 1, а потом 10 000 раз кнопка два. Так устроит ?
Хорошо пусть 100мс опрашивается только одна кнопка
Добавлю. Второе условие получается бессмысленное в функции btn, т.к. что оно выполняется, что нет - выдавать будет false
Почему? оно сбрасывает флаг после 100мс который необходим для запуска первого условия

Если хочется опрашивать по таймеру кнопки, то тогда лучше сделать так:
если прошло боьше 100 мс, то :
опросить кнопку 1.
опросить кнопку 2.
запомнить новое.
А если их больше чем две? каждый раз дописывать? как то хочется функцию
а в функции опроса кнопок убрать таймеры.
А как дребезг давить без rc цепи?
 

Сотнег

★★★★★★★
15 Янв 2020
4,455
1,523
Почему не взять готовую библиотеку с обработчиком кнопок?
Хотя бы для изучения...
 

VanGelmont

✩✩✩✩✩✩✩
11 Окт 2023
5
0
Ну я думал что тут что-то очевидное, а там в библиотеке: классы, структуры, всё непонятное, но я попробую
 

Сотнег

★★★★★★★
15 Янв 2020
4,455
1,523
@VanGelmont,
для каждой кнопки нужно создавать флаги и таймеры.
Классы нужны в том числе, чтобы это делать одной строчкой.
 
  • Лойс +1
Реакции: VanGelmont

Старик Похабыч

★★★★★★★
14 Авг 2019
4,277
1,303
Москва
Хорошо пусть 100мс опрашивается только одна кнопка
С одной кнопкой должно работать.

Добавка. Даже с 2-мя работает как ни странно, но мышкой 2 нажать не получиться, так что по очереди . Но светодиод на 2-м пине гасится совсем не в том месте - он гасится каждый цикл, т.е. постоянно.

 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,277
1,303
Москва
А как дребезг давить без rc цепи?
Я выше написал самое 1-ое условие. Проверка всех кнопок запускается по интервалу, там и идет антитдребезг и один таймер на все проверки всех кнопок.

Почему? оно сбрасывает флаг после 100мс который необходим для запуска первого условия
Флаг сбрасывать надо, да, я опять не внимательно посмотрел.
 
  • Лойс +1
Реакции: VanGelmont