Как объявить глобальный массив, длина которого будет сохранена в EEPROM?
Я работаю с Arduino UNO, подключенным к дисплею BV4612. Я работаю над простым кодом, управляющим несколькими водяными насосами. Каждый насос может работать в нескольких режимах. Я храню эти режимы в массиве. Количество водяных насосов может варьироваться, и я хотел бы сохранить это значение в EEPROM (Arduino или дисплея).
Когда количество насосов фиксировано, я использую фиксированное значение, определяемое макросом:
#define PUMP_COUNT 18 //Сколько у нас насосов
uint8_t pumpModes[PUMP_COUNT];
void setup(){...}
void loop(){...}
Я бы хотел избавиться от фиксированного определенного значения PUMP_COUNT и загрузить его из EEPROM или сохранить новое значение счетчика насосов в EEPROM, если это необходимо. Однако я не могу объявить массив, если не могу выполнить чтение из EEPROM перед функцией setup() следующим образом (например, с адреса 32):
uint8_t pumpModes[EEread(32)];
void setup(){...}
void loop(){...}
Есть ли решение, как получить значение из EEPROM, чтобы с его помощью можно было объявить длину глобального массива?
Спасибо.
@MiragePV, 👍1
2 ответа
Лучший ответ:
В языке C нельзя создавать массивы переменной длины. Это не так работает в языке C.
Вместо этого вам придется создать массив достаточно большого размера для хранения максимального количества насосов, с которыми вы хотите иметь дело.
Таким образом, «размер» массива — это просто число в переменной, полученной из любого места (включая EEPROM).
Неважно, используете ли вы весь массив. Всё остальное просто лежит там, метафорически бездействуя.
Другой вариант, если вы собираетесь определить массив только один раз при запуске или очень редко изменять его размер, — использовать malloc():
uint8_t *pumps;
uint8_t nPumps = 0;
void setup() {
nPumps = EEPROM.read(32);
pumps = (uint8_t *)malloc(nPumps);
}
Вы можете изменить размер массива с помощью:
nPumps = 8; // например
pumps = realloc(pumps, nPumps);
И удалите массив с помощью:
nPumps = 0;
free(pumps);
Лучше всего постараться не изменять размер массива после его создания, так как это может превратить кучу в швейцарский сыр, и это не очень удобно для небольшого микроконтроллера. Если вы можете задать размер массива один раз при настройке и поддерживать его неизменным на протяжении всей работы программы, это безопасная операция. В противном случае это становится рискованным.
Можно использовать динамически выделяемый массив с malloc и free.
Для создания такого массива используйте:
uint8_t* pumpModes;
Где-то в настройках (предпочтительно):
pumpModes = malloc(sizeof(uint8_t) * PUMP_COUNT);
Освобождение памяти не требуется, если она нужна на протяжении всей программы, в противном случае можно использовать
free(pumpModes);
Однако имейте в виду, что если вы постоянно выделяете и освобождаете память в функции loop(), то можете получить «пробелы» в памяти, и она очень быстро закончится, поскольку у Uno всего несколько КБ оперативной памяти.
- Использование переменной для индексации массива
- Что означает display.setSegments(&segto, 1, 1); делать?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- Как изменить байт на целое число? - Arduino
- Некоторые переменные не сохраняют свои значения при выходе из цикла while?
- Как отобразить переменные с плавающей запятой на OLED-дисплее (0,96 дюйма)
- Сохранение файла .txt на SD-карту и чтение данных каждого содержимого в файл txt, а затем сохранение его в переменной
- Пользовательская функция сна для Nextion