Расширение памяти

Тема в разделе "Arduino & Shields", создана пользователем eval25, 12 мар 2021.

  1. eval25

    eval25 Нуб

    Подключаю светодиодную ленту WS2812B к arduino nano. Длина 20 м (60 led на 1м). Горит только половина (в скетче ограничиваю 600 led). Если увеличиваю в скетче количество светодиодов, то выдает ошибку: не хватает памяти. Как можно решить проблему?
     
  2. Ariadna-on-Line

    Ariadna-on-Line Гуру

    1. Выложьте скетч на обозрение. Телепатов тут нет.
    или
    2. Разрежьте ленту на две по 600 СД и включите параллельно.
     
    arkadyf нравится это.
  3. parovoZZ

    parovoZZ Гуру

  4. b707

    b707 Гуру

    Взять контроллер "побольше"
     
  5. akl

    akl Гуру

    если все светодиоды действуют синхронно или хотя бы там две половины действующие синхронно, то есть массив длинной во всю ленту по факту избыточен, то можно как-нибудь библиотечную функцию покорежить.
    в библиотеке light_ws2812 например она выглядит так:

    Код (C++):
    while (datlen--) {
        curbyte=*data++;
       
       asm volatile(....
       дальше всякая дичь на ассемблере
       ...);
    }
    можно же изуродовать так чтобы она вообще одно значение сколько угодно раз посылала, или повторяла массив циклично сколько надо раз.
     
    Ariadna-on-Line нравится это.
  6. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Не, если скетч создает в памяти МК типа видеобуфер с размерностью в число СД, тогда понятна нехватка памяти. Но зачем это надо ? От числа СД должно зависеть лишь число повторений цикла записи данных в ленту. Ведь лента по сути и есть видео-буфер.
     
  7. b707

    b707 Гуру

    Похоже, что вы еще ни разу ленту 2812 в руках не держали...
    У адресной ленты цвет (24бита) каждого ЛЕДа задается отдельно. А потом выводится на ленту длинным набором импульсов. Вывод с частотой 800КГц - для ардуино задачка на грани возможности. поэтому на ходу пересчитывать биты некогда, массив видеобуфера должен быть сформирован заранее.
    Поэтому библиотека заранее создает в памяти МК буфер размером "число СД * 3" байт.
    В ардуино Уно помещается управление только примерно 2000 /3 = 600 светодиодами.
    Есть разные ухищрения для уменьшения потребности в памяти. например хранить цвет кажого пикселя не в 3х байтах, а в двух или даже одном - но это уже частности
     
  8. parovoZZ

    parovoZZ Гуру

    для фреймворка ардуино - да, но для любого МК с частотами 10-20 МГц - нет.
     
  9. b707

    b707 Гуру

    паровоз. хватит трещать в каждой ветке. выдавая бессмысленные замечания.
    ты уже демонстрировал свой код для адресной ленты, помнишь. что я тебе на него писал?
    ты пишешь без ардуины не лучше. чем с ардуиной...
     
  10. parovoZZ

    parovoZZ Гуру

    это не мой код.

    кто?
     
  11. b707

    b707 Гуру

    так это еще и не твой код был? :) ну ваще...
     
  12. parovoZZ

    parovoZZ Гуру

    это из апноута с сайта атмела/микрочипа. На замечания людей без подтверждённой квалификации я не реагирую.
     
  13. b707

    b707 Гуру

    раз на мое реагируешь - это как понимать? - что моя квалификация тобой подтверждена? - спасибо
     
  14. parovoZZ

    parovoZZ Гуру

    не помню.
     
  15. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Всё верно. Но лента - это лента. Ею кино не показывают. Нет нужды хранить каждый пиксел. Все для чего ее используют - либо гонять по линии повторяющиеся "узоры" (спрайты), либо целиком цветами "переливаться". А для этого нужны лишь "комбинации циклов передачи". Библа, выбранная ТС-ом, явно избыточна для его целей.
     
  16. eval25

    eval25 Нуб

    Код (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);
    }
    }
     
    Последнее редактирование модератором: 14 мар 2021
  17. b707

    b707 Гуру

    не нужен уже код ваш, не будет тут 1200 светиков работать НИКАК
     
  18. eval25

    eval25 Нуб

    т.е. добавить память невозможно?
     
  19. eval25

    eval25 Нуб

    Можете что-нибудь посоветовать?
     
  20. Igor68

    Igor68 Гуру

    Это для разработки своих устройств наверное и не по теме:
    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... но они всё же родственники) была возможность применения внешней памяти... обратил внимание когда ремонтировал в своё время видаки(они применялись как контроллеры системы управления... правда с масочным ПЗУ) .
    Если что не в тему не ругайте!