Как запрограммировать кнопку на цвет для полоски неопикселей?

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

#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(); // Обновляем полосу новым содержимым
}

, 👍0

Обсуждение

Почему вы хотите/нужно использовать массив?, @Paul

Показанный код работает неправильно? Если это так, включите в свой вопрос описание того, как он ведет себя на самом деле и чего вы от него ожидаете., @chrisl


1 ответ


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