Ви не увійшли.
Сторінки 1
Добрый день. Помогите начинающему.
Хочу сделать управление поливом. Плата UNO.
Создал структуру CONFIG для хранения конфирационных данных.
- poliv_ZoneCount - количество зон
- poliv_ZonePin - динамический массив номеров зон (по количеству зон)
- poliv_Plans - динамический массив структур плана полива PolivPlan_t, структура собержит время старта и динамический массив таймингов полива зон (по количеству зон)
В void setup() сначала задаю количество зон и количество планов, переконфигурируется переменная CONFIG и потом заполняется.
Для теста сразу выводится конфигурация.
Проблема:
1.Помогите пожалуйста оценить правильно ли я работаю с массивами
2.Иногда код выводит неожиданные числа в тайминге плана, при чем именно в тайминге, стартовое время показывается правильно
Пример правильного вывода
poliv_Plan:0 active:1 time:12:33 timers:5 6 7 8 9 10 11
Но иногдла показывает
poliv_Plan:0 active:1 time:12:33 timers:21 32 8 56 0 1 0
#include <EEPROM.h>
#define SerialSpeed 9600
#define InvBit(reg, bit) reg ^= (1<<(bit))
bool needRestart = false;
// Структура объекта ЗонаПолива
typedef struct PolivPlan_t{
bool Active ;
uint8_t TimeStartH;
uint8_t TimeStartM;
uint8_t *poliv_ZoneTimes=0; // массив Таймингов для каждой зоны
} ;
struct configObj {
bool serialShow; // показывать диагностический вывод
bool poliv_Active; // полив может запускаться
uint8_t poliv_ZoneCount; // количество зон полива
uint8_t poliv_PlanCount; // количество планов полива
uint8_t *poliv_ZonePin=0; // Массив номеров зон полива
PolivPlan_t *poliv_Plans=0;// Массив зон полива
byte controlByte = 0x55;
} config;
//-----------------------------------------------------------------------
void printConfig();
void ConfigSave(){
uint16_t startingAddress = 0;
EEPROM.put(startingAddress, config); startingAddress += sizeof(config);
//poliv zone pins
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++){
EEPROM.put(startingAddress, config.poliv_ZonePin[_zone]); startingAddress += sizeof(config.poliv_ZonePin[_zone]);
}
//poliv plans
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
EEPROM.put(startingAddress, config.poliv_Plans[_plan].Active); startingAddress += sizeof(config.poliv_Plans[_plan].Active);
EEPROM.put(startingAddress, config.poliv_Plans[_plan].TimeStartH); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartH);
EEPROM.put(startingAddress, config.poliv_Plans[_plan].TimeStartM); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartM);
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++) {
EEPROM.put(startingAddress, config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]); startingAddress += sizeof(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]);
}
}
}
void ConfigLoad(){
Serial.print("np1");
uint16_t startingAddress = 0;
EEPROM.get(startingAddress, config); startingAddress += sizeof(config);
config.poliv_ZonePin=0;
config.poliv_Plans=0;
ChangeConfig();
//poliv zone pins
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++){
EEPROM.get(startingAddress, config.poliv_ZonePin[_zone]); startingAddress += sizeof(config.poliv_ZonePin[_zone]);
}
//poliv plans
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
EEPROM.get(startingAddress, config.poliv_Plans[_plan].Active); startingAddress += sizeof(config.poliv_Plans[_plan].Active);
EEPROM.get(startingAddress, config.poliv_Plans[_plan].TimeStartH); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartH);
EEPROM.get(startingAddress, config.poliv_Plans[_plan].TimeStartM); startingAddress += sizeof(config.poliv_Plans[_plan].TimeStartM);
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++) {
EEPROM.get(startingAddress, config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]); startingAddress += sizeof(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]);
}
}
}
void ChangeConfig(){
//--- poliv_ZonePin
config.poliv_ZonePin = (uint8_t*) realloc(config.poliv_ZonePin, config.poliv_ZoneCount * sizeof(uint8_t));
//--- poliv_Plans
config.poliv_Plans = (PolivPlan_t*) realloc(config.poliv_Plans, config.poliv_PlanCount * sizeof(PolivPlan_t));
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
config.poliv_Plans[_plan].poliv_ZoneTimes = (uint8_t*)realloc(config.poliv_Plans[_plan].poliv_ZoneTimes, config.poliv_ZoneCount * sizeof(uint8_t));
}
}
void setup() {//=== SETUP ======= SETUP ======= SETUP
Serial.begin(SerialSpeed);
// --- Предварительная запись в EEPROM ----
Serial.println(F("test varialbe set"));
config.poliv_Active = true;
config.poliv_ZoneCount = 7;
config.poliv_PlanCount = 1;
config.poliv_ZonePin = 0; // первоначальная инициализация перед заполнением из EEPROM
config.poliv_Plans = 0; // первоначальная инициализация перед заполнением из EEPROM
Serial.println(F("nChangeConfig();"));
ChangeConfig(); // переконфигурирование CONFIG
Serial.println(F("test varialbe set next"));
config.poliv_ZonePin[0] = 20;
config.poliv_ZonePin[1] = 21;
config.poliv_ZonePin[2] = 22;
config.poliv_ZonePin[3] = 23;
config.poliv_ZonePin[4] = 24;
config.poliv_ZonePin[5] = 25;
config.poliv_ZonePin[6] = 26;
config.poliv_Plans[0].Active = true;
config.poliv_Plans[0].TimeStartH = 12;
config.poliv_Plans[0].TimeStartM = 33;
config.poliv_Plans[0].poliv_ZoneTimes[0] = 5;
config.poliv_Plans[0].poliv_ZoneTimes[1] = 6;
config.poliv_Plans[0].poliv_ZoneTimes[2] = 7;
config.poliv_Plans[0].poliv_ZoneTimes[3] = 8;
config.poliv_Plans[0].poliv_ZoneTimes[4] = 9;
config.poliv_Plans[0].poliv_ZoneTimes[5] = 10;
config.poliv_Plans[0].poliv_ZoneTimes[6] = 11;
printConfig();
Serial.println(F("nChangeSave()"));
ConfigSave();
/* Serial.println(F("nConfigLoad()"));
ConfigLoad();
Serial.println("nAFTER LOAD");
printConfig();
*/
}
void loop(){
/* Serial.println("nvoid loop()");
printConfig();
delay(1000);
*/
}
void printConfig() {//--- Вывод текущей конфигурации ----------
Serial.print(F("Current config"));
if (needRestart) Serial.print(F(" !!! Need restart !!!"));
Serial.println();
Serial.print(F("serial show:")); Serial.println(config.serialShow);
Serial.print(F("poliv_Active:")); Serial.println(config.poliv_Active);
Serial.print(F("poliv_ZoneCount:")); Serial.print(config.poliv_ZoneCount);
Serial.print(F(" contact numbers:")); for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++){Serial.print(config.poliv_ZonePin[_zone], DEC); Serial.print(" ");} Serial.println();
Serial.print(F("poliv_PlanCount:")); Serial.println(config.poliv_PlanCount);
// poliv plan
for (uint8_t _plan=0; _plan<config.poliv_PlanCount; _plan++) {
Serial.print(F("poliv_Plan:")); Serial.print(_plan);
Serial.print(F(" active:")); Serial.print(config.poliv_Plans[_plan].Active);
Serial.print(F(" time:")); Serial.print(config.poliv_Plans[_plan].TimeStartH);Serial.print(F(":")); Serial.print(config.poliv_Plans[_plan].TimeStartM);
Serial.print(F(" timers:"));
for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++) {
Serial.print(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]);Serial.print(F(" "));
}
Serial.println();
}
}
Остання редакція VLDnepr (2022-01-31 10:45:40)
Неактивний
Когда Вы делаете realloc(config.poliv_Plans[_plan].poliv_ZoneTimes, ...); то последние значения config.poliv_Plans[_plan].poliv_ZoneTimes (до индекса config.poliv_PlanCount и начиная с его предыдущего значения) находятся в только что выделенной (расширенной) области памяти и не инициализированы. Чтобы инициализировать нулями только нужные (новые), Вам нужна информация о предыдущем значении config.poliv_PlanCount.
Неактивний
Когда Вы делаете realloc(config.poliv_Plans[_plan].poliv_ZoneTimes, ...); то последние значения config.poliv_Plans[_plan].poliv_ZoneTimes (до индекса config.poliv_PlanCount и начиная с его предыдущего значения) находятся в только что выделенной (расширенной) области памяти и не инициализированы. Чтобы инициализировать нулями только нужные (новые), Вам нужна информация о предыдущем значении config.poliv_PlanCount.
Это как раз понятно и будет отработано.
Осенила другая мысль
void ConfigLoad(){
Serial.print("np1");
uint16_t startingAddress = 0;
EEPROM.get(startingAddress, config); startingAddress += sizeof(config);
config.poliv_ZonePin=0;
config.poliv_Plans=0;
ChangeConfig();
Строки
config.poliv_ZonePin=0;
config.poliv_Plans=0;
Переменные являются указателями на динамические массивы. Предполагалось что строки сбросят указатели, т.е. они не должны указывать никуда.
Но помоему в этом написании я не сбрасываю указатель, а изменяю значение, на которое указывает указатель?
Как правильно сбросить указатель, чтобы сам указатель был NULL?
Неактивний
NULL это (void*)0, можно писать config.poliv_Plans=0, а можно config.poliv_Plans=NULL, просто в первом случае будет предупреждение компилятора о несоответствии типов. Пишите всегда NULL, если присваиваете указателю, считайте это правилом хорошего тона.
Неактивний
Массивы индексируются, начиная с 0. Если вы введете 1 вместо x, ваш массив будет иметь длину 1, и этот один элемент будет проиндексирован как числа[0]. number[1] не существует, отсюда и ошибка.
Сторінки 1