Запись части структуры в EPPROM

AlexArGC
AlexArGC аватар
Offline
Зарегистрирован: 18.11.2016

Добрый день.

Есть структура

struct ObjetSmartHome {
  double Kp1, Ki1, Kd1;      // для радиаторов
  double Kp2, Ki2, Kd2;      // для теплых полов
  // Температуры зон обогрева для ручного режима
  double SetTEMPZ1, SetTEMPZ2, SetTEMPZ3, SetTEMPZ4, SetTEMPZ5;
  // Температура теплоносителя
  double SetTEMP_T1;
  byte Rezhim;
};

ObjetSmartHome SmartHome;

Для восстановления всех режимов работы после перезагрузки системы, я сохраняю структуру в EPPROM. Достаточно удобно кидать в EPPROM все значения структуры и читать одной командой.

  // Читаем данные настроек системы из EEPROM
  int eeAddress = 0; //Адрес EEPROM для чтения с

  // читаем структуру типа ObjectSmartHome
  EEPROM.get(eeAddress, SmartHome);

...

  // сохраняем структуру типа ObjectSmartHome
  EEPROM.put(eeAddress, SmartHome);

Ну вот в некоторых случаях есть нобходимость сохранить только одно измененное значение из структуры в EPPROM и не переписывать другие. Я понимаю что нужно вычислить eeAddress пременой в структуре. И после, явно его указав, сохранить в EPPROM:


// сохраним в EPPROM только значение коэффициента Kp1

  eeAddress.Kp1 = (вычислим относительны адрес переменной Kp1 в структур);
  EEPROM.put(eeAddress.Kp1, SmartHome.Kp1);

Есть какой либо" красивый" способ/метод это сделать прямо в коде? Чтобы в случае изменения структуры или внесения дополнительных переменных в неё этот код работал.

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

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

Или Вам что-то другое нужно, типа "они-то поменялись, но сохранять не хочу"?

AlexArGC
AlexArGC аватар
Offline
Зарегистрирован: 18.11.2016

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

Или Вам что-то другое нужно, типа "они-то поменялись, но сохранять не хочу"?

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

eeAddress.Kp1 = (int)&SmartHome.Kp1 - (int)&SmartHome;
eeAddress.SetTEMP_T1 = (int)&SmartHome.SetTEMP_T1 - (int)&SmartHome;

Достаточно будет INT для адресации? Переменные GLOBAL хранятся в первом сегменте RAM у MEGA2560?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
#include <EEPROM.h>
struct MyObject {
  float field1;
  byte field2;
  char name[10];
};

int eeAddress = 0;
MyObject Object;

void setup() {
  Object.field1=12.5;
  EEPROM.put((int)(&((MyObject*)eeAddress)->field1),Object.field1);
}

void loop() {
}

 

AlexArGC
AlexArGC аватар
Offline
Зарегистрирован: 18.11.2016

qwone пишет:

...
  EEPROM.put((int)(&((MyObject*)eeAddress)->field1),Object.field1);
...

Красиво записано, а можно разъяснить что происходит в поле "адреса"?

P.S. Нашел очень хорошую статью по EEPROM.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ну вам надо изучить ... язык Си, в частности указатели, указатели на объект, операции приведения , в частности приведение к указателю на объект  . Ну проще подтянуть знание языка Си и его синтаксис.И это не издевательство и не шутка.

https://www.youtube.com/watch?time_continue=41&v=r4dzBju23wQ