Adafruit NeoPixel какая-то дурацкая проблема

sasken
Offline
Зарегистрирован: 28.10.2015

Здравствуйте.

Есть вот такой простой код:
 

#include <Adafruit_NeoPixel.h>

#define WIDTH 18                     // ширина матрицы
#define HEIGHT 17                    // высота матрицы
#define NUM_LEDS WIDTH * HEIGHT      // общее количество диодов

#define PIN 2      // пин матрицы1
#define PIN_el 6   // пин матрицы2

Adafruit_NeoPixel matrix(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800); 
Adafruit_NeoPixel matrix_el(NUM_LEDS, PIN_el, NEO_GRB + NEO_KHZ800);
const uint16_t colors[] = {matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255) };
const uint16_t colors_el[] = {matrix_el.Color(255, 0, 0), matrix_el.Color(0, 255, 0), matrix_el.Color(0, 0, 255) };
  
void setup() {
  pinMode(PIN, OUTPUT);
  pinMode(PIN_el, OUTPUT);  
  matrix.begin(); 
  matrix_el.begin();
  matrix_el.setBrightness(10); 
}

void loop() {
    matrix_el.setPixelColor(10, 0xFFFFFF);  
    matrix_el.show();
    delay(100);
    matrix_el.setPixelColor(10, 0x000000);
    matrix_el.show();
    delay(100);
}

и он прекрасно работает на мега256 с кварцем 16 МГц, но совершенно не работает на 328 с внутренним генератором на 8 МГЦ.

Если из этого кода убрать объект matrix и оставить все только для объекта matrix_el то код замечательно работает и на 328 с внутренним генератором 8МГц.
А с двумя объектами отказывается работать. не понимаю в чем дело. куда смотреть? как исправить. очень прошу совета.

rkit
Offline
Зарегистрирован: 23.11.2016

Смотреть в сторону покупки кварца, очевидно.

sasken
Offline
Зарегистрирован: 28.10.2015

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

а то получается что с одним обьектом все работает хорошо, а с двумя уже никак?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

виима, памяти не хватат. 

adafruit у себя унутре хапает памяти либо 3*число светодиодов, либо 4 * 

Светодиодов у тебя 306, значит памяти отхапаеца минимум 918 байт на 1 ленту.  Вторая всяко в 328 мегу не влазиит

rkit
Offline
Зарегистрирован: 23.11.2016

sasken пишет:

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

Довольно мелкая плата за ленивость протестировать до заказа.

sadman41
Offline
Зарегистрирован: 19.10.2016

"Отказывается" письменно или устно?

sasken
Offline
Зарегистрирован: 28.10.2015

DetSimen пишет:

виима, памяти не хватат. 

adafruit у себя унутре хапает памяти либо 3*число светодиодов, либо 4 * 

Светодиодов у тебя 306, значит памяти отхапаеца минимум 918 байт на 1 ленту.  Вторая всяко в 328 мегу не влазиит

да. вы правы.  так и есть.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

sasken пишет:

да. вы правы.  так и есть.

Дыкёптыть. 

sasken
Offline
Зарегистрирован: 28.10.2015

DetSimen пишет:
Дыкёптыть.

почему ж тогда arduino IDE обманывает меня показывая, что всего 3% памяти используется

b707
Offline
Зарегистрирован: 26.05.2017

потому что ИДЕ умеет считать память только на глобальные переменные,  а у вас основной расход - на локальные переменные внутри библиотеки NeoPixel. которые к тому же наверняка еще и динамические, которые ИДе тоже не видит

sasken
Offline
Зарегистрирован: 28.10.2015

а атмел студио умеет? давно уже думаю перейти на нее

b707
Offline
Зарегистрирован: 26.05.2017

sasken пишет:

а атмел студио умеет? давно уже думаю перейти на нее

не знаю, но сомневаюсь.

Посчитать налезание стека на кучу или наоборот - не такая простая задача

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
void Adafruit_NeoPixel::updateLength(uint16_t n) {
  free(pixels); // Free existing data (if any)

  // Allocate new data -- note: ALL PIXELS ARE CLEARED
  numBytes = n * ((wOffset == rOffset) ? 3 : 4);
  if((pixels = (uint8_t *)malloc(numBytes))) {
    memset(pixels, 0, numBytes);
    numLEDs = n;
  } else {
    numLEDs = numBytes = 0;
  }
}

внимательно посмотри на строку 6.  Откуда компилятору знать, сколько памяти будет жрать этот массив?  Это знает только менеджер кучи, уже на этапе выполнения.  

Переходить на Atmel Studio в таком контексте - бессмысленно, он тоже не узнает что у тебя в голове. 

sasken
Offline
Зарегистрирован: 28.10.2015

понял. спасибо большое.