Nano сходит с ума

Делаю контроллер управления нагрузками.

#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 = 0;              // переменная обработки временного интервала
long lastSwitchTime = 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 = millis();
  }
  if (reading_2 && !lastReading_2){
      // Если кнопка только что была нажата (текущее состояние кнопки "reading" равно true, а предыдущее состояние "lastReading" равно false),
      // то сохраняем текущее время в переменную "onTime"
    onTime = millis();
  }
  // Проверка отпускания кнопки
  if (!reading_1 && lastReading_1){
      // Если кнопка только что была отпущена (текущее состояние кнопки "reading" равно false, а предыдущее состояние "lastReading" равно true),
      // то проверяем, прошла ли задержка для подавления дребезга
    if (((millis() - onTime) > bounceTime)){
      // Если прошла задержка для подавления дребезга, то проверяем, прошло ли достаточно времени с момента последнего переключения для определения двойного нажатия
      if ((millis() - lastSwitchTime) >= doubleTime){
      // Если прошло достаточно времени с момента последнего переключения, то устанавливаем флаг "buttonSingle" в true,
      // сбрасываем счетчик "i" в 1 и обновляем время последнего переключения "lastSwitchTime"
        lastSwitchTime = millis();
        buttonSingle_1 = true;
        i_1=1;
      } else {
      // Если не прошло достаточно времени, то увеличиваем счетчик "i" и обновляем время последнего переключения "lastSwitchTime",
      // а также устанавливаем флаг "buttonSingle" в false и флаг "buttonMulti" в true
        i_1++;
        lastSwitchTime = millis();
        buttonSingle_1 = false;
        buttonMulti_1 = true;
      }
    }
  }
  if (!reading_2 && lastReading_2){
      // Если кнопка только что была отпущена (текущее состояние кнопки "reading" равно false, а предыдущее состояние "lastReading" равно true),
      // то проверяем, прошла ли задержка для подавления дребезга
    if (((millis() - onTime) > bounceTime)){
      // Если прошла задержка для подавления дребезга, то проверяем, прошло ли достаточно времени с момента последнего переключения для определения двойного нажатия
      if ((millis() - lastSwitchTime) >= doubleTime){
      // Если прошло достаточно времени с момента последнего переключения, то устанавливаем флаг "buttonSingle" в true,
      // сбрасываем счетчик "i" в 1 и обновляем время последнего переключения "lastSwitchTime"
        lastSwitchTime = millis();
        buttonSingle_2 = true;
        i_2=1;
      } else {
      // Если не прошло достаточно времени, то увеличиваем счетчик "i" и обновляем время последнего переключения "lastSwitchTime",
      // а также устанавливаем флаг "buttonSingle" в false и флаг "buttonMulti" в true
        i_2++;
        lastSwitchTime = millis();
        buttonSingle_2 = false;
        buttonMulti_2 = true;
      }
    }
  }
  // Сохранение текущего состояния кнопки
  lastReading_1 = reading_1;
  // Проверка состояния "краткое нажатие" и времени с момента последнего переключения
  if (buttonSingle_1 && (millis() - lastSwitchTime) > doubleTime){
  // Если флаг "buttonSingle" установлен в true и прошло достаточно времени с момента последнего переключения,
  // вызываем функцию для обработки состояния "краткое нажатие"
    isButtonSingle_1();
  }
  // Проверка состояния "двойное нажатие" и времени с момента последнего переключения
  if (buttonMulti_1 && (millis() - lastSwitchTime) > doubleTime){
  // Если флаг "buttonMulti" установлен в true и прошло достаточно времени с момента последнего переключения,
  // вызываем функцию для обработки состояния "двойное нажатие" и передаем ей значение счетчика "i"
    isButtonMulti_1(i_1);
  }
    lastReading_2 = reading_2;
  // Проверка состояния "краткое нажатие" и времени с момента последнего переключения
  if (buttonSingle_2 && (millis() - lastSwitchTime) > doubleTime){
  // Если флаг "buttonSingle" установлен в true и прошло достаточно времени с момента последнего переключения,
  // вызываем функцию для обработки состояния "краткое нажатие"
    isButtonSingle_2();
  }
  // Проверка состояния "двойное нажатие" и времени с момента последнего переключения
  if (buttonMulti_2 && (millis() - lastSwitchTime) > 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("a" + count);
    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("b" + count);
    read_4 = !read_4;
    digitalWrite(5, read_4);
}

Схема подключения:
Нагрузка 1 + (d2) - (GND)
Нагрузка 2 + (d3) - (GND)
Нагрузка 3 + (d4) - (GND)
Нагрузка 4 + (d5) - (GND)

Кнопка 1 a4 к GND (через резистор к 5В)
Кнопка 2 a5 к GND (через резистор к 5В)

Переключение происходит хаотично
и на мониторе порта вообще чушь происходит

4
2
1
1



a1
b1
b1
a1

a1


a1

a1

Я так понимаю проблема аппаратного плана, но не знаю как решить.

nano с озона?

Да, с Озона

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

1 лайк

Я ее брал еще в начале года.

я тоже, думаю даже в конце того года, тут есть тема где я пытался досконально разобраться с этими платами, сдувал чипы и ставил другие, там проблема не в самой атмеге, а в мосте USB-UART.
если нет соотв. классификации - выкинь!

Ну, может Nano и неправильная, но от Ваших строк №№ 136 и 156 я бы тоже с ума сошёл. Здесь не JavaScript, здесь так не работает.

И ещё, Вы забыли написать очень важную информацию - что за нагрузка? Какие токи жрёт?

а фото платы можешь выложить?

На данный момент светодиод. Не пойму что не так со строчками?! А еще больше мне интересно зачем вам информация про нагрузку?

Как минимум, переменная onTime должна быть не одна, а на каждую кнопку своя.
И lastSwitchTime аналогично.

Спасибо! Попробую. Как то я не подумал, про несколько таймеров.

Вывод через Сериал не позволяет складывать строчки оператором “+”, если только это не экзепляры String

как, интересно, вы планировали РАЗДЕЛЬНО управлять несолькими плотребителями с одного таймера?

А что Вы надеетесь получить, складывая указатель на символ с числом?

Несколькими управляющими устройствами работать с одним таймером. (я и говорю не подумал)

Ну теперь ответ более развернутый, спасибо!

Не принимай на веру все.
“так” как ты написал - почти можно.
Ниже пример:

void setup() {
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:
  static int count;

  Serial.println(String("Вот оно как, однако! ") + count);

  ++count;
  delay(1000);
}

и ссылка на то, как работает.

1 лайк

Тут я тоже помогу немного. Вместо адресата.
Нужно знать ток нагрузки. Ты - новичок, мы тебя не знаем. 99 из 100 новичков НЕ ОТЛИЧАЮТ +5 и логическую 1 на Ардуино.
Высокий уровень пина -НЕ питание и даже светодиод от него не всегда можно зажечь. В Уно-Нано - ОК, но уже на более современных контрллерах можно столкнуться с тем, что 10 мА пина не хватает. А есть контроллеры, на которых и 10 мА нельзя снимать с пина.

Поэтому не удивляйся вопросу. Если ты все понимаешь - не обидишься, а если не понимаешь - научишься.

Мне? Совершенно не нужна. Это у Вас “Нано с ума сходит”, а не у меня, вот Вам это всё и нужно.

Будем отвечать на вопросы, которые задают те, кто хочет помочь? Или выпендриваться?

конечно, вы жеж не берёте китайских ардуин чтобы потом не мучаться, это жеж нужно уметь писать китайский код для скетчей )

Спасибо за помощь! Но к сожаления не намного корректнее стало. При нажатии на любую из кнопок, контроллер почему-то думает что юзаются сразу обе, и при одинарном и при двойном клике.