Как запрограммировать кнопку на цвет для полоски неопикселей?
Я пытаюсь сделать так, чтобы определенный пиксель в полосе неопикселей становился зеленым, красным или синим в зависимости от того, какая кнопка была нажата, и оставался включенным до тех пор, пока не будет снова нажат (как переключатель), но в настоящее время, когда я нажимаю один из кнопки он мигает правильным цветом, когда кнопка нажата, но не действует как тумблер, а затем загорается белым светом.
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Требуется для Adafruit Trinke 16 МГц
#endif
#define BUTTON_PIN1 2
#define BUTTON_PIN2 10
#define BUTTON_PIN3 11
#define PIXEL_PIN 6 // Цифровой контакт 6, подключенный к NeoPixels.
#define PIXEL_COUNT 13 // Количество NeoPixels
// Объявляем наш объект полосы NeoPixel:
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
boolean oldState1 = HIGH;
boolean newState1 = HIGH;
boolean toggle1 = LOW;
boolean oldState2 = HIGH;
boolean newState2 = HIGH;
boolean toggle2 = LOW;
boolean oldState3 = HIGH;
boolean newState3 = HIGH;
boolean toggle3 = LOW;
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN1, INPUT_PULLUP);
pinMode(BUTTON_PIN2, INPUT_PULLUP);
pinMode(BUTTON_PIN3, INPUT_PULLUP);
strip.begin(); // Инициализировать объект полосы NeoPixel (ОБЯЗАТЕЛЬНО)
strip.show(); // Инициализируем все пиксели выключенными
}
void loop() {
updateButtonState1();
updateButtonState2();
updateButtonState3();
}
void updateButtonState1() {
// Получить текущее состояние кнопки.
newState1 = digitalRead(BUTTON_PIN1);
if ((newState1 == LOW) && (oldState1 == HIGH)) {
delay(50);
newState1 = digitalRead(BUTTON_PIN1);
if (newState1 == LOW) {
toggle1 = !toggle1;
}
}
oldState1 = newState1;
if (toggle1 == HIGH) {
strip.setPixelColor(2, 245, 15, 15); //электрическая/пожарная опасность (красный)
} else {
strip.setPixelColor(2, 0, 0, 0);
}
strip.show(); // Обновляем полосу новым содержимым
}
void updateButtonState2() {
// Получить текущее состояние кнопки.
newState2 = digitalRead(BUTTON_PIN2);
if ((newState2 == LOW) && (oldState2 == HIGH)) {
delay(50);
newState2 = digitalRead(BUTTON_PIN2);
if (newState2 == LOW) {
toggle2 = !toggle2;
}
}
oldState2 = newState2;
if (toggle2 == HIGH) {
strip.setPixelColor(2, 13, 50, 190); //Утечка (синий)
} else {
strip.setPixelColor(2, 0, 0, 0);
}
strip.show(); // Обновляем полосу новым содержимым
}
void updateButtonState3() {
// Получить текущее состояние кнопки.
newState3 = digitalRead(BUTTON_PIN3);
if ((newState3 == LOW) && (oldState3 == HIGH)) {
delay(50);
newState3 = digitalRead(BUTTON_PIN3);
if (newState3 == LOW) {
toggle3 = !toggle3;
}
}
oldState3 = newState3;
if (toggle3 == HIGH) {
strip.setPixelColor(2, 58, 233, 65); //бункеры/переработка (зеленый)
} else {
strip.setPixelColor(2, 0, 0, 0);
}
strip.show(); // Обновляем полосу новым содержимым
}
1 ответ
На самом деле вам не обязательно использовать для этого массив, хотя я согласен, что это самое чистое решение.
Вот упрощенная версия вашего кода. Имейте в виду, что вам все равно придется обрабатывать кнопки самостоятельно (путем установки для кнопки "true" при нажатии кнопки).
Кроме того, при добавлении дополнительных цветов в массив вам придется вручную настроить значение "totalColors".
void setup() {
//Объявления цветов/пикселей на основе https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-use
uint32_t magenta = strip.Color(255, 0, 255);
uint32_t greenishwhite = strip.Color(0, 64, 0, 64);
//https://www.arduino.cc/reference/en/language/variables/data-types/array/
uint32_t colors[] = {magenta, greenishwhite};
unsigned char totalColors = 2;
unsigned char currentColor = 0;
}
void loop() {
if (buttonpressed) {
// Изменяем индекс «currentColor» каждый раз, когда нажимается кнопка, но заставляем его начинать с 0, когда он достигает конца.
currentColor++;
if (currentColor >= totalColors) {
currentColor = 0;
}
//Из массива цветов выбираем тот, у которого индекс "currentColor" и показываем.
ledstrip.fill( colors[currentColor] , 0, strip.numPixels() - 1);
ledstrip.show();
buttonpressed = false; // Сбросьте флаг, чтобы это не выполнялось до тех пор, пока не будет нажата кнопка в следующий раз.
}
}
Вы должны иметь возможность заменить первые 3 строки (настройка массива) на одну:
uint32_t colors[] = {strip.Color(255, 0, 255, strip.Color(0, 64, 0, 64)};
Но я разделил его, чтобы лучше показать идею массива.
В качестве альтернативы вы можете сделать следующее:
switch(currentColor){
case 0:
//Красный цвет
break;
case 1:
//Цвет ЗЕЛЕНЫЙ
break;
case 2:
//Цвет ЧЕРНЫЙ
break;
}
Большое спасибо! Где в коде я могу настроить buttonpressed как true? Я подумал, что потенциально массив был бы лучшим способом сделать это, так как после этого я хотел бы настроить его так, чтобы сначала можно было ввести, какой неопиксель включить с помощью одного набора кнопок, а затем какой цвет (который является частью этого кода) пытаюсь обратиться), @Georgia Cottington
Не имеет значения, где вы установили для «buttonPressed» значение true. Хотя желательно перед кодом, где он это проверяет. Вы даже можете заменить «buttonPressed» на «digitalRead (buttonPin)» и поставить задержку после изменения цветов пикселей (чтобы избежать отскока контакта, чтобы вызвать его несколько раз для одного нажатия)., @Paul
- Использование switch case с 5-позиционным переключателем и последовательным выходом
- Непрерывно запускайте функцию световой последовательности в операторе if
- Перезапустите последовательность NeoPixel с помощью кнопки в любое время.
- Включить светодиоды из массива
- Strip.clear() не очищает/отключает полосу NeoPixel после сброса ESP8266.
- Проблемы с кнопкой NeoMatrix
- Как переключить светодиод при нажатии кнопки?
- Определение того, была ли нажата и отпущена кнопка
Почему вы хотите/нужно использовать массив?, @Paul
Показанный код работает неправильно? Если это так, включите в свой вопрос описание того, как он ведет себя на самом деле и чего вы от него ожидаете., @chrisl