Кнопка переключения переключает между операторами обращения с разблокированием кнопки

Общий обзор моего кода заключается в том, что я хочу, чтобы была нажата кнопка переключения, и каждое нажатие кнопки перемещало код к следующему оператору case. В каждом операторе case будут разные функции светодиодов. Мне нужна помощь в нескольких вещах

  1. Мне нужна помощь с непрерывным миганием 4 светодиодов с паузой 100 мс в случае 1. Поскольку он не входит в основной цикл, у меня возникают проблемы с включением и выключением 4 светодиодов. Обычно у меня может быть просто простой код, который включает его, затем сравнивает предыдущий с последним и, если отличается, выключает его, и это продолжается.
  2. Мне нужен код, чтобы вернуться к регистру 0 после удержания кнопки в течение 2 секунд.
  3. Я не могу заставить свой код разблокировки кнопки работать от случая 0 до случая 1. Если я добавлю код отмены в случае 0, как у меня есть в остальных случаях, он не будет выполняться в остальных случаях. Ниже приведен код:

//Светодиодные переменные для выхода сигнала левого поворота
int LED_1 = 2; 
int LED_2 = 3;
int LED_3 = 4;
int LED_4 = 5; 

//Светодиодные переменные для сигнала правого поворота OUT
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//выход сигнала
int BS_OUT = A5;

//обратный сигнал OUT
int RS_OUT = 10;

//кнопка переключения между различными режимами
int toggle_IN = A4;

//переменная оператора switch case для переключаемых режимов
int toggleState = 0;

//переменные, чтобы увидеть, была ли нажата кнопка переключения или нет
boolean oldSwitchStateToggle = LOW;
boolean newSwitchStateToggle = LOW;

//true или false, чтобы сохранить, была ли нажата кнопка для переключения операторов регистра
bool enabledToggle;

//время отмены, чтобы позаботиться о том, чтобы кнопка отскакивала
const int debounce = 100; // мс

//время удержания текущего времени миллис ()
unsigned long t = 0;



void setup() 
{
  Serial.begin(9600);
  //кнопка переключения
  pinMode(toggle_IN, INPUT);

  //
  pinMode(LED_4, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);


}

void loop() 
{
   //проверка, была ли нажата кнопка переключения
   newSwitchStateToggle = digitalRead(toggle_IN);
   if(newSwitchStateToggle != oldSwitchStateToggle)
  {
    if(newSwitchStateToggle == HIGH)
    {
      //включение переключателя для операторов if
      enabledToggle = true;
      // переключатель корпуса для потока через 4 различных варианта вывода светодиодов
      toggleButtonState();
      
    }
    else
    enabledToggle = false;
    oldSwitchStateToggle = newSwitchStateToggle;
  }
}

void toggleButtonState()
{
  unsigned long nowToggle = millis(); 
  switch (toggleState)
  {

    case 0:
    Serial.println("0000");
          if(enabledToggle)
          {
            digitalWrite(LED_1, HIGH);
            t = nowToggle;
            toggleState = 1;
          }

          break; 
          
    case 1:
    Serial.println("1111"); 
          if(enabledToggle)
          {
            digitalWrite(LED_1, LOW);
            digitalWrite(LED_2, HIGH);
            // позволяет перейти в следующее состояние после 100 мс для отмены нажатия кнопки
            if(nowToggle - t > debounce)
            {
              toggleState = 2;
              t = nowToggle;
            }
          }
       
          break;

     case 2:
     Serial.println("2222"); 
          if(enabledToggle)
          {
            digitalWrite(LED_2, LOW);
            digitalWrite(LED_3, HIGH);
            if(nowToggle - t > debounce)
            {
              toggleState = 3;
              t = nowToggle;
            }
          }
          
          break;
          
     case 3:
     Serial.println("3333"); 
         if(enabledToggle)
          {
            digitalWrite(LED_3, LOW);
            digitalWrite(LED_4, HIGH);
            if(nowToggle - t > debounce)
            {
              toggleState = 4;
              t = nowToggle;
            }
          }
          break;
          
     case 4:
     Serial.println("44444"); 
          if(enabledToggle)
          {
            turnOffLeds();
            if(nowToggle - t > debounce)
            {
              toggleState = 0;
              t = nowToggle;
            }
          }
          break;
         
  }
}

void turnOffLeds()
{
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
}

обновленный код: пытаюсь добавить в debounce, но это не сработает


int LED_1 = 2; 
int LED_2 = 3;
int LED_3 = 4;
int LED_4 = 5; 


int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;


//кнопка переключения между различными режимами
int toggle_IN = A4;

//переменная оператора switch case для переключаемых режимов
int toggleState = 0;

//переменные, чтобы увидеть, была ли нажата кнопка переключения или нет
boolean oldSwitchStateToggle = LOW;
boolean newSwitchStateToggle = LOW;

//true или false, чтобы сохранить, была ли нажата кнопка для переключения операторов регистра
bool enabledToggle;

//время отмены, чтобы позаботиться о том, чтобы кнопка отскакивала
const int debounce = 100; // мс

//время удержания текущего времени миллис ()
unsigned long t = 0;

int ledBlinkState = LOW;

unsigned long prevBlinkMillis = 0;

const int blinkInterval = 150;

bool state1 = false;
bool state2 = false;
bool state3 = false;
bool state4 = false;
bool state0 = false;

void setup() 
{
  Serial.begin(9600);
  //кнопка переключения
  pinMode(toggle_IN, INPUT);

  //
  pinMode(LED_4, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);


}

void loop() 
{
  unsigned long nowToggle = millis(); 
  Serial.print("NOWWWWWW");
  Serial.println(nowToggle);
   //проверка, была ли нажата кнопка переключения
   newSwitchStateToggle = digitalRead(toggle_IN);
   if(newSwitchStateToggle != oldSwitchStateToggle)
   {
    t = nowToggle;
    Serial.print("TIMEEEEE");
    Serial.println(t);
    if(newSwitchStateToggle == HIGH)
    {
      if(nowToggle - t > debounce)
      {
        //включение переключателя для операторов if
        enabledToggle = true;
        // переключатель корпуса для потока через 4 различных варианта вывода светодиодов
        toggleButtonState();
      }
      
    }
    else
    enabledToggle = false;
    oldSwitchStateToggle = newSwitchStateToggle;
  }

  unsigned long currentBlinkMillis = millis();
  
  if(state0 == true)
  {
    digitalWrite(LED_5, HIGH);
    digitalWrite(LED_6, HIGH);
    digitalWrite(LED_7, HIGH);
    digitalWrite(LED_8, HIGH);
    
    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_1, ledBlinkState);
      digitalWrite(LED_2, ledBlinkState);
      digitalWrite(LED_3, ledBlinkState);
      digitalWrite(LED_4, ledBlinkState);
    }
  }
  
  if(state1 == true)
  {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, HIGH);
    
    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_5, ledBlinkState);
      digitalWrite(LED_6, ledBlinkState);
      digitalWrite(LED_7, ledBlinkState);
      digitalWrite(LED_8, ledBlinkState);
    }
  }

  if(state2 == true)
  {
    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_1, ledBlinkState);
      digitalWrite(LED_2, ledBlinkState);
      digitalWrite(LED_3, ledBlinkState);
      digitalWrite(LED_4, ledBlinkState);
      digitalWrite(LED_5, ledBlinkState);
      digitalWrite(LED_6, ledBlinkState);
      digitalWrite(LED_7, ledBlinkState);
      digitalWrite(LED_8, ledBlinkState);
    }
  }
  
  if(state3 == true)
  {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, HIGH);
    digitalWrite(LED_5, HIGH);
    digitalWrite(LED_6, HIGH);
    digitalWrite(LED_7, HIGH);
    digitalWrite(LED_8, HIGH);
  }
  
  if(state4 == true)
  {
    turnOffLeds();
  }
  
}

void toggleButtonState()
{
  switch (toggleState)
  {

    case 0:
    Serial.println("0000");
          if(enabledToggle)
          {
            turnOffLeds();
            state4 = false;
            state0 = true;
            toggleState = 1;
          }

          break; 
          
    case 1:
    Serial.println("1111"); 
          if(enabledToggle)
          {
            turnOffLeds();
            state0 = false;
            state1 = true;
            toggleState = 2;
          }
       
          break;

     case 2:
     Serial.println("2222"); 
          if(enabledToggle)
          {
            turnOffLeds();
            state1 = false;
            state2 = true;
            toggleState = 3;
          }
          
          break;
          
     case 3:
     Serial.println("3333"); 
         if(enabledToggle)
          {
            turnOffLeds();
            state2 = false;
            state3 = true;
            toggleState = 4;
          }
          break;
          
     case 4:
     Serial.println("44444"); 
          if(enabledToggle)
          {
            turnOffLeds();
            state3 = false;
            state4 = true;
            toggleState = 0;
          }
          break;
         
  }
}

void turnOffLeds()
{
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

, 👍2

Обсуждение

1. функция toggleButtonState() не должна содержать никакого светодиодного кода... он должен только установить флаг ... код мигания должен находиться внутри loop() и активироваться флагом, @jsotola

2. выполните обнаружение кнопки в начале loop() ... код кнопки должен только устанавливать флаг, не более того, @jsotola

3. ... прочитайте 2., @jsotola

1. Так, например, я был бы в случае 1, и он установил бы для переменной значение true. Затем в цикле введите оператор if в where, если эта переменная имеет значение true, то она будет проходить через этот мигающий код светодиода?, @Myles

ДА... цикл () повторяется много раз в секунду... используйте millis () для мигания... см. Пример скетча "blinkWithoutDelay", @jsotola

@jsotola Я понял, что помечено, и мой код отлично работает для мигающих светодиодов. Сейчас у меня возникли проблемы с тем, чтобы заставить код debounce работать. У меня есть это в моем обновленном коде, но это не работает. Я пытаюсь включить его вокруг моего нажатия кнопки в цикле (). Когда я смотрю на это в моем последовательном мониторе, "t" удерживает nowToggle каждый экземпляр и не удерживает его в одном значении., @Myles


2 ответа


1

Я бы порекомендовал вам начать с существующей библиотеки, чтобы выполнить обнаружение "отключения кнопки" и "длительного нажатия кнопки".

Библиотека EasyButton на github и через Arduino IDE library manager обладает потенциалом.

Вот тестовый скетч, который показывает часть вашего требования "обнаружение кнопок".

Если бы вы добавили переменную для представления "состояния", этот код можно было бы адаптировать для управления оператором case на основе состояния.

// Sketch использует 3286 байт (10%) дискового пространства программы.
// Глобальные переменные используют 357 байт (17%) динамической памяти.
#include <EasyButton.h>

// EasyButton(вывод uint8_t, 
// uint32_t debounce_time = 35, 
// bool pullup_enable = истина, 
// bool active_low = true)
EasyButton button(2);

void onPressed(){
  // Ваш код здесь для УВЕЛИЧЕНИЯ "счетчика состояний".
  Serial.println("Button pressed");
}

void onPressedForDuration(){
  // Ваш код здесь, чтобы УСТАНОВИТЬ "счетчик состояний" на 0.
  Serial.println("Button pressed for duration");
}

void setup(){

  // Тестовый вывод на последовательный монитор.
  Serial.begin(9600);

  // Инициализируйте кнопку.
  button.begin();

  // Добавьте функцию обратного вызова, которая будет вызываться при нажатии кнопки.
  button.onPressed(onPressed);

  // Добавьте функцию обратного вызова, которая будет вызываться при нажатии кнопки
  // по крайней мере, на данный момент.
  button.onPressedFor(2000, onPressedForDuration);

}

void loop(){

  // Постоянно считывайте состояние кнопки.
  button.read();

}

,

Я бы сделал это таким образом, но я собираюсь перенести это в компилятор eclipse. Я держусь подальше от библиотек, созданных arduino. Я пытаюсь найти способ взглянуть на то, что происходит на заднем плане easybutton.h. Вы не знаете, где я мог бы это найти?, @Myles

@Myles - Вы можете посмотреть исходный код EasyButton, чтобы увидеть, как это работает: https://github.com/evert-arias/EasyButton/tree/main/src, @VE7JRO


0

Я ответил, как переключить режим всего одной кнопкой, много-много лет назад. Используйте его, как хотите ... Это всего лишь образец скелета. Вот код, который я использовал:

/*
 Использование одного переключателя для выбора между 3 режимами
*/
// Схема: http://www.pwillard.com/files/mode4.jpg
//===============================================================
// Глобальные переменные и константы
//===============================================================
 
const int ledPinOne = 2; // АНОД LED1
const int ledPinTwo = 4; // АНОД LED2
const int ledPinThree = 7; // АНОД LED3
const int modePin = 13; // Активный МАКСИМУМ, удерживается на низком уровне 4,7К
 
int mode = 0; // Состояние селектора (начальное состояние = ВСЕ ВЫКЛЮЧЕНО)
int val = 0; // Вывод 13 ВЫСОКИЙ / НИЗКИЙ статус
int butState = 0; // Состояние последней кнопки
int modeState = 0; // Состояние последнего режима
boolean debug = 1; // 1 = включена последовательная печать / 0 = отключена
 
//===============================================================
// НАСТРОЙКА
//===============================================================
void setup () {
 pinMode(ledPinOne, OUTPUT);
 pinMode(ledPinTwo, OUTPUT);
 pinMode(ledPinThree, OUTPUT);
 pinMode(modePin, INPUT);
 if (debug){
 Serial.begin(9600);
 Serial.print("Initial Mode: ");
 Serial.println(mode);
 Serial.print("Setup Complete\n");
 }
}
 
//===============================================================
// Основной цикл
//===============================================================
void loop() {
 
 val = digitalRead(modePin);
 
 // Если мы видим изменение состояния кнопки, увеличьте значение режима
 if (val != butState && val == HIGH){
 mode++;
 }
 
 butState = val; // Отслеживать последнее состояние кнопки
 
 // Нет необходимости продолжать устанавливать контакты * каждый * цикл
 if (modeState != mode){
 
 // Если ни одна клавиша еще не была нажата, не выполняйте
 // приведенный ниже код переключателя
 // если (режим != 0) {
 
 switch ( mode ) {
 //случай 1 фактически обрабатывается ниже по умолчанию
 
case 2:
 digitalWrite(ledPinOne, LOW);
 digitalWrite(ledPinTwo, HIGH);
 showState();
 break;
 case 3:
 digitalWrite(ledPinTwo, LOW);
 digitalWrite(ledPinThree, HIGH);
 showState();
 break;
 default:
 mode = 1;
 // возврат к 1 по умолчанию, кажется избыточным, но
 // он также обрабатывает проблему "режим> 3"
 digitalWrite(ledPinThree, LOW);
 digitalWrite(ledPinOne, HIGH);
 showState();
 break;
 } // конечный выключатель
// } // завершение проверки "if mode = 0"
 } // конец ModeState проверьте
 modeState = mode; // Следите за задержкой последнего значения режима mode
 delay(10); // немного замедлите цикл для отмены
}
 
//===============================================================
// Подпрограмма
//===============================================================
void showState() {
 if (debug){
 Serial.print("Mode: ");
 Serial.println(mode);
 }
}
,