Как объявить глобальный массив с длиной, хранящейся в EEPROM?

Я работаю с Arduino UNO, подключенным к дисплею BV4612. Я работаю над простым кодом, который управляет несколькими водяными насосами. Каждый насос имеет несколько режимов, в которых он может работать. Я храню эти режимы в массиве. Количество водяных насосов может меняться, и я хотел бы сохранить это значение в EEPROM (либо arduino, либо дисплей).

Когда количество насосов фиксировано, я использую фиксированное значение, определенное макросом:

#define     PUMP_COUNT      18      //How many pumps we have

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, чтобы я мог объявить длину глобального массива?

Спасибо.

1 голос | спросил MiragePV 14 PMpSat, 14 Apr 2018 13:07:34 +030007Saturday 2018, 13:07:34

2 ответа


1

Вы не можете создавать массивы переменной длины в C. Это не то, как работает C.

Вместо этого вам нужно создать массив, который достаточно велик для хранения максимального количества насосов, с которыми вы хотите иметь дело.

Массив «размер» - это просто число в переменной, полученной из любой точки (включая EEPROM).

Не имеет значения, не используете ли вы весь массив. Остальное просто сидит там, крутя свои метафорические превью.

Другой вариант, если вы только собираетесь определять массив один раз при запуске или очень редко меняете размер, следует использовать malloc():

uint8_t *pumps;
uint8_t nPumps = 0;

void setup() {
    nPumps = EEPROM.read(32);
    pumps = (uint8_t *)malloc(nPumps);
}

Вы можете изменить размер массива, а затем:

nPumps = 8; // for example
pumps = realloc(pumps, nPumps);

И удалите массив с помощью:

nPumps = 0;
free(pumps);

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

ответил Majenko 14 PMpSat, 14 Apr 2018 13:11:53 +030011Saturday 2018, 13:11:53
0

Можно использовать динамически выделенный массив с malloc и бесплатным.

Чтобы создать такой массив, используйте:

uint8_t* pumpModes;

Где-то в настройке (желательно):

pumpModes = malloc(sizeof(uint8_t) * PUMP_COUNT);

Освобождение памяти не требуется, если вам это нужно на протяжении всей программы, иначе вы можете использовать

free(pumpModes);

Однако учтите, что если вы постоянно malloc и свободная память в функции loop (), вы можете получить «пробелы» памяти, и у вас заканчивается память очень быстро, так как Uno имеет всего несколько КБ ОЗУ.

ответил Michel Keijzers 14 PMpSat, 14 Apr 2018 13:15:58 +030015Saturday 2018, 13:15:58

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132