Помогите с динамическим массивом

VLDnepr
Offline
Зарегистрирован: 31.01.2022

ЕвгенийП пишет:

VLDnepr пишет:

Вчера переписывал/испытывал код

Вы точно уверены, что результат приведённый в комментарии получен с этим кодом? Совсем с этим, а не с "я там ... но это ни на что не влияет"?

Если с этим, то ищите проблему в шнуре, в раздолбанных разъёмах или ещё в каких помехах.

Я запускал это код на своей тест-станции 3252 раза и ни разу не видел ни одного сбоя.

Я тоже получаю разные результаты, заливая один и тотже код, для пущей верности иногда меняю стото незначительное в цикле loop. 

Плата ведет себя странно, при заливке с ней теряется связь, она может принять заливку, но зависнуть за запуске, а если переподключить, нормально стартует и работает новая заливка. Могут ли эти чудеса быть связаны с битым шнуром или платой?

VLDnepr
Offline
Зарегистрирован: 31.01.2022

Еще обнаружил странный эффект.

если в строке 181 Serial.print(" ");} - то после выполнения 98 строки плата перегружается.

если в строке 181 Serial.print("-");} - то все работает ожидаемо.

Попробую сегодня вечером залить это на мегу2560.

/* test_002_DinamicArray_EEPROM
*/

#include <EEPROM.h>

#define SerialSpeed 9600
#define InvBit(reg, bit)    reg ^= (1<<(bit))
#define SetBit(reg, bit)          reg |= (1<<(bit))
#define InvBit(reg, bit)    reg ^= (1<<(bit))

bool needRestart = false;
bool led = 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);

//    Serial.print(_plan); Serial.print(" plan  ZoneTimes \n ");
    for (uint8_t _zone=0; _zone<config.poliv_ZoneCount; _zone++) {
//      Serial.print(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]); Serial.print(" ");
      EEPROM.put(startingAddress, config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]); startingAddress += sizeof(config.poliv_Plans[_plan].poliv_ZoneTimes[_zone]);
    }
  }
}


void ConfigLoad(){
  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 ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP ======= SETUP =======
  Serial.begin(SerialSpeed);

  Serial.print("\nLoad EEPROM");
  for (uint8_t _i=0; _i<40; _i++) {byte _p; EEPROM.get(_i, _p);  Serial.print(_p, DEC);  Serial.print(" ");}
  Serial.println();

//step 1 - формирование config и запись
/*
  // --- Предварительная запись в EEPROM ----
  Serial.println(F("test varialbe set"));
  config.poliv_Active = true;
  config.poliv_ZoneCount = 7;
  config.poliv_PlanCount = 2;
  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;
  config.poliv_Plans[1].Active = true;
  config.poliv_Plans[1].TimeStartH = 112;
  config.poliv_Plans[1].TimeStartM = 133;
  config.poliv_Plans[1].poliv_ZoneTimes[0] = 15;
  config.poliv_Plans[1].poliv_ZoneTimes[1] = 16;
  config.poliv_Plans[1].poliv_ZoneTimes[2] = 17;
  config.poliv_Plans[1].poliv_ZoneTimes[3] = 18;
  config.poliv_Plans[1].poliv_ZoneTimes[4] = 19;
  config.poliv_Plans[1].poliv_ZoneTimes[5] = 110;
  config.poliv_Plans[1].poliv_ZoneTimes[6] = 111;

  printConfig();

  Serial.println(F("\nChangeSave()"));
  ConfigSave();

  Serial.print("\nLoad EEPROM");
  for (uint8_t _i=0; _i<50; _i++) {byte _p; EEPROM.get(_i, _p);  Serial.print(_p, DEC);  Serial.print(" ");}
  Serial.println();
*/

//step 2 чтение из EEPROM
  Serial.println(F("\nConfigLoad()"));
  ConfigLoad();
  Serial.println("\nAFTER LOAD");

  printConfig();

  //SetBit(DDRB, 5);
  pinMode(13, OUTPUT);
}

  
void loop(){
  Serial.println("\nvoid loop()");
  printConfig();
  delay(1000);

  digitalWrite(13, led); led = !led;
}


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.print(F("\npoliv_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();
  }
}


/*
ChangeConfig();
test varialbe set next
Current config
serial show:0
poliv_Active:1
poliv_ZoneCount:7 contact numbers:20 21 22 23 24 25 26 
poliv_PlanCount:1
poliv_Plan:0 active:1 time:12:33 timers:21 32 8 56 0 1 0 

ChangeSave()
*/

 

VLDnepr
Offline
Зарегистрирован: 31.01.2022

Прошу прощения за назойливость, но хочу уточнить.

Строки ниже обнуляют адрес на который указывают переменные, а не значения ячеек памяти на которые указывают?

1 config.poliv_ZonePin=0;
2 config.poliv_Plans=0;

 

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

VLDnepr пишет:

Прошу прощения за назойливость, но хочу уточнить.

Строки ниже обнуляют адрес на который указывают переменные, а не значения ячеек памяти на которые указывают?

1 config.poliv_ZonePin=0;
2 config.poliv_Plans=0;

 

я ж написал выше, обнуляют ваши указатели poliv_ZonePin и poliv_Plans

даже написал как правильно "обнулять", для получения значения по адресам в этих указателей, надо сделать операцию по разыменованию указателя (если интересно найдете что это)

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

VLDnepr пишет:

Я тоже получаю разные результаты, заливая один и тотже код

Почему "тоже". Я то ничего странного не получаю. Всё нормально работает

VLDnepr пишет:

Плата ведет себя странно, при заливке с ней теряется связь, она может принять заливку, но зависнуть за запуске, а если переподключить, нормально стартует и работает

Шнур, разъёмы USB (с обеих сторон), сильные помехи. Последнее - наименее вероятно. Проверяйте.

У меня тот код, что Вы дали, работает надёжно.