Изменение функции neopixel rainbow для работы с 4 контактами

Итак, моя настройка такова, что у меня есть полоски, разделенные на 4 контакта, и я хотел бы изменить эту функцию rainbow из neopixel, чтобы она работала на 4 отдельных полосках, которые находятся на 4 отдельных контактах. Я хотел бы выглядеть так, как будто полоса № 2 является продолжением полосы № 1, а число 3 равно 2, а число 4 равно 3. Очень интересная особенность этой функции заключается в том, что начало и конец являются продолжением, так что это означает, что у меня в основном есть настройка кольца.

void rainbow(int wait) {
  // Оттенок первого пикселя проходит 5 полных циклов по цветовому колесу.
  // Цветовое колесо имеет диапазон 65536, но все в порядке, если мы перевернемся, так что
  // просто посчитайте от 0 до 5*65536. Каждый раз добавляя 256 в firstPixelHue
  // означает, что мы сделаем 5*65536/256 = 1280 проходов через этот внешний цикл:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Смещение оттенка пикселя на величину, позволяющую сделать один полный оборот
      // цветового круга (диапазон 65536) по длине полосы
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() может принимать 1 или 3 аргумента: оттенок (от 0 до 65535) или
      // при необходимости добавьте насыщенность и значение (яркость) (каждое от 0 до 255).
      // Здесь мы используем только вариант оттенка с одним аргументом. Результат
      // передается через strip.gamma32() для обеспечения более "правильных" цветов
      // перед назначением каждому пикселю:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Обновить полосу новым содержимым
    delay(wait);  // Пауза на мгновение
  }
}

Я не понимаю, как работает оттенок и гамма, поэтому мне немного сложнее изменить эту функцию.

Вот моя попытка, но моя попытка такая грубая, а у хоггса так много памяти

void rainbow(int wait) {

  unsigned int totalPixelCount = strip1.numPixels() + strip2.numPixels() + strip3.numPixels() + strip4.numPixels();
  uint32_t pixelHueList [totalPixelCount];
  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
    for (int i = 0; i < totalPixelCount; i++) {
      int pixelHue = firstPixelHue + (i * 65536L / totalPixelCount);
      pixelHueList[i] = strip1.gamma32(strip1.ColorHSV(pixelHue));
    }

    unsigned int j = 0;
    for (j = j; j < strip1.numPixels(); j++)
      strip1.setPixelColor(j,pixelHueList[j]);
    for (j = j; j < strip1.numPixels() + strip2.numPixels(); j++)
      strip2.setPixelColor(j,pixelHueList[j]);
    for (j = j; j < strip1.numPixels() + strip2.numPixels() + strip3.numPixels(); j++)
      strip3.setPixelColor(j,pixelHueList[j]);
    for (j = j; j < strip1.numPixels() + strip2.numPixels() + strip3.numPixels() + strip3.numPixels(); j++)
      strip3.setPixelColor(j,pixelHueList[j]);


    strip1.show();
    strip2.show();
    strip3.show();
    strip4.show();
    delay(wait);
  }
}

Есть ли способ сделать это более эффективным?

, 👍0

Обсуждение

"неподписанные" компиляции?, @VE7JRO

Разве "setPixelColor ()" также не нуждается в индексе светодиода в качестве параметра?, @chrisl

Хорошо, ваш код не может быть скомпилирован из-за некоторых синтаксических ошибок. Кроме того, вам не нужно сначала создавать массив. Вы перебираете светодиоды в любом случае, поэтому вы можете просто вычислить необходимые значения прямо там, не сохраняя их в массиве inbetweeen. Когда я снова сяду за свой компьютер, я смогу написать вам ответ (если никто не будет быстрее)., @chrisl

@chrisl Извиняюсь, я исправил синтаксис :) . Я все еще еду домой, поэтому я просто написал код здесь., @DrakeJest

У вас все еще есть ошибка sytax со строкой pixelHueList[i] = (i, strip1.gamma32(. Я снова рассмотрю ваш вопрос завтра. В моей стране сейчас самое время ложиться спать :), @chrisl

@крисл, конечно ! я буду ждать этого :), @DrakeJest

Почему бы не сделать 1 (расширенную) строку из всех 4 строк NeoPixels и не управлять ими с помощью 1 единственного пина с гораздо более простым кодом?, @StarCat


1 ответ


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

2

В настоящее время вы сначала заполняете массив значениями из расчета, просматривая все светодиоды; а затем вы снова просматриваете все светодиоды, чтобы фактически установить их. Вы можете сделать это за один шаг. Кроме того, ваш текущий код, скорее всего, не будет работать, так как вы просто считаете от нуля до общего количества светодиодов, но отдельная полоса не знает об этом количестве светодиодов. Это приведет к проблемам со всем после первого цикла for, в котором вы установите светодиоды.

Для того, чтобы сделать это за один шаг и одновременно решить проблему:

void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536L; firstPixelHue += 256) {
    int j = 0;
    for (int i = 0; i < strip1.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip1.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }
    j = strip1.numPixels();
    for (int i = 0; i < strip2.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip2.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }
    j += strip2.numPixels();
    for (int i = 0; i < strip3.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip3.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }
    j += strip3.numPixels();
    for (int i = 0; i < strip4.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip3.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }


    strip1.show();
    strip2.show();
    strip3.show();
    strip4.show();
    delay(wait);
  }
}

Здесь я использовал j в качестве индекса для всей цепочки светодиодных лент, а i-в качестве индекса для отдельной светодиодной ленты. Таким образом, j-это начальная точка индекса каждой полосы. Затем вычисление оттенка выполняется с текущим общим индексом (j как смещение текущей полосы во всей цепочке и i как индекс текущего светодиода в текущей полосе) j+i. Для фактической установки соответствующего светодиода мы используем i в качестве индекса текущего светодиода в текущей полосе.

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

Примечание: Я не тестировал приведенный выше код и не компилировал его.

,

Привет! Извините за длинный ответ, пришлось с чем-то разбираться. Я попробую это сделать., @DrakeJest