Увеличение занятой памяти при переносе массива внутрь setup()

Изначально массив датчиков задан в глобальном массиве:

const uint8_t addr[] [8] PROGMEM = {
{0x28, 0xFF, 0x98, 0xA2, 0x6B, 0x14, 0x3, 0x3E},  
{0x28, 0xFF, 0x79, 0x78, 0x6B, 0x14, 0x3, 0x33},  
{0x28, 0xFF, 0xB9, 0x3F, 0x71, 0x14, 0x4, 0xD4},  
{0x28, 0xFF, 0x1, 0x2A, 0x70, 0x14, 0x4, 0xB7},   
{0x28, 0xFF, 0xC4, 0x41, 0x70, 0x14, 0x4, 0x43},  
…(и.т.д 18 датчиков)
};

void setup(void) {
// устанавливаем адреса датчиков температуры
for (int i = 0; i < DS_SENSOR_AMOUNT; i++) {
sensor[i].setAddress( pgm_read_byte(&(addr[i])) );
}
…
}

Скетч использует 26374 байт (85%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 1383 байт (67%) динамической памяти, оставляя 665 байт для локальных переменных. Максимум: 2048 байт.

Прочитал правильную мысль, что не надо держать глобально всё подряд, а лучше внести внутрь функции, чтобы после выхода из неё память освободилась. Ну и перенёс этот массив addr внутрь setup, то есть вставил в самое начало, сразу перед циклом.
И увидел вот это:
Скетч использует 26568 байт (86%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 1527 байт (74%) динамической памяти, оставляя 521 байт для локальных переменных. Максимум: 2048 байт.

Попробовал убрать PROGMEM и/или const - просто обычный массив объявить, тоже не помогает…

Что я не так делаю?
Массив addr должен удаляться после закрытия setup и память должна очиститься?
Или это особенности подсчёта занятой памяти по ходу компиляции?

не дописал
#define DS_SENSOR_AMOUNT 18
но это вроде понятно

Массиа констант в любом случае займёт место во флеше.

Вы не увидите при компиляции как меняется размер озу после выхода из функции

.setAddress как описана ? Что принимает на вход ?

А это что? Вы перекладываете яйца из одной корзины в другую, а обе эти корзины у вас в машине … сколько места освободиться?

В общем и целом это правильная мысль, но к вашему случаю она не имеет отношения, так как ваш массив не в оперативной памяти, а во флеш.
Оставьте массив там, где он находился.
Какая библиотека работы с сенсорами у вас используется?

void setup(void) {
uint8_t buf[8];  // Временный буфер в RAM (8 байт)
// Устанавливаем адреса датчиков температуры
for (int i = 0; i < DS_SENSOR_AMOUNT; i++) {
memcpy_P(buf, addr[i], 8);    // Копируем 8 байт из FLASH в RAM
sensor[i].setAddress(buf);    // Передаём указатель на buf
// setAddress должен скопировать адрес во внутренний массив sensor[i]
// Если setAddress просто сохраняет указатель - это будет ошибка!
// Нужно, чтобы он делал внутреннее копирование
}
// После цикла buf освободится (выйдет из стека)
// Но адреса уже скопированы внутрь sensor[i], всё работает
}

void loop() {
// Ваш основной код
}

может пригодится

Вот то-то и оно :slight_smile:

Вот, вроде ничего не забыл:

const uint8_t addr[] [8] PROGMEM = {
{0x28, 0xFF, 0x98, 0xA2, 0x6B, 0x14, 0x3, 0x3E},
{0x28, 0xFF, 0x79, 0x78, 0x6B, 0x14, 0x3, 0x33},

};
#include <microDS18B20.h>
#define DS_SENSOR_AMOUNT 18

//DS_ADDR_MODE для подключения блока адресации
//и создаём массив датчиков на пине D3
MicroDS18B20<3, DS_ADDR_MODE> sensor[DS_SENSOR_AMOUNT];

void setup(void) {
// устанавливаем адреса датчиков температуры
for (int i = 0; i < DS_SENSOR_AMOUNT; i++) {
sensor[i].setAddress( pgm_read_byte(&(addr[i])) );
}

}

ум за разум… да, всё, похоже что вопрос снят…
Спасибо.

Или у вас какая-то древняя версия библиотеки, или выше некорректный код

Читать кусками?
Спасибо, надо подумать.
Я изначально вообще хотел этот массив на SD-шку в файл выгрузить и вот так кусочками считывать (вообще не хотел флеш использовать, но потом подумал, что 100 тыщ циклов - это много…)


// указываем, что будем работать с адресацией, на линии будет несколько (amount) датчиков, а адреса будем хранить в PROGMEM
// см. пример async_read_many_bus_pgm
MicroDS18B20<uint8_t pin, DS_ADDR_MODE, uint8_t amount, DS_PROGMEM>;

Что именно не так, где напортачил?
Я сейчас без датчиков - в тепле, так что замеры не вижу, ардуинку домой забрал… но буквально в прошлые выходные всё вроде работало…

ничего не выйдет. И код от @BABOS тоже не пойдет.

@kuksha
Ответьте на мой вопрос - какую именно версию Гайверовской либы вы используете?

да все.
Вот у @Komandir в посте #11 правильный код. А у вас что?

Там же даже пример есть для немкольких адресов в прогмем

поскольку я чайник, то не уверен что в правильном месте смотрю - открыл сам файл microDS18B20.h
v3.10

microDS18B20/examples/async_read_many_bus_pgm at main · GyverLibs/microDS18B20 · GitHub

тогда ваш код неправильный.

Откройте пример библиотеки async_read_many_bus_pgm.ino

вижу, что параметров больше
И как оно в таком случае у меня работает - температуру-то правильно показывает… систему переставлял, может на самом деле не в той папке смотрю.
Спасибо, разберусь завтра. Бардак похоже…

Ну знаете, иногда минус на минус дает плюс. Может у вас на все 18 сенсоров читается один первый адрес.

Вообще, либы Гайвера и так славятся обилием ошибок, а если еще их и использовать неправильно, вообще ни на что положится нельзя будет :slight_smile: