Как правильно создать массив GButton в setup()?

Scally

✩✩✩✩✩✩✩
24 Сен 2026
2
0
Приветствую всех.
Столкнулся с проблемой, что надо сначала подгрузить пины из EEPROM и потом только инициализировать GButton,
но проблема какая-то странная.
Если глобально объявить массив и заполнить его сразу там-же объектами GButton - то всё норм. Но это не катит, мы ещё не знаем какие пины будут использованы. заменить пины на нужные позже - не нашёл такой процедуры.
Пляски начинаются, если создавать в Setup() GButton с нужным Pin и записывать объект в массив.
ИИшка кучу способов предложила, вроде логично, всё должно работать, но беда от них одна! После такого создания в Serial несколько символов выводишь и всё. Serial висит, даже недовывев остатки строки, хотя loop() дёргается норм.
Что только не пробовал. ИИшка кучу 100% решений выдала, но 2й день мучаюсь с ESP8266 NodeMCU v3.
 

poty

★★★★★★★
19 Фев 2020
3,679
1,056
@Scally, если создать массив внутри блока без static, то он удаляется (освобождается память) и в эту память потом может быть записано всё, что угодно.
Даже static не даёт полной гарантии, если компилятор решит, что доступ к переменной больше никогда не осуществится.
Можно включить класс внутрь другого класса (или напрямую, или через наследование) и загрузить данные из EEPROM в конструкторе.
 

Bruzzer

★★★★✩✩✩
23 Май 2020
841
260
Что только не пробовал. ИИшка кучу 100% решений выдала,
Из кучи 100 % решений (+1 от poty) надо выбрать наиболее вам понятное, сделать на его основе полный и понятный но КОРОТКИЙ пример, и если не работает, то привести код этого примера (вставленный с форматированием сообщения из панели инструментов </>), и спросить - в чем может быть дело.
 

Scally

✩✩✩✩✩✩✩
24 Сен 2026
2
0
@poty, структура и её массив, куда она пихается - всё глобально. Делал цельным классом сначала, думал что он виноват, разобрал на отдельные массивы, нашёл, что затыкается при создании GButton и. Если класс создать глобально, записав в него сразу данные, то норм, если в setup() - рушится.
А как вы создаёте в массиве GButton, если не заполняете его при инициализации? Можно пример?
А то похоже, что придётся лезть в исходник GButton и Public'овать переменную с PIN.
 

bort707

★★★★★★★
21 Сен 2020
3,530
1,008
@Scally,

В общем случае это обычно делается так - глобально создается только указатель на GButton (или массив указателей), а сами экземпляры создаете динамически когда прочитаете пины, например в setup().

Если не работает - покажите код, как пробовали.

Ну а в целом ничего удивительного, все опытные программисты в курсе, что либы Гайвера строго рекомендуется использовать только так, как описано в примерах :) Шаг в сторону - и все посыпалось :)
 
Изменено:

poty

★★★★★★★
19 Фев 2020
3,679
1,056
@Scally, массив из классов - это массив указателей. Если сам класс создаётся в глобальном контексте, то память под сам объект выделяется также глобально. Соответственно, создание класса внутри блока (например, процедуры или любых фигурных скобок) выделяет память (без static) только до момента выхода из блока. То есть, указатель в глобальном контексте будет указывать на уже освобожденную область памяти, в которую может быть записано всё, что угодно, последующим кодом.
Посмотрите также на вариант @bort707, динамическое выделение памяти не зависит от блока. Я его не предложил только по одной причине: при многократном использовании это может привести к фрагментации памяти, что в условиях её жёсткой ограниченности может привести к проблемам, аналогичным Вашей.
Ну, и использование "библиотеки", если она Вам не подходит, не очень правильный путь. Эта библиотека не настолько сложна, чтобы не изменить её код под себя.