Как управлять светодиодами и полосами neopixel вместе (одновременно)?

Вот код, который я написал:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Требуется для 16 МГц Adafruit Trinket
#endif

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

int numOfRegisters = 2;
byte* registerState;

long effectId = 0;
long prevEffect = 0;
long effectRepeat = 0;
long effectSpeed = 30;

#define LED_PIN    2
#define LED_COUNT 24

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
  #endif

  strip.begin();           // ИНИЦИАЛИЗИРОВАТЬ объект NeoPixel strip (ОБЯЗАТЕЛЬНО)
  strip.show();            // Отключите все пиксели как МОЖНО СКОРЕЕ
  strip.setBrightness(50); // Установить ЯРКОСТЬ примерно на 1/5 (max = 255)

  //Инициализировать массив
  registerState = new byte[numOfRegisters];
  for (size_t i = 0; i < numOfRegisters; i++) {
    registerState[i] = 0;
  }

  // установите контакты для вывода, чтобы вы могли управлять
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  do {
    effectId = random(6);
  } while (effectId == prevEffect);
  prevEffect = effectId;

  switch (effectId) {
  case 0:
    effectRepeat = random(1, 2);
    break;
  case 1:
    effectRepeat = random(1, 2);
    break;
  case 3:
    effectRepeat = random(1, 5);
    break;
  case 4:
    effectRepeat = random(1, 2);
    break;
  case 5:
    effectRepeat = random(1, 2);
    break;
  }

  for (int i = 0; i < effectRepeat; i++) {
    effectSpeed = random(10, 90);

    switch (effectId) {
    case 0:
      effectA(effectSpeed);
      break;
    case 1:
      effectB(effectSpeed);
      break;
    case 3:
      effectC(effectSpeed);
      break;
    case 4:
      effectD(effectSpeed);
      break;
    case 6:
      effectE(effectSpeed);
      break;
    }
  }

  
  // Заливка по длине полосы различными цветами...
  colorWipe(strip.Color(255,   0,   0), 1); // Красный
  colorWipe(strip.Color(  0, 255,   0), 1); // Зеленый
  colorWipe(strip.Color(  0,   0, 255), 1); // Синий

  // Сделайте эффект театрального шатра в различных цветах...
  theaterChase(strip.Color(127, 127, 127), 1); // Белый, половинная яркость
  theaterChase(strip.Color(127,   0,   0), 1); // Красный, половинная яркость
  theaterChase(strip.Color(  0,   0, 127), 1); // Синий, половинная яркость

  rainbow(1);             // Flowing rainbow cycle along the whole strip
  theaterChaseRainbow(1); // Rainbow-enhanced theaterChase variant
}

void colorWipe(uint32_t color, int wait) {
  for (int i=0; i<strip.numPixels(); i++) { // Для каждого пикселя в полосе...
    strip.setPixelColor(i, color);          // Установить цвет пикселя (в оперативной памяти)
    strip.show();                           // Обновить полосу до соответствия
    delay(wait);                            // Пауза на мгновение
  }
}

void theaterChase(uint32_t color, int wait) {
  for (int a=0; a<10; a++) {  // Повторите 10 раз...
    for (int b=0; b<3; b++) { // 'b' отсчитывается от 0 до 2...
      strip.clear();          // Установите для всех пикселей в оперативной памяти значение 0 (выкл.)
      // "c" отсчитывает от "b" до конца полосы с шагом 3...
      for (int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Установить пиксель 'c' в значение 'color'
      }
      strip.show(); // Обновить полосу новым содержимым
      delay(wait);  // Пауза на мгновение
    }
  }
}

void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for (int i=0; i<strip.numPixels(); i++) { // Для каждого пикселя в полосе...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Обновить полосу новым содержимым
    delay(wait);  // Пауза на мгновение
  }
}

void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;      // Первый пиксель начинается с красного цвета (оттенок 0)
  for (int a=0; a<30; a++) {  // Повторите 30 раз...
    for (int b=0; b<3; b++) { // 'b' отсчитывается от 0 до 2...
      strip.clear();          // Установите для всех пикселей в оперативной памяти значение 0 (выкл.)
      // "c" отсчитывается от "b" до конца полосы с шагом 3...
      for (int c=b; c<strip.numPixels(); c += 3) {
        // оттенок пикселя "c" смещается на величину, делающую его полным
        // оборот цветового круга (диапазон 65536) по длине
        // strip(strip.Nump() шаги):
        int hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Установить пиксель 'c' в значение 'color'
      }
      strip.show();                // Обновить полосу новым содержимым
      delay(wait);                 // Пауза на мгновение
      firstPixelHue += 65536 / 90; // Один цикл цветового круга более 90 кадров
    }
  }
}

void effectA(int speed){
  for (int i = 0; i < 16; i++) {
    for (int k = i; k < 16; k++) {
      regWrite(k, HIGH);
      delay(speed);
      regWrite(k, LOW);
    }

    regWrite(i, HIGH);
  }
}

void effectB(int speed) {
  for (int i = 15; i >= 0; i--) {
    for (int k = 0; k < i; k++) {
      regWrite(k, HIGH);
      delay(speed);
      regWrite(k, LOW);
    }

    regWrite(i, HIGH);
  }
}

void effectC(int speed){
  int prevI = 0;
  for (int i = 0; i < 16; i++) {
    regWrite(prevI, LOW);
    regWrite(i, HIGH);
    prevI = i;

    delay(speed);
  }

  for (int i = 15; i >= 0; i--) {
    regWrite(prevI, LOW);
    regWrite(i, HIGH);
    prevI = i;

    delay(speed);
  }
}

void effectD(int speed){
  for (int i = 0; i < 8; i++) {
    for (int k = i; k < 8; k++) {
      regWrite(k, HIGH);
      regWrite(15 - k, HIGH);
      delay(speed);
      regWrite(k, LOW);
      regWrite(15 - k, LOW);
    }

    regWrite(i, HIGH);
    regWrite(15 - i, HIGH);
  }
}

void effectE(int speed) {
  for (int i = 7; i >= 0; i--) {
    for (int k = 0; k <= i; k++) {
      regWrite(k, HIGH);
      regWrite(15 - k, HIGH);
      delay(speed);
      regWrite(k, LOW);
      regWrite(15 - k, LOW);
    }

    regWrite(i, HIGH);
    regWrite(15 - i, HIGH);
  }
}

void regWrite(int pin, bool state) {
  //Определяет регистр
  int reg = pin / 8;
  //Определяет pin для фактического регистра
  int actualPin = pin - (8 * reg);

  //Начать сеанс
  digitalWrite(latchPin, LOW);

  for (int i = 0; i < numOfRegisters; i++) {
    // Получить фактические состояния для регистра
    byte* states = &registerState[i];

    //Обновить состояние
    if (i == reg){
      bitWrite(*states, actualPin, state);
    }

    //Написать
    shiftOut(dataPin, clockPin, MSBFIRST, *states);
  }

  // Окончание сеанса
  digitalWrite(latchPin, HIGH);
}

, 👍1


1 ответ


2

Это происходит ВСЕ ВРЕМЯ. Не используйте задержку. Выполните поиск в Google по адресу "arduino blinkwithoutdelay" и прочитайте одну из различных статей на эту тему.

Вот запись, которая выглядит довольно хорошо:

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing

,