Управление 4 цифровыми выходами одним переключателем
Я хочу управлять 4 цифровыми выходами (d0, d1, d2, d3) с помощью одного переключателя. Когда Arduino запускается, все они должны находиться в состоянии LOW.
Теперь, после однократного нажатия кнопки, d0 должен стать ВЫСОКИМ. Еще одно нажатие переводит d0 в LOW, а d1 в HIGH. Так что на самом деле 4 выхода должны вести себя как битовая маска. После каждого нажатия битовая маска должна увеличиваться на единицу.
d0 LOW
d1 LOW
d2 LOW
d3 LOW
нажать
d0 HIGH
d1 LOW
d2 LOW
d3 LOW
нажать
d0 LOW
d1 HIGH
d2 LOW
d3 LOW
Есть ли простой способ реализовать это без ввода каждого регистра в коде?
Я рад любым подсказкам. Удачи и спасибо.
@pfra, 👍-1
1 ответ
Как обычно в программировании, есть много решений, например:
- Вы можете использовать битовую маску, поместить 4 переменные в массив с двоичными значениями 1000, 0100, 0010 и 0001, и при нажатии переключателя вы сохраните значение на каждом выводе светодиода, сравнив значение.
- Однако более простое решение — просто использовать счетчик от 0 до 4, если значение равно 1, первый светодиод должен быть единицей, затем после переключения увеличьте значение и используйте модуль 5 (% 5), чтобы перейти вернуться к 0.
Чтобы проверить, нажата ли кнопка, используйте логическое значение, которое проверяет предыдущее значение. Также реализуйте алгоритм устранения дребезга, который можно найти на сайте Arduino.
Без устранения дребезга это могло бы выглядеть так:
#include "stdlib.h"
int buttonPin = 7;
int buttonState = LOW;
int led1Pin = 8;
int led2Pin = 9;
int led3Pin = 10;
int led4Pin = 11;
int ledMode = 0; // Все выключено, 1-4 означает, что светодиод 1-4 горит
void setup()
{
}
void loop()
{
// Добавляем дебаунс сами
if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
{
buttonState = HIGH;
ledMode = (ledMode + 1) % 5;
}
else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
{
buttonState = LOW;
}
digitalWrite(led1Pin, ledMode == 1 ? HIGH : LOW);
digitalWrite(led2Pin, ledMode == 2 ? HIGH : LOW);
digitalWrite(led3Pin, ledMode == 3 ? HIGH : LOW);
digitalWrite(led4Pin, ledMode == 4 ? HIGH : LOW);
}
Если вы поместите светодиоды на последующие контакты, вы можете использовать следующий код, который проще и работает для любого количества светодиодов:
#include "stdlib.h"
int buttonPin = 7;
int buttonState = LOW;
int nrOfLeds = 4;
int startLed = 8;
int ledMode = 0; // Все выключено, 1 означает светодиод на контакте startLed, 2 означает светодиод на контакте startLed + 1 и т. д.
void setup()
{
}
void loop()
{
// Добавляем дебаунс сами
if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
{
buttonState = HIGH;
ledMode = (ledMode + 1) % (nrOfLeds + 1);
}
else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
{
buttonState = LOW;
}
for (int led = 0; led < nrOfLeds; ledPin++)
{
digitalWrite(startLed + led, ledMode == led + 1 ? HIGH : LOW);
}
}
- Кнопка с таймером переключения и функцией сброса времени + светодиод обратной связи
- Нужен простой, маломощный, недорогой беспроводной коммутатор для передачи на Arduino
- нужно сравнить, если байт меньше 80 шестнадцатеричных
- Все ли эти битовые настройки означают одно и то же?
- Кнопка срабатывает несколько случайно
- avrdude ser_open() can't set com-state
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Какое максимальное энергопотребление Arduino Nano 3.0?
Большое спасибо за ваш подробный ответ!, @pfra
Если это поможет вам, проголосуйте за ответ, если это правильный ответ для вас, также сделайте его принятым., @Michel Keijzers