Nano сходит с ума

Видя все эти «муки» возникает вопрос справедливый - Библиотеку для кнопки использовать пробовали?

Не нашел нужной

Возникает резонный вопрос - А ЧТО НУЖНО?

  1. GitHub - kakmyc-github/kakmyc_btn (постоянно сам пользуюсь)
  2. GitHub - VAleSh-Soft/shButton: Библиотека для работы с тактовыми кнопками в Ардуино (более продвинутый вариант, есть работа с аналоговыми кнопками и матрицами (на сколько я знаю, автор на форуме - поправит если ошибаюсь)).

Чо надо то???

Вроде у Гайвера нашел…

Задача простая, есть n-Кол-во кнопок, каждая из которых управляет двумя нагрузками, и есть еще одна кнопка, которая отключает определенные (или все) нагрузки.

Опять же. Хотелось бы самому все написать. Библиотеки это хорошо. Но знания лучше!

И теперь вы на форуме “сами” пишете…

1 лайк

Да я помощи попросил, это мне кажется практичнее чем убивать время, на разбор кода который кто-то написал. Если бы мне было 15 лет, без сомнения я бы так и сделал. Но не сейчас, не в свои 30.

на форуме ))

Вот небольшой гайд по работе с кнопками
https://forum.arduino.ru/t/podklyuchenie-knopki-i-schityvanie-nazhatiya-knopki

Там же ссылка на тему на старом форуме с более детальным руководством

Здесь средний возраст участников - около полтинника, так что ваши 30 лет совсем не впечатляют ))
Но желание разобраться похвально и приветствуется

Спасибо! изучу

Я не собирался никого впечатлять, просто констатировал.

Приведённая цитата содержит ноль информации. Буквально несколько дней назад в какой-то соседней теме об этом уже говорил. Если хотите дальше в своём коде разбираться, то приводите исправленный, актуальный скетч. Далее подробно описываете, что делаете, что по Вашим ожиданиям должно произойти, и что реально происходит. Типа такого: коротко нажимаю кнопку номер 1, в мониторе порта должна появиться одна цифра “1”, а появляются три единицы и пять двоек!
Или забейте на этот код и, как Вам уже предложили, возьмите готовую библиотеку для работы с кнопками. Используйте её.

p.s. На приколы по поводу возраста не обижайтесь. Здесь очень часто приходят новички, которые сразу выкладывают аргумент, якобы почему им так трудно, почему у них ничего не выходит, почему все обязаны им помогать, и это обычно - мне мол уже 60, мне уже под 70. Поэтому о Ваших 30 на этом фоне и шутят.

Предоставляю исправленный код. При нажатии на кнопку 1 единожды должно в мониторе порта прописаться а1, многократно - а2. при нажатии на кнопку 2 аналогично (в1 в2)

#define BUTTON_PIN_2 19
#define BUTTON_PIN_1 18

short bounceTime = 100;          // задержка для подавления дребезга
short doubleTime = 2000;         // время, в течение которого нажатия можно считать двойным
short i_1 = 0;
short i_2 = 0;                    // Счетчик для подсчета количества двойных нажатий кнопки

boolean lastReading_1 = false;  // флаг предыдущего состояния кнопки
boolean lastReading_2 = false;
boolean buttonSingle_1 = false; // флаг состояния "краткое нажатие"
boolean buttonMulti_1 = false; // флаг состояния "двойное нажатие"
boolean buttonSingle_2 = false; // флаг состояния "краткое нажатие"
boolean buttonMulti_2 = false;
 
boolean read_1 = 0;
boolean read_2 = 0;
boolean read_3 = 0;
boolean read_4 = 0;

long onTime_1 = 0;              // переменная обработки временного интервала
long lastSwitchTime_1 = 0;      // переменная времени предыдущего переключения состояния
long onTime_2 = 0;              // переменная обработки временного интервала
long lastSwitchTime_2 = 0;      // переменная времени предыдущего переключения состояния


void setup(){
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  Serial.begin(9600);         // Настройка последовательного порта для вывода данных
}

void loop(){
  // Считывание состояния кнопки
  boolean reading_1 = digitalRead(BUTTON_PIN_1);
  boolean reading_2 = digitalRead(BUTTON_PIN_2);

  // проверка первичного нажатия
  if (reading_1 && !lastReading_1){
      // Если кнопка только что была нажата (текущее состояние кнопки "reading" равно true, а предыдущее состояние "lastReading" равно false),
      // то сохраняем текущее время в переменную "onTime"
    onTime_1 = millis();
  }
  if (reading_2 && !lastReading_2){
      // Если кнопка только что была нажата (текущее состояние кнопки "reading" равно true, а предыдущее состояние "lastReading" равно false),
      // то сохраняем текущее время в переменную "onTime"
    onTime_2 = millis();
  }
  // Проверка отпускания кнопки
  if (!reading_1 && lastReading_1){
      // Если кнопка только что была отпущена (текущее состояние кнопки "reading" равно false, а предыдущее состояние "lastReading" равно true),
      // то проверяем, прошла ли задержка для подавления дребезга
    if (((millis() - onTime_1) > bounceTime)){
      // Если прошла задержка для подавления дребезга, то проверяем, прошло ли достаточно времени с момента последнего переключения для определения двойного нажатия
      if ((millis() - lastSwitchTime_1) >= doubleTime){
      // Если прошло достаточно времени с момента последнего переключения, то устанавливаем флаг "buttonSingle" в true,
      // сбрасываем счетчик "i" в 1 и обновляем время последнего переключения "lastSwitchTime"
        lastSwitchTime_1 = millis();
        buttonSingle_1 = true;
        i_1=1;
      } else {
      // Если не прошло достаточно времени, то увеличиваем счетчик "i" и обновляем время последнего переключения "lastSwitchTime",
      // а также устанавливаем флаг "buttonSingle" в false и флаг "buttonMulti" в true
        i_1++;
        lastSwitchTime_1 = millis();
        buttonSingle_1 = false;
        buttonMulti_1 = true;
      }
    }
  }
  if (!reading_2 && lastReading_2){
      // Если кнопка только что была отпущена (текущее состояние кнопки "reading" равно false, а предыдущее состояние "lastReading" равно true),
      // то проверяем, прошла ли задержка для подавления дребезга
    if (((millis() - onTime_2) > bounceTime)){
      // Если прошла задержка для подавления дребезга, то проверяем, прошло ли достаточно времени с момента последнего переключения для определения двойного нажатия
      if ((millis() - lastSwitchTime_2) >= doubleTime){
      // Если прошло достаточно времени с момента последнего переключения, то устанавливаем флаг "buttonSingle" в true,
      // сбрасываем счетчик "i" в 1 и обновляем время последнего переключения "lastSwitchTime"
        lastSwitchTime_2 = millis();
        buttonSingle_2 = true;
        i_2=1;
      } else {
      // Если не прошло достаточно времени, то увеличиваем счетчик "i" и обновляем время последнего переключения "lastSwitchTime",
      // а также устанавливаем флаг "buttonSingle" в false и флаг "buttonMulti" в true
        i_2++;
        lastSwitchTime_2 = millis();
        buttonSingle_2 = false;
        buttonMulti_2 = true;
      }
    }
  }
  // Сохранение текущего состояния кнопки
  lastReading_1 = reading_1;
  // Проверка состояния "краткое нажатие" и времени с момента последнего переключения
  if (buttonSingle_1 && (millis() - lastSwitchTime_1) > doubleTime){
  // Если флаг "buttonSingle" установлен в true и прошло достаточно времени с момента последнего переключения,
  // вызываем функцию для обработки состояния "краткое нажатие"
    isButtonSingle_1();
  }
  // Проверка состояния "двойное нажатие" и времени с момента последнего переключения
  if (buttonMulti_1 && (millis() - lastSwitchTime_1) > doubleTime){
  // Если флаг "buttonMulti" установлен в true и прошло достаточно времени с момента последнего переключения,
  // вызываем функцию для обработки состояния "двойное нажатие" и передаем ей значение счетчика "i"
    isButtonMulti_1(i_1);
  }
    lastReading_2 = reading_2;
  // Проверка состояния "краткое нажатие" и времени с момента последнего переключения
  if (buttonSingle_2 && (millis() - lastSwitchTime_2) > doubleTime){
  // Если флаг "buttonSingle" установлен в true и прошло достаточно времени с момента последнего переключения,
  // вызываем функцию для обработки состояния "краткое нажатие"
    isButtonSingle_2();
  }
  // Проверка состояния "двойное нажатие" и времени с момента последнего переключения
  if (buttonMulti_2 && (millis() - lastSwitchTime_2) > doubleTime){
  // Если флаг "buttonMulti" установлен в true и прошло достаточно времени с момента последнего переключения,
  // вызываем функцию для обработки состояния "двойное нажатие" и передаем ей значение счетчика "i"
    isButtonMulti_2(i_2);
  }
}

// Функция для обработки состояния "краткое нажатие"
void isButtonSingle_1(){
  // Сбрасываем флаги состояний "краткое нажатие" и "двойное нажатие"
    buttonMulti_1 = false;
    buttonSingle_1 = false;
  // Выводим значение 1 в последовательный порт
    Serial.println("a1");
    read_1 = !read_1;
    digitalWrite(2, read_1);
}
// Функция для обработки состояния "двойное нажатие"
void isButtonMulti_1( short count ){
  // Сбрасываем флаги состояний "краткое нажатие" и "двойное нажатие"
    buttonSingle_1 = false;
    buttonMulti_1 = false;
  // Выводим значение count (количество нажатий) в последовательный порт
    Serial.println("a2");
    read_2 = !read_2;
    digitalWrite(3, read_2);
}
// Функция для обработки состояния "краткое нажатие"
void isButtonSingle_2(){
  // Сбрасываем флаги состояний "краткое нажатие" и "двойное нажатие"
    buttonMulti_2 = false;
    buttonSingle_2 = false;
  // Выводим значение 1 в последовательный порт
    Serial.println("b1");
    read_3 = !read_3;
    digitalWrite(4, read_3);
}
// Функция для обработки состояния "двойное нажатие"
void isButtonMulti_2( short count ){
  // Сбрасываем флаги состояний "краткое нажатие" и "двойное нажатие"
    buttonSingle_2 = false;
    buttonMulti_2 = false;
  // Выводим значение count (количество нажатий) в последовательный порт
    Serial.println("b2");
    read_4 = !read_4;
    digitalWrite(5, read_4);
}

Во первых, разбирать чужой код всегда полезно в плане развития. Во вторых, прелесть готовых библиотек состоит в том, что в их потрохах ковыряться не обязательно, достаточно использовать публичные методы, этими библиотеками предоставляемые. Например:

#include <shButton.h> // https://github.com/VAleSh-Soft/shButton

#define BTN_PIN 10 // пин, к которому подключена кнопка

shButton but(BTN_PIN); 

void setup()
{
  but.setVirtualClickOn(); // включение режима виртуального клика

  Serial.begin(9600);
}

void loop()
{

  switch (but.getButtonState())
  {
  case BTN_ONECLICK:
    // действие по одинарному клику 
    Serial.println("onClick");
    break;
  case BTN_DBLCLICK:
    // действие по двойному клику
    Serial.println("onDblClick");
    break;
  }
}

Что значит “многократно”? В комментариях к коду фигурирует “двойное нажатие”. Вы об этом?
И не написали вторую половину - а в реальности происходит что? В каждом конкретном случае?

В реальности на любую кнопку жмешь, а работает как-будто сразу на две нажал. единственно что работает это реакция на 1 и несколько нажатий.

Да есть такое. это на перспективу. При чтении переменной i_n но не факт что буду применять. А так пока одинаково будет что 2 что 3 что 132 нажатия.

Ну как так-то? В начале предложения пишете, что на одно нажатие реакция неправильная, значит не работает, а в конце это уже оказывается единственное, что работает. Пойми тут чего!
И нужно конкретно, без всяких “как-будто сразу на две нажал” писать - нажал один раз на кнопку 1, в мониторе порта появилось…
Это не придирки. Вам легко, перед Вами собранное устройство, а здесь Вам пытаются что-то подсказать видя только Ваш код и Ваши описания его работы. Поэтому всё должно быть максимально чётко.

Ну тут вообще ерунда написана. Не может быть одинаково, “что на 2, что на 3…”. Вы в коде-то что имели ввиду? Если ничего, лишь бы что-то написать, и Вам это сейчас не нужно - выкинте всё про многократные нажатия нафиг! Пусть хоть без них-то заработает.
На этом пока всё, время позднее уже…

Даже если в логике работы с кнопками остались ошибки, я не вижу каких либо пересечений кнопок между собой. Переменные и функции относящиеся к первой и второй кнопке вроде нигде не попутаны. Так что по коду я не вижу предпосылок, чтобы при нажатии на одну кнопку была реакция и на вторую.
Проверяйте схему, качество всех соединений. Вероятно, что причина там. Особенно если это макетка-breadboard.

1 лайк

Я за схему и спрашивал изначально… Что может кто сталкивался. как подключено я написал. В чем проблема не понимаю… Почему-то удалилось мое сообщение

Нужно: жмем кнопку 1 (однократно) - выводится а1, (многократно) - выводится а2. Жмем кнопку 2 (однократно) - выводится - в1, (многократно) - выводится - в2. По факту: жмем любую кнопку (однократно) - выводится
а1
в1
(Многократно) - выводится
а2
в2
То что написано 2 нажатие в комментариях это рассчитано на то что на одной кнопке будет 2 нагрузки т. е. Сейчас просто нужно отладить под одинократное и многократное нажатие. Но чтобы количество нажатий фиксировалось в переменной i_(n)