Управление несколькими светодиодами с помощью нескольких кнопок

Проблема 1: LED1 должен гореть только тогда, когда кнопка 1 удерживается нажатой. Прямо сейчас для включения и выключения требуется несколько нажатий, и он остается включенным. Проблема 1: светодиоды 2,3,4 не выключаются кнопками 2,3,4. Все они выключаются кнопкой 1, чего я и хочу, но мне также нужно, чтобы они выключались нажатием соответствующих кнопок.

Мне нужны кнопки 2, 3, 4, чтобы загорались светодиоды 2, 3, 4 и горели до тех пор, пока я снова не нажму соответствующие кнопки ИЛИ кнопку 1, которая выключает все огни, а светодиод кнопки 1 должен гореть только тогда, когда кнопка 1 нажата. удерживается.

Я уже на полпути, у меня всего несколько мелких проблем. Во-первых, светодиод 1 остается включенным, а не только тогда, когда я удерживаю кнопку 1 нажатой. Другая проблема заключается в том, что для включения или выключения светодиодов требуется много нажатий. Я исправил это на 2,3,4, удалив следующий код для каждого контакта:

if (digitalRead(buttonPin2) == HIGH) { // проверяем, была ли нажата кнопкаPin2 (обязательно использовать резистор?)
  { digitalWrite(ledPin2, LOW);       // включить ledPin2
    ledPin2_status = 1;                // 1 = включено, устанавливаем ledPin2_status в 1
  }

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

Полный код:

// устанавливаем контакты
const int buttonPin1 = 2;                 // кнопка Pin1
const int buttonPin2 = 4;                 // кнопка Pin2
const int buttonPin3 = 6;                 // кнопка Pin3
const int buttonPin4 = 8;                 // кнопка Pin4
const int ledPin1 = 3;                    // Светодиод Pin1
const int ledPin2 = 5;                    // светодиод Pin2
const int ledPin3 = 7;                    // светодиод Pin3
const int ledPin4 = 9;                    // светодиод Pin4

// устанавливаем переменные
int ledPin1_status = 0;
int ledPin2_status = 0;
int ledPin3_status = 0;
int ledPin4_status = 0;

void setup() {  // инициализируем контакты
  pinMode(buttonPin1, INPUT); // устанавливаем PINn как INPUT
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(ledPin1, OUTPUT);   // устанавливаем LEDn как ВЫХОД
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
}

// следующие переменные являются беззнаковыми длинными, потому что время, измеренное в
// миллисекунды, быстро станет большим числом, чем может быть сохранено в int.
unsigned long lastDebounceTime = 0;  // последний раз, когда выходной пин был переключен
unsigned long debounceDelay = 50;    // время устранения дребезга; увеличить, если выход мерцает

void loop() {
  if (digitalRead(buttonPin1) == HIGH) { // проверяем, была ли нажата кнопкаPin1 (обязательно использовать резистор?)
    if (ledPin1_status == 0) {           // проверяем, не был ли уже нажат ledPin1
      digitalWrite(ledPin1, HIGH);       // включаем ledPin1
      ledPin1_status = 1;                // 1 = включено, устанавливаем ledPin1_status в 1
    }
    else {
      digitalWrite(ledPin1, LOW);        // выключаем ledPin1
      ledPin1_status = 0;                // 0 = выключено, установите Pin1_status на 0
      digitalWrite(ledPin2, LOW);        // выключаем ledPin2
      ledPin2_status = 0;                // 0 = выключено, установите Pin2_status на 0
      digitalWrite(ledPin3, LOW);        // выключаем ledPin3
      ledPin3_status = 0;                // 0 = выключено, установите Pin2_status на 0
      digitalWrite(ledPin4, LOW);        // выключаем ledPin4
      ledPin3_status = 0;                // 0 = выключено, установите Pin2_status на 0
    }
  }

  if (digitalRead(buttonPin2) == HIGH) { // проверяем, была ли нажата кнопкаPin2 (обязательно использовать резистор?)
    { digitalWrite(ledPin2, HIGH);       // включить ledPin2
      ledPin2_status = 1;                // 1 = включено, устанавливаем ledPin2_status в 1
    }
  }

  if (digitalRead(buttonPin2) == HIGH) { // проверяем, была ли нажата кнопкаPin2 (обязательно использовать резистор?)
    { digitalWrite(ledPin2, LOW);       // включить ledPin2
      ledPin2_status = 1;                // 1 = включено, устанавливаем ledPin2_status в 1
    }
  }

  if (digitalRead(buttonPin3) == HIGH) { // проверяем, была ли нажата кнопкаPin3 (обязательно использовать резистор?)
    { digitalWrite(ledPin3, HIGH);       // включить ledPin3
      ledPin3_status = 1;                // 1 = включено, устанавливаем ledPin3_status в 1
    }
  }

  if (digitalRead(buttonPin3) == HIGH) { // проверяем, была ли нажата кнопкаPin2 (обязательно использовать резистор?)
    { digitalWrite(ledPin3, LOW);       // включить ledPin3
      ledPin2_status = 1;                // 1 = включено, устанавливаем ledPin2_status в 1
    }
  }

  if (digitalRead(buttonPin4) == HIGH) { // проверяем, была ли нажата кнопкаPin2 (обязательно использовать резистор?)
    { digitalWrite(ledPin4, HIGH);       // включить ledPin4
      ledPin2_status = 1;                // 1 = включено, устанавливаем ledPin2_status в 1
    }
  }

  if (digitalRead(buttonPin4) == HIGH) { // проверяем, была ли нажата кнопкаPin2 (обязательно использовать резистор?)
    { digitalWrite(ledPin4, LOW);       // включить ledPin4
      ledPin2_status = 1;                // 1 = включено, устанавливаем ledPin2_status в 1
    }
  }

, 👍0

Обсуждение

такие имена, как buttonPin1, ledPin1 и ledPin1_status загромождают листинг кода .... просто используйте такие имена, как button1, led1 и led1_status, @jsotola


1 ответ


Лучший ответ:

0

Во-первых, вам нужно избавиться от дребезга кнопок. Тот факт, что вы объявил (неиспользуемую) переменную, debounceDelay предполагает, что у вас есть, хотя про дебаунс, но вы его не реализовали.

Следующее, вам нужно найти события нажатия кнопки и отпускания. Это когда контакт кнопки меняет состояние с LOW на HIGH или наоборот. наоборот Недостаточно проверить, является ли контакт HIGH или LOW, вы должны проверять изменения состояния. Обычно это называется край обнаружение.

Приложив достаточно усилий, вы, вероятно, могли бы сделать это самостоятельно. Однако, чтобы сделать вашу жизнь проще, вы можете использовать библиотеку устранения дребезга, которая обнаружение, такое как довольно популярный Bounce2. Эта библиотека предоставляет, для каждой кнопки, которую он устраняет, метод rose(), который сообщает вам, когда входной сигнал вырос (т.е. перешел от LOW к HIGH) и Метод fell(), который сообщает вам, когда он упал (перешел в HIGH → НИЗКИЙ). Используя эти методы, ваша проблема может быть закодирована в справедливой форме. естественный способ. Например (не проверено):

#include <Bounce2.h>

const int     BUTTON_COUNT = 4;
const int16_t DEBOUNCE_DELAY = 50;
const uint8_t buttonPins[BUTTON_COUNT] = {2, 4, 6, 8};
const uint8_t ledPins[BUTTON_COUNT] = {3, 5, 7, 9};

Bounce buttons[BUTTON_COUNT];
uint8_t ledStates[BUTTON_COUNT];

void setup() {
    for (int i = 0; i < BUTTON_COUNT; i++) {
        buttons[i].attach(buttonPins[i], INPUT);
        buttons[i].interval(DEBOUNCE_DELAY);
        pinMode(ledPins[i], OUTPUT);
        ledStates[i] = LOW;
        digitalWrite(ledPins[i], ledStates[i]);
    }
}

void loop() {

    // Обновить дебаунсеры.
    for (int i = 0; i < BUTTON_COUNT; i++)
        buttons[i].update();

    // При нажатии первой кнопки:
    if (buttons[0].rose()) {

        // Загорается первый светодиод.
        digitalWrite(ledPins[0], HIGH);

        // и отключаем все остальные.
        for (int i = 1; i < BUTTON_COUNT; i++) {
            ledStates[i] = LOW;
            digitalWrite(ledPins[i], ledStates[i]);
        }
    }

    // Когда первая кнопка отпущена:
    if (buttons[0].fell()) {

        // выключаем первый светодиод.
        digitalWrite(ledPins[0], LOW);
    }

    // При нажатии любой другой кнопки:
    for (int i = 1; i < BUTTON_COUNT; i++) if (buttons[i].rose()) {

        // Переключить его состояние.
        ledStates[i] = !ledStates[i];
        digitalWrite(ledPins[i], ledStates[i]);
    }
}

Изменить: чтобы первая кнопка выключала только светодиоды 1 и 2, линии

// и отключаем все остальные.
for (int i = 1; i < BUTTON_COUNT; i++) {
    ledStates[i] = LOW;
    digitalWrite(ledPins[i], ledStates[i]);
}

следует заменить на:

// и выключаем светодиоды 1 и 2.
for (int i = 1; i <= 2; i++) {
    ledStates[i] = LOW;
    digitalWrite(ledPins[i], ledStates[i]);
}
,

Вау, Эдгар, какой отличный набросок, такой аккуратный, надеюсь, я смогу многому научиться из него, спасибо. Какие существуют методы, чтобы Windows распознала его как контроллер? Это код или окна, с которыми мне приходится играть, или и то, и другое., @TRUEBRIT

Как мне выбрать только определенные кнопки для отключения с помощью кнопки 1? Скажем, я хотел, чтобы кнопка 4 была независимой., @TRUEBRIT

@TRUEBRIT: 1. Извините, я ничего не знаю о программировании для Windows, которое в любом случае здесь не в тему. 2. В разделе сразу после комментария «и выключите все остальные» вместо циклического перебора кнопок с 1 по 3 (они пронумерованы с нуля) вы отключаете только кнопку 1 и 2., @Edgar Bonet

Я не вижу, как это сделать?, @TRUEBRIT

@TRUEBRIT: см. ответ с поправками., @Edgar Bonet

Еще раз спасибо Эдгар. Если бы я добавил другие входы, такие как поворотный энкодер, повлияла бы на это библиотека подавления дребезга?, @TRUEBRIT

@TRUEBRIT: это не связано с исходным вопросом., @Edgar Bonet