@soofftt91

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

Через WebSocket передаю на ардуину строку с последовательностью цветов для каждого светодиода. Сейчас цвета передаются в hex формате с 6 символами, но планирую переписать на 3 символьный hex.

Получаемые данные обрабатываются так:
char data[length - 2];
  for (int x = 2; x < length; x++) { // первые 2 символа отсекаем т.к. там тип события и разделитель
    data[x - 2] = (char) payload[x];
  }


Далее в зависимости от типа события вызывается соответствующая функция:
switch (payload[0]) {
    .......
    case 'C': // Color Array: c|FFFFFF000000..
      eventColorArray(data);
      break;
    .......
  }


Функция обработки события:
void eventColorArray(char* data) {
  for (byte i = 0; i < LEDS_COUNT / 2; i += 1) {
    char hex[6];
    for (int j = 0; j < 6; j++) { // первые 2 символа отсекаем т.к. там тип события и разделитель
      hex[j] = (char) data[j + (6 * i)];
    }
    unsigned long rgb = (unsigned long) strtol(hex, NULL, 16);
    byte r = abs(0 + (rgb >> 16) & 0xFF);
    byte g = abs(0 + (rgb >>  8) & 0xFF);
    byte b = abs(0 + (rgb >>  0) & 0xFF);
    strip.setPixelColor(i*2, strip.Color(g, r, b));
    strip.setPixelColor(i*2+1, strip.Color(g, r, b));
  }
  strip.show();
}


Все это работает более менее стабильно до ±10 fps. Дальше начинается накапливаемая задержка.

Часть проблемы возможно в слабом интернете, ибо в ленте 234 светодиода, это одна из причин почему решил слать 3х символьный hex вместо 6 символьного. Но также возможно более опытные люди подскажут как оптимизировать функцию "заливки ленты".
  • Вопрос задан
  • 71 просмотр
Решения вопроса 1
ProgrammerForever
@ProgrammerForever
Учитель, автоэлектрик, программист, музыкант
1) Упростить алгоритм передачи, убрать по максимуму служебные поля
2) Гнать данные в сыром бинарном формате (что пришло, то и пуляется в ленту), а не "человекопонятном" с кучей преобразований
3) Возможно имеет смысл готовить несколько кадров за раз, оптимально использовать размер пакета данных того протокола через который данные перегоняются, чтобы, опять же, сэкономить на служебных данных
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@lonelymyp
Хочу вылезти из минуса по карме.
Чтобы знать что ускорять имеет смысл для начала сделать замеры.
Например раскидать в коде micros() и выводить в консоль длительности выполнения разных операций

Возможно что strip.setPixelColor сама по себе очень медленная и повтор её 234 раза даёт сильный затуп.
Тогда возможно стоит порезать ленту на несколько кусков и использовать их отдельно, просто протянув провода от ардуины к нужным частям ленты.
Насколько я помню там идёт именно заливка, то есть чтобы зажечь 234 диод надо выполнить перекидывание команды по всем 233 диодам, а если поделить на 3 части, то заливка ленты ускорится в 2 раза.

В идеале библиотечка неопиксела может дать 110 герц на 256 диодах, в примере выше я вижу сразу две процедуры подряд, значит итоговая частота уже падает до 50 герц, но если в коде между процедурами установкой цвета есть какие-то ещё операции, что-то там разбирается из пакетов, или не дaй бог delay(), то частота заливки будет ощутимо меньше.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы