Проблема - не достаточно памяти Arduino
Я создал скетч для часы, каждого сегмента 9 ws2812b лента.
Глобальные переменные используют 2352 байт (114%) динамической памяти, оставляя -304 байт для локальных переменных.
Максимум: 2048 байт. Проблема - недостаточно памяти.
прочитайте http://www.arduino.cc/en/Guide/Troubleshooting#size
Ошибка компиляции для платы Arduino Uno.
Помогите пожалуйста - как уменьшить используемый объем памяти?
// library
#include <DS3232RTC.h>
#include <TimeLib.h>
#include <Time.h>
#include <Wire.h>
#include <FastLED.h>
//library
// uzgarmaslar
#define NUM_LEDS 380
#define COLOR_ORDER GRB
#define LED_PIN 12
#define DST_PIN 5
#define MIN_PIN 4
#define HUR_PIN 2
#define CHANGE_CLR_PIN 8
#define BRI_PIN 3
// uzgarmaslar
byte digits[10][63] = {
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 0
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1}, // Digit 1
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0}, // Digit 2
};
void PrintNumber(int number,int beginPosition)
{
for(int i=beginPosition; i < beginPosition+63; i++)
{
int arrayPos = i - beginPosition;
if(digits[number][arrayPos] == 1)
{ leds[i] = defaultColor; }
else
{ leds[i] = 0x000000; }
}
}
void OffLights()
{
for(int i=0; i< NUM_LEDS; i++)
{ leds[i] = 0x000000; }
}
void dotSwitch()
{
tmElements_t Now;
RTC.read(Now);
int second = Now.Second;
if (second % 2==0)
{
leds[126] = defaultColor;
leds[127] = defaultColor;
}
else
{
leds[126] = 0x000000;
leds[127] = 0x000000;
};
}
Ответы (1 шт):
Замечания по вопросу:
- Код приведен не весь
- Что такое массив
leds[]? При анализе кода представляется что это массив из 380 элементов, каждый из которых занимает 3 байта. Т.е. всего 1140 байт. - В вашем фрагменте кода переменных массив
digits[10][63]- 630 байт и 14 байт - макросы, которые транслируются вint. Т.е. вероятно где-то ещё есть переменные, которые вы не показали здесь.
Теперь по вариантам уменьшения памяти:
Попробуйте использовать побитовое хранение информации вместо массива byte digits[10][63]. Тогда он будет выглядеть как byte digits[10][8]. И занимать будет не 630 байт а 80.
byte digits[10][8] = {
{ 0b00000000, 0b00111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111}, // Digit 0
// или если бинарная запись чисел не поддерживается
byte digits[10][8] = {
{ 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Digit 0
Из описания модели памяти Arduino:
Неизменяемые строки и данные во время работы скетча можно хранить во флеш-памяти. Для этого необходимо использовать ключ PROGMEM.
Скорее всего что-то можно сделать с массивом leds[], если знать как он объявлен и для чего вообще нужен. Какой тип у массива leds[] и defaultColor? Просто странная размерность - 3 байта leds[i] = 0x000000;. Судя по всему у вас массив leds[380] из 380 светодиодов. И в каждом элементе вы храните его цвет (3 байта). Но судя по коду, реально вы используете только 2 цвета - 0x00 и defaultColor (светит/не светит). Тогда зачем хранить цвет и использовать (наверное!) 3 байта памяти на светодиод ( на весь массив 380*3=1140 байт), если можно хранить побитово 0/1 - 0x0/defaultColor, что на весь массив займет 48 байт?
Даже если хранить не цвет а число 0/1, как изначально в массиве byte digits[][], то у вас произойдет неплохая оптимизация кода - массив займет 380 байт и чтобы записать цифру из digits[][] в leds[] вам нужно будет всего лишь скопировать 63 байта с одного адреса в памяти по другому простым циклом или с помощью memcpy(). И линейный цикл копирования большинство компиляторов заменит на вызов memcpy().
for(int i=0; i < 63; ++i)
leds[beginPosition + i] = digits[number][i];
// большинство компиляторов заменит на
memcpy( &leds[beginPosition], &digits[number][0], 63);
Если заменить хранение абсолютного значения цвета на признак, то уже должно хватить памяти - leds[] 380 байт + digits[][] 630 байт + макросы = 1 Кб, т.е. половина от имеющейся.
Проверьте, сколько памяти у вас занимает тип int - 2 или 4 байта? Скорее всего 2 байта - обычно это можно изменить в настройках компилятора.
Проверьте (на всякий случай) какое выравнивание данных установлено в компиляторе - установите в 1 байт.
Макросы #define LED_PIN 12 по-умолчанию будут транслироваться в целые и занимать 2 байта. Замените на const byte LED_PIN = 12; - будет занимать 1 байт.
Я не сталкивался с программированием Arduino, поэтому это - общие рекомендации по уменьшению расхода памяти.