Добрый день. Передо мной стоит задача использовать Arduino как устройство передачи данных на адреcную LED ленту. Информация о цвете диодов (пикселей) посылается из внешней программы TouchDesigner (далее TD). Есть проблемы корректной работы ленты. Можете подсказать? TD отправляет информацию по serial port простым скриптом. Суть скрипта в том, что данные о координатах цвета пикселя пакуются в одномерный целочисленный массив. Числа в диапазоне от 0 до 255. Информация передаётся с частотой обновления 60FPS. Скетч arduino будет в конце топика. По железкам сборка следующая: PC > Arduino UNO > драйвер светодиодных лент WS2812 от Troyka > лента на WS2815. В модуль Troyka подключены кабели питания земли и управляющего сигнала от ленты Возникают следующие проблемы. При малом количестве пикселей всё работает нормально. начиная с 7 пикселей лента начинается работать не корректно. 1) С 7 задействованных пикселей значения пикселя сдвигаются на 1. Т.е. если в оригинальном изображении первый пиксель был белым, а последний синим на ленте первый диод будет синим, а второй белым. Данный сдвиг в 1 пиксель постепенно увеличивается. Например при 40 задействованных диодах сдвиг составляет уже 3 пикселя; 2) После 32 пикселей искажаются координаты цвета. Я узнаю паттерн, который отдаётся в ардуино, но цвета кардинально отличаются. Как будто значения цвета на пикселе перепутаны местам; 3) После 47 пикселей лента начинает хаотично мигать. Со стороны TD я проверил все слабые места. Пробовал несколько модулей для лент от Troyka. Попробовал ленты на разных чиппах, близких к ws2812. Направление потока данных на ленте соблюдено. Лента на 12В, запитана с другой стороны. Судя по работе ленты, ошибки увеличиваются пропорционально количеству задействованных пикселей. Из чего я делаю вывод, что это возможно связано с электрической частью. Скетч ардуино: Код (C++): #include <FastLED.h> #define NUM_LEDS 10 #define DATA_PIN 4 CRGB leds[NUM_LEDS]; const int dataChunkSize = 3; const int numOfBytes = NUM_LEDS * dataChunkSize; byte inputBuffer[numOfBytes]; void setup() { FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); FastLED.clear(); Serial.begin(115200); Serial.println("connected"); Serial.setTimeout(300); } void loop() { if(Serial.available() > 0) { Serial.readBytes(inputBuffer, numOfBytes); for (int j = 0; j < NUM_LEDS; j++) { int r = inputBuffer[(j*3)]; int g = inputBuffer[(j*3)+1]; int b = inputBuffer[(j*3)+2]; leds[j] = CRGB(r,g,b); } } else { FastLED.clear(); } FastLED.show(); }
это не связано с электрической частью. проблема чисто программная.. Контроллер просто не успевает. Считаем время: Чтобы передать по Сериал три байта на каждый из 47 светодиодов - на скорости 115200 тебуется около 10мс Чтобы вывести 47 светиков на ленту - еще около 2мс При скорости 60 FPS у нас на все про все есть только 16.6 мс То есть загрузка процессора только на работу с 47 диодами - как минимум 75%. Это при условии, что все идеально синхронизировано и данные одного кадра не наезжают на данные другого. Абсолютный же предел при таком раскладе - примерно 65 диодов Вывод - либо уменьшайте FPS. либо ищите другой способ передачи информации, Сериал слишком медленный.
Я на полпути решения данной проблемы http://forum.amperka.ru/threads/attiny817-ws2812.18338/ Пока периферия засылает код в один светодиод ленты, у меня есть 320 тактов на решение других задач. Например, перевод HSL -> RGB. На этот процесс уходит 98 тактов. Остаётся ещё 200. Фактически, скорость обновления ленты зависит от количества светодиодов в ленте и более ни от чего.
Тоже думал на фпс и уменьшал до 30. Кажется не помогало. Но повторно проверю завтра. Имеет ли смысл разбивать поток данных на диоды в несколько потоков? Ардуино сможет сделать это? Очень условно понимаю о чем речь. Ваш пост изучу внимательно.
У меня в ленте 448 светодиодов. Все последовательно. Каких-то быстрых эффектов мне не надо, а вот моменты включения и выключения хочется анимировать по максимуму. Кстати, жрут они мама не горюй! 300 светодиодов на половине яркости (127) жрут аж 60 ватт!
ты там в соседней ветке спрашивал, чем хороша СТМ Так вот, на копеечной STM32F103 есть два канала SPI с поддержкой DMA. Дальше обьяснять? Работа с WS2812 происходит так - ты указываешь первый байт массива данных для ленты, запускаешь SPI и активируешь DMA. И все. С этого момента программа может заниматься своими делами, массив будет выгружен на ленту без участия центрального процессора. Никаких таймеров и прерываний для отсылки каждого байта. И все это доступно любому новичку прямо в Ардуино ИДЕ
Это смысла не имеет, поскольку в вашей проблеме главное узкое место - это передача данных с ПК на ардуину. Так что варианты у вас только уменьшение FPS или кардинальное изменение алгоритма, например предварительная запись всей последовательности на флеш-память, а потом воспроизведение с нее.
"ноу-хау" parovoZZa вам ничего не даст, поскольку ваша проблема не в медленности ардуины, а пропускной способности Сериал интерфейса.
attiny11416 - 60 центов, твоя STM32 в самом дешманском варианте 2 бакса. Плюс догрузом ненужные USB и CAN. Нет, не все. Данные ещё надо подготовить, ибо 0 в массиве это совсем не ноль на выходе SPI. Эта артподготовка нивелирует превосходство по тактовой частоте (70 против 20 МГц). Согласен, что доступно, но не все могут освоить. Резюме - не убедил.
Так а мне-то нужен тот, у которого есть USB. STM анонсировал G0 серию. Мк из valueline кладут на лопатки F серию. Там тебе и кэш команд, куча защит, aes и ещё что-то, но пока нет USB(