Подключаю светодиодную ленту WS2812B к arduino nano. Длина 20 м (60 led на 1м). Горит только половина (в скетче ограничиваю 600 led). Если увеличиваю в скетче количество светодиодов, то выдает ошибку: не хватает памяти. Как можно решить проблему?
1. Выложьте скетч на обозрение. Телепатов тут нет. или 2. Разрежьте ленту на две по 600 СД и включите параллельно.
Взять другой МК или написать обработку самому. 450 светодиодов и всего 2 кБ ОЗУ: http://forum.amperka.ru/threads/450-ws2812-на-attiny1614-и-немного-кода.20663/
если все светодиоды действуют синхронно или хотя бы там две половины действующие синхронно, то есть массив длинной во всю ленту по факту избыточен, то можно как-нибудь библиотечную функцию покорежить. в библиотеке light_ws2812 например она выглядит так: Код (C++): while (datlen--) { curbyte=*data++; asm volatile(.... дальше всякая дичь на ассемблере ...); } можно же изуродовать так чтобы она вообще одно значение сколько угодно раз посылала, или повторяла массив циклично сколько надо раз.
Не, если скетч создает в памяти МК типа видеобуфер с размерностью в число СД, тогда понятна нехватка памяти. Но зачем это надо ? От числа СД должно зависеть лишь число повторений цикла записи данных в ленту. Ведь лента по сути и есть видео-буфер.
Похоже, что вы еще ни разу ленту 2812 в руках не держали... У адресной ленты цвет (24бита) каждого ЛЕДа задается отдельно. А потом выводится на ленту длинным набором импульсов. Вывод с частотой 800КГц - для ардуино задачка на грани возможности. поэтому на ходу пересчитывать биты некогда, массив видеобуфера должен быть сформирован заранее. Поэтому библиотека заранее создает в памяти МК буфер размером "число СД * 3" байт. В ардуино Уно помещается управление только примерно 2000 /3 = 600 светодиодами. Есть разные ухищрения для уменьшения потребности в памяти. например хранить цвет кажого пикселя не в 3х байтах, а в двух или даже одном - но это уже частности
паровоз. хватит трещать в каждой ветке. выдавая бессмысленные замечания. ты уже демонстрировал свой код для адресной ленты, помнишь. что я тебе на него писал? ты пишешь без ардуины не лучше. чем с ардуиной...
это из апноута с сайта атмела/микрочипа. На замечания людей без подтверждённой квалификации я не реагирую.
Всё верно. Но лента - это лента. Ею кино не показывают. Нет нужды хранить каждый пиксел. Все для чего ее используют - либо гонять по линии повторяющиеся "узоры" (спрайты), либо целиком цветами "переливаться". А для этого нужны лишь "комбинации циклов передачи". Библа, выбранная ТС-ом, явно избыточна для его целей.
Код (C++): #include <FastLED.h> // подключаем библиотеку #define NUM_LEDS 600 #define PIN 4 byte bright = 50; // яркость светодиодов byte rate = 0; // скорость эффектов byte w = 1; // переключение режимов byte baza = 0; // изменение оттенка boolean button1WasUp = true; // переменные для считывания нажатия на кнопки boolean button2WasUp = true; boolean button3WasUp = true; CRGB leds[NUM_LEDS]; void setup() { pinMode(8, INPUT_PULLUP); // подключаем тактовые кнопки pinMode(10, INPUT_PULLUP); pinMode(12, INPUT_PULLUP); FastLED.addLeds <WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); FastLED.setBrightness(bright); } void knopka () { boolean button1IsUp = digitalRead(8); // узнаем текущее состояние кнопок boolean button2IsUp = digitalRead(10); boolean button3IsUp = digitalRead(12); // если кнопка 1 была нажата, добавляем яркость (не больше 250) if (button1WasUp && !button1IsUp) { delay(10); button1IsUp = digitalRead(8); if (!button1IsUp) { bright = bright + 50; if (bright > 250) { bright = 50; } } } button1WasUp = button1IsUp; // запоминаем состояние кнопки 1 // если кнопка 2 была нажата, увеличиваем задержку (не больше 50) if (button2WasUp && !button2IsUp) { delay(10); button2IsUp = digitalRead(10); if (!button2IsUp) { rate = rate + 10; if (rate > 50) { rate = 0; } } } button2WasUp = button2IsUp; // запоминаем состояние кнопки 2 // если кнопка 3 была нажата, переходим в новый режим if (button3WasUp && !button3IsUp) { delay(10); button3IsUp = digitalRead(12); if (!button3IsUp) { w++; if (w > 7) { w = 1; } } } button3WasUp = button3IsUp; // запоминаем состояние кнопки 3 } void loop() { // первый режим (радуга) while (w == 1) { knopka(); // узнаем состояние кнопок for (int i = 0; i < NUM_LEDS; i++) { leds = CHSV(baza+ i * 3, 255, 255); } baza++; FastLED.setBrightness(bright); FastLED.show(); delay(50 - rate); } // второй режим (палитра) while (w == 2) { knopka(); // узнаем состояние кнопок static uint8_t starthue = 0; fill_rainbow( leds + 5, NUM_LEDS - 5, --starthue, rate); uint8_t secs = (millis() / 1000) % (rate * 2); if (secs < rate) { FastLED.setTemperature( Tungsten100W ); leds[0] = Tungsten100W; } else { FastLED.setTemperature( OvercastSky ); leds[0] = OvercastSky; } FastLED.setBrightness(bright); FastLED.show(); } // третий режим (конфетти) while (w == 3) { knopka(); // узнаем состояние кнопок fadeToBlackBy(leds, NUM_LEDS, (rate + 1) * 2); int pos = random16(NUM_LEDS); leds[pos] += CHSV(baza++ + random8(64), 200, 255); FastLED.setBrightness(bright); FastLED.show(); } // четвертый режим (бегущий огонек) while (w == 4) { knopka(); // узнаем состояние кнопок fadeToBlackBy(leds, NUM_LEDS, (rate + 1) * 2); int pos = beatsin16(13, 0, NUM_LEDS - 1); leds[pos] += CHSV(baza++, 255, 192); FastLED.setBrightness(bright); FastLED.show(); } // пятый режим (циклон) while (w == 5) { for (int i = 0; i < NUM_LEDS; i++) { leds.nscale8(250); } for (int i = 0; i < NUM_LEDS; i++) { knopka(); // узнаем состояние кнопок leds = CHSV(baza++, 255, 255); FastLED.setBrightness(bright); FastLED.show(); delay(rate); } } // шестой режим (фокус) while (w == 6) { knopka(); // узнаем состояние кнопок fadeToBlackBy(leds, NUM_LEDS, (rate + 1) * 2); for (int i = 0; i < 8; i++) { leds[beatsin16(i + 7, 0, NUM_LEDS - 1)] |= CHSV(baza+=16, 200, 255); } FastLED.setBrightness(bright); FastLED.show(); delay(10); } // седьмой режим (радуга с мерцанием) while (w == 7) { knopka(); // узнаем состояние кнопок fill_rainbow( leds, NUM_LEDS, baza++, 7); if (random8() < 80) { leds[ random16(NUM_LEDS) ] += CRGB::White; } FastLED.setBrightness(bright); FastLED.show(); delay(50 - rate); } }
Это для разработки своих устройств наверное и не по теме: http://www.gaw.ru/html.cgi/txt/doc/micros/avr/arh128/2_1.htm https://www.rlocman.ru/shem/schematics.html?di=71093 Помню для 51-го ядра (не AVR... но они всё же родственники) была возможность применения внешней памяти... обратил внимание когда ремонтировал в своё время видаки(они применялись как контроллеры системы управления... правда с масочным ПЗУ) . Если что не в тему не ругайте!