Запись и чтение EEPROM

sivanko
Offline
Зарегистрирован: 25.02.2016

Добрый всем день. Начинаю потихоньку осваивать ардуино. Делаю управление на сварку и возникла небходимость в начале работы считать данные о настройках из энергонезависимой памяти (6 переменных - int, одна float). Во время работы из меню настройки эти же переменные должны быть записаны в память. Посмотрел примеры и такое наваял...

 В сетапе


  
  PRE_FLOW_M = EEPROM.read(0);
  OVER_FLOW_M = EEPROM.read(1);
  PRE_FLOW_T = EEPROM.read(2);
  OVER_FLOW_T = EEPROM.read(3);
  PRE_FLOW_P = EEPROM.read(4);
  OVER_FLOW_P = EEPROM.read(5);
  Time_Weld = EEPROM.read(6);

Действие по нажатию кнопки записи

for (int i = 0; i < 512; i++)
    EEPROM.write(i, 0);
  EEPROM.write(0,PRE_FLOW_M);
  EEPROM.write(1,OVER_FLOW_M);
  EEPROM.write(2,PRE_FLOW_T);
  EEPROM.write(3,OVER_FLOW_T);
  EEPROM.write(4,PRE_FLOW_P);
  EEPROM.write(5,OVER_FLOW_P);
  EEPROM.write(6,Time_Weld);

Данные пишет, но "левые", не те что в настройках. Где я неправ?

vde69
Offline
Зарегистрирован: 10.01.2016

int - это 2 байта.... вот пример как работать:

//*************************************************************************************************
// процедура читает из энерго независимой памяти двухбйтовое число
//   num - идентификатор памяти (номер двухбайтного слова)
//*************************************************************************************************
int ReadInt(int num)
{
  byte a;
  byte b;
  int result;
  
  a = int(EEPROM.read(num * 2));
  b = int(EEPROM.read(num * 2 + 1));   
  result = a * 255 + b;

  return result;
}

//*************************************************************************************************
// процедура записывает в энерго независимую память двухбйтовое число
//   num - идентификатор памяти (номер двухбайтного слова)
//   value - записываемое значение
//*************************************************************************************************
void WriteInt(int num, int value)
{
  byte a;
  byte b;
  
  b = value % 255;   
  a = (value - b) / 255;
  EEPROM.write(num * 2, a);
  EEPROM.write(num * 2 + 1, b);
  Beep(4); // сделано для выявления безконтрольной записи и снижения ресурса EEPROM
}

//*************************************************************************************************
// процедуры, для записи и получении всех данных EEPROM 
// собраны здесь для единообразного адресного хранения и визуализации карты использования EEPROM, 
// адреса в двух байтовом виде (1 - это два байта с физическим адресом 2 и 3)
//*************************************************************************************************

// ------------------- чтение -------------------
int Get_signature()    { return ReadInt(0); }                    // 0 - сигнатура
int Get_term_set()     { return ReadInt(1); }                    // 1 - установленая температура
                                                                 // 2...9 - резерв
int Get_temp(int Num) { return ReadInt(Num+10); }                // 10..19 - массив калибровочных температур
int Get_pow(int Num)  { return ReadInt(Num+20); }                // 20..29 - массив мощности поддержания температуры
int Get_tep(int Num)  { return ReadInt(Num+30); }                // 30..39 - массив температур инерционности
int Get_dt(int Num)   { return ReadInt(Num+40); }                // 40..49 - массив времени цикла on/off 
int Get_step(int Num) { return ReadInt(Num+50); }                // 50..59 - массив времени инерционности 
int Get_setup(int Num){ return ReadInt(Num+60); }                // 60..69 - массив флагов калибровки
                                                                 // 70..99 - резерв
                                                                 // 100..511 - свободно 

// ------------------- запись -------------------
int Set_signature(int value)        { WriteInt(0, value); }      // 0 - сигнатура
int Set_term_set(int value)         { WriteInt(1, value); }      // 1 - установленая температура
                                                                 // 2...9 - резерв
void Set_temp(int Num, int value)  { WriteInt(Num+10, value); }  // 10..19 - массив калибровочных температур
void Set_pow(int Num, int value)   { WriteInt(Num+20, value); }  // 20..29 - массив мощности поддержания температуры
void Set_tep(int Num, int value)   { WriteInt(Num+30, value); }  // 30..39 - массив температур инерционности
void Set_dt(int Num, int value)    { WriteInt(Num+40, value); }  // 40..49 - массив времени цикла on/off 
void Set_step(int Num, int value)  { WriteInt(Num+50, value); }  // 50..59 - массив времени инерционности 
void Set_setup(int Num, int value) { WriteInt(Num+60, value); }  // 60..69 - массив флагов калибровки
                                                                 // 70..99 - резерв
                                                                 // 100..511 - свободно 


 

 

 

bad_user
Offline
Зарегистрирован: 13.11.2015

попробуйте так:

 В сетапе

  
  PRE_FLOW_M = EEPROM.get(0);
  OVER_FLOW_M = EEPROM.get(2);
  PRE_FLOW_T = EEPROM.get(4);
  OVER_FLOW_T = EEPROM.get(6);
  PRE_FLOW_P = EEPROM.get(8);
  OVER_FLOW_P = EEPROM.get(10);
  Time_Weld = EEPROM.get(12);

Действие по нажатию кнопки записи

for (int i = 0; i < 512; i++)    
    {EEPROM.write(i, 0);}
  EEPROM.put(0,PRE_FLOW_M);
  EEPROM.put(2,OVER_FLOW_M);
  EEPROM.put(4,PRE_FLOW_T);
  EEPROM.put(6,OVER_FLOW_T);
  EEPROM.put(8,PRE_FLOW_P);
  EEPROM.put(10,OVER_FLOW_P);
  EEPROM.put(12,Time_Weld);

 

 

bad_user
Offline
Зарегистрирован: 13.11.2015

sivanko пишет:

 

for (int i = 0; i < 512; i++)
    {EEPROM.write(i, 0);}

 это, кстати, не обязательно и можно убрать

sivanko
Offline
Зарегистрирован: 25.02.2016

bad_user пишет:

попробуйте так:

 В сетапе

  
  PRE_FLOW_M = EEPROM.get(0);
  OVER_FLOW_M = EEPROM.get(2);
  PRE_FLOW_T = EEPROM.get(4);
  OVER_FLOW_T = EEPROM.get(6);
  PRE_FLOW_P = EEPROM.get(8);
  OVER_FLOW_P = EEPROM.get(10);
  Time_Weld = EEPROM.get(12);

Действие по нажатию кнопки записи

for (int i = 0; i < 512; i++)    
    {EEPROM.write(i, 0);}
  EEPROM.put(0,PRE_FLOW_M);
  EEPROM.put(2,OVER_FLOW_M);
  EEPROM.put(4,PRE_FLOW_T);
  EEPROM.put(6,OVER_FLOW_T);
  EEPROM.put(8,PRE_FLOW_P);
  EEPROM.put(10,OVER_FLOW_P);
  EEPROM.put(12,Time_Weld);

 

 

Пишет error: 'class EEPROMClass' has no member named 'get'

bad_user
Offline
Зарегистрирован: 13.11.2015

 

Сорри, запарился... так должно работать

 В сетапе

  
 EEPROM.get(0, PRE_FLOW_M);
 EEPROM.get(2, OVER_FLOW_M);
 EEPROM.get(4, PRE_FLOW_T);
 EEPROM.get(6, OVER_FLOW_T);
 EEPROM.get(8, PRE_FLOW_P);
 EEPROM.get(10, OVER_FLOW_P);
 EEPROM.get(12, Time_Weld);

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

sivanko  , прочитай внимательно http://arduino.ru/forum/programmirovanie/zapis-i-chtenie-eeprom-peremennykh-tipa-float-unsigned-long-long-unsigned-int

и дай размерности 7-ми переменных , которые 6 интовых и 1 флоатная :)

не парся - там всё просто....

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

Не понимаю, зачем все эти хитрожопости?

Ну есть же высокоуровневые макросы put и get. Так и пользуйтесь на здоровье.

double f;
int n;

// чтение
EEPROM.get (0, f );
EEPROM.get (2, n );

// запись
EEPROM.put (0, f );
EEPROM.put (2, n );

нафига лезть во внутренне представление чисел, особенно если его не знаешь?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
// чтение
PRE_FLOW_M =  EEPROM.read(0);
OVER_FLOW_M = EEPROM.read(1);
PRE_FLOW_T =  EEPROM.read(2);
OVER_FLOW_T = EEPROM.read(3);
PRE_FLOW_P =  EEPROM.read(4);
OVER_FLOW_P = EEPROM.read(5);
Time_Weld =   EEPROM.read(6);
// запись
for (int i = 0; i < 512; i++) // не получится - разная длина полей для переменных !!!!!!!!!
    EEPROM.write(i, 0);
  EEPROM.write(0,PRE_FLOW_M);
  EEPROM.write(1,OVER_FLOW_M);
  EEPROM.write(2,PRE_FLOW_T);
  EEPROM.write(3,OVER_FLOW_T);
  EEPROM.write(4,PRE_FLOW_P);
  EEPROM.write(5,OVER_FLOW_P);
  EEPROM.write(6,Time_Weld);
// покажи какие переменные интовые и какая флоатная ?

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

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

Не понимаю, зачем все эти хитрожопости?

Ну есть же высокоуровневые макросы put и get. Так и пользуйтесь на здоровье.

double f;
int n;

// чтение
EEPROM.get (0, f );
EEPROM.get (2, n );

// запись
EEPROM.put (0, f );
EEPROM.put (2, n );

нафига лезть во внутренне представление чисел, особенно если его не знаешь?

а не лучше ли именно изучить внутренне представление чисел и писать-читать что нам угодно ?
моя искренне удивлён Вашему посту :)-

sivanko
Offline
Зарегистрирован: 25.02.2016

SU-27-16 пишет:

// чтение
PRE_FLOW_M =  EEPROM.read(0);
OVER_FLOW_M = EEPROM.read(1);
PRE_FLOW_T =  EEPROM.read(2);
OVER_FLOW_T = EEPROM.read(3);
PRE_FLOW_P =  EEPROM.read(4);
OVER_FLOW_P = EEPROM.read(5);
Time_Weld =   EEPROM.read(6);
// запись
for (int i = 0; i < 512; i++) // не получится - разная длина полей для переменных !!!!!!!!!
    EEPROM.write(i, 0);
  EEPROM.write(0,PRE_FLOW_M);
  EEPROM.write(1,OVER_FLOW_M);
  EEPROM.write(2,PRE_FLOW_T);
  EEPROM.write(3,OVER_FLOW_T);
  EEPROM.write(4,PRE_FLOW_P);
  EEPROM.write(5,OVER_FLOW_P);
  EEPROM.write(6,Time_Weld);
// покажи какие переменные интовые и какая флоатная ?

 

Последняя - флоат

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

ЕвгенийП ,   извини , но я не знаю .get и .put , к сожалению.....
эти методы умееют сами вычислять смещение в зависимости от типа переменной ?
мне проще всё рассчитать - где что - потом читать-записывать....
в чём преимущество .get и .put ?
спасибо :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

sivanko пишет:

SU-27-16 пишет:

// чтение
PRE_FLOW_M =  EEPROM.read(0);
OVER_FLOW_M = EEPROM.read(1);
PRE_FLOW_T =  EEPROM.read(2);
OVER_FLOW_T = EEPROM.read(3);
PRE_FLOW_P =  EEPROM.read(4);
OVER_FLOW_P = EEPROM.read(5);
Time_Weld =   EEPROM.read(6);
// запись
for (int i = 0; i < 512; i++) // не получится - разная длина полей для переменных !!!!!!!!!
    EEPROM.write(i, 0);
  EEPROM.write(0,PRE_FLOW_M);
  EEPROM.write(1,OVER_FLOW_M);
  EEPROM.write(2,PRE_FLOW_T);
  EEPROM.write(3,OVER_FLOW_T);
  EEPROM.write(4,PRE_FLOW_P);
  EEPROM.write(5,OVER_FLOW_P);
  EEPROM.write(6,Time_Weld);
// покажи какие переменные интовые и какая флоатная ?

 

Последняя - флоат

ты не учёл смещение адресов в зависимости от типа переменной....
...и не прочитал ссылку , скорее всего

пока советовать не буду....
...жду решения сэнсея :)

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

SU-27-16 пишет:

а не лучше ли именно изучить внутренне представление чисел и писать-читать что нам угодно ?

А какова цель? Изучить внутренне представление чисел? Тогда, конечно лучше. А если цель - сделать проект, так лучше пользовать эти макросы и писать/читать всё, что нам угодно - они понимают любые типы данных, включая стуктуры и классы. Единствееное, что надо помнить, если тип - указатель, то они указатель и запишут, а вовсе не содержимое.

vde69
Offline
Зарегистрирован: 10.01.2016

по идее они кросс платформеные, то есть не зависящие от физической длины типов... все это в теории и на ПК хорошо, но на узкозаточеном софте только накладные расходы....

vde69
Offline
Зарегистрирован: 10.01.2016

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

МНЕ ПРОЩЕ И ПОНЯТНЕЕ ТАК :

// чтение
PRE_FLOW_M =  EEPROM.read(0);
OVER_FLOW_M = EEPROM.read(2);
PRE_FLOW_T =  EEPROM.read(4);
OVER_FLOW_T = EEPROM.read(6);
PRE_FLOW_P =  EEPROM.read(8);
OVER_FLOW_P = EEPROM.read(10);
Time_Weld =   EEPROM.read(12);
// ВАЖНО !!!!!!!!!! СЛЕДУЮЩИЙ СВОБОДНЫЙ АДРЕС = 16 !!!!!!!!!!!!
// запись
  EEPROM.write(0,PRE_FLOW_M);
  EEPROM.write(2,OVER_FLOW_M);
  EEPROM.write(4,PRE_FLOW_T);
  EEPROM.write(6,OVER_FLOW_T);
  EEPROM.write(8,PRE_FLOW_P);
  EEPROM.write(10,OVER_FLOW_P);
  EEPROM.write(12,Time_Weld);

 

vde69
Offline
Зарегистрирован: 10.01.2016

это если у тебя чтение и запись только в одном месте... а попробуй сделай чтение в 5 разных местах... вот тут и задумаешся...

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

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

SU-27-16 пишет:

а не лучше ли именно изучить внутренне представление чисел и писать-читать что нам угодно ?

А какова цель? Изучить внутренне представление чисел? Тогда, конечно лучше. А если цель - сделать проект, так лучше пользовать эти макросы и писать/читать всё, что нам угодно - они понимают любые типы данных, включая стуктуры и классы. Единствееное, что надо помнить, если тип - указатель, то они указатель и запишут, а вовсе не содержимое.

Спасибо !
в #16 мой код....
твой можно ? 
посредством .get и .put - для сравнения-понимания ?
я вовсе не спорщик :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

vde69 пишет:

это если у тебя чтение и запись только в одном месте... а попробуй сделай чтение в 5 разных местах... вот тут и задумаешся...

дык , примером можешьминя убить ?
шутка.... пока не изучил эти методы - я тупой !
спасибо

vde69
Offline
Зарегистрирован: 10.01.2016

SU-27-16 пишет:

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

SU-27-16 пишет:

а не лучше ли именно изучить внутренне представление чисел и писать-читать что нам угодно ?

А какова цель? Изучить внутренне представление чисел? Тогда, конечно лучше. А если цель - сделать проект, так лучше пользовать эти макросы и писать/читать всё, что нам угодно - они понимают любые типы данных, включая стуктуры и классы. Единствееное, что надо помнить, если тип - указатель, то они указатель и запишут, а вовсе не содержимое.

Спасибо !
в #16 мой код....
твой можно ? 
посредством .get и .put - для сравнения-понимания ?
я вовсе не спорщик :)

 

мой код http://arduino.ru/forum/programmirovanie/zapis-i-chtenie-eeprom#comment-184477

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

vde69 пишет:

это если у тебя чтение и запись только в одном месте... а попробуй сделай чтение в 5 разных местах... вот тут и задумаешся...

согласен..... до таких задач ещё не дошёл.....
но ведь можно для каждой переменной прописать адрес через #define и использовать ?

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

SU-27-16 пишет:

ЕвгенийП ,   извини , но я не знаю .get и .put , к сожалению.....
эти методы умееют сами вычислять смещение в зависимости от типа переменной ?
мне проще всё рассчитать - где что - потом читать-записывать....
в чём преимущество .get и .put ?
спасибо :)

Смещение не умеют. Адреса надо задавть самому.

Преимущество их в том, что они единообразно работают с любыми типами данных.

Например:

#include	<EEPROM.h>

//
//	имеем конфигурацию нашей супер-пупер программы
//
struct MySuperPuperProgramConfig {
	double	voltage;
	int	amount;
	char IPAddr[15];
	uint8_t	pin_Number;
} my_config;

//
//	Кроме конфигурации в EEPROM ещё сидит
//	1) какая-фигня 64-битная целая
//	2) какая-то хрень типа double
//	
long long figna;
double	hren;

//
//	Задаём адреса в EEPROM
//
#define	START_ADDRESS	4
#define	CONFIG_ADDRESS	START_ADDRESS
#define	FIGNA_ADDRESS (CONFIG_ADDRESS + sizeof(my_config)) 
#define	HREN_ADDRESS (FIGNA_ADDRESS + sizeof(figna)) 

//
//	Вот так читаем
//
void readAll(void) {
	EEPROM.get(CONFIG_ADDRESS, my_config);
	EEPROM.get(FIGNA_ADDRESS, figna);
	EEPROM.get(HREN_ADDRESS, hren);
}

//
//	Вот так пишем
//
void storeAll(void) {
	EEPROM.put(CONFIG_ADDRESS, my_config);
	EEPROM.put(FIGNA_ADDRESS, figna);
	EEPROM.put(HREN_ADDRESS, hren);
}

Заметьте, мы пишем и читаем одинаково, независимо от того, что там - сверхдлинное целое, плавающее или разлапистая структура. И в этом и есть ценность метода!

Да, кстати, а если читать/писать надо побайтно, то почему не использовать EEPROM как массив? Вот так:

byte b = EEPROM[10];
EEPROM[10] = b + 1;

Разве это не читабельнее, чем использовать отдельные функции,

vde69
Offline
Зарегистрирован: 10.01.2016

SU-27-16 пишет:

vde69 пишет:

это если у тебя чтение и запись только в одном месте... а попробуй сделай чтение в 5 разных местах... вот тут и задумаешся...

согласен..... до таких задач ещё не дошёл.....
но ведь можно для каждой переменной прописать адрес через #define и использовать ?

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

опытные программисты сами так делают, новичкам обычно такие вещи возвращают на переделку....

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

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

SU-27-16 пишет:

ЕвгенийП ,   извини , но я не знаю .get и .put , к сожалению.....
эти методы умееют сами вычислять смещение в зависимости от типа переменной ?
мне проще всё рассчитать - где что - потом читать-записывать....
в чём преимущество .get и .put ?
спасибо :)

Смещение не умеют. Адреса надо задавть самому.

Преимущество их в том, что они единообразно работают с любыми типами данных.

Например:

#include	<EEPROM.h>

//
//	имеем конфигурацию нашей супер-пупер программы
//
struct MySuperPuperProgramConfig {
	double	voltage;
	int	amount;
	char IPAddr[15];
	uint8_t	pin_Number;
} my_config;

//
//	Кроме конфигурации в EEPROM ещё сидит
//	1) какая-фигня 64-битная целая
//	2) какая-то хрень типа double
//	
long long figna;
double	hren;

//
//	Задаём адреса в EEPROM
//
#define	START_ADDRESS	4
#define	CONFIG_ADDRESS	START_ADDRESS
#define	FIGNA_ADDRESS (CONFIG_ADDRESS + sizeof(my_config)) 
#define	HREN_ADDRESS (FIGNA_ADDRESS + sizeof(figna)) 

//
//	Вот так читаем
//
void readAll(void) {
	EEPROM.get(CONFIG_ADDRESS, my_config);
	EEPROM.get(FIGNA_ADDRESS, figna);
	EEPROM.get(HREN_ADDRESS, hren);
}

//
//	Вот так пишем
//
void storeAll(void) {
	EEPROM.put(CONFIG_ADDRESS, my_config);
	EEPROM.put(FIGNA_ADDRESS, figna);
	EEPROM.put(HREN_ADDRESS, hren);
}

Заметьте, мы пишем и читаем одинаково, независимо от того, что там - сверхдлинное целое, плавающее или разлапистая структура.

Да, кстати, а если читать/писать надо побайтно, то почему не использовать EEPROM как массив? Вот так:

byte b = EEPROM[10];
EEPROM[10] = b + 1;

Разве это не читабельнее, чем использовать отдельные функции,

согласен....
но ты же в дефайнах прописал смещение !
по моему - это тоже самое что прописать каждой переменной свой адрес дефайново,
а смещение можно задать всегда....
...это я сам с собом - тибя надо вдумчиво читать.....

не согласен - figna...... не читается....
fignja или fu....ja - тибе виднее , твои переменные.....
спасибо обоим !!!!!! пойду "курить"

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Заметьте, мы пишем и читаем одинаково, независимо от того, что там - сверхдлинное целое, плавающее или разлапистая структура. И в этом и есть ценность метода!

воооооот , сформулировал вопрос - а ты уже и отвечал.....

метод пишет-читает любой тип !
а следующий свободный адрес он не вычисляет же ? надопросчитать ручками ? так ?

 

sivanko
Offline
Зарегистрирован: 25.02.2016

Пробовал с get и put.... Ругается на get

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

vde69 пишет:

SU-27-16 пишет:

vde69 пишет:

это если у тебя чтение и запись только в одном месте... а попробуй сделай чтение в 5 разных местах... вот тут и задумаешся...

согласен..... до таких задач ещё не дошёл.....
но ведь можно для каждой переменной прописать адрес через #define и использовать ?

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

опытные программисты сами так делают, новичкам обычно такие вещи возвращают на переделку....

 

спасибо :)
мине переделывать-то нечего :(
так - для знакомых чёта кодю....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

sivanko пишет:

Пробовал с get и put.... Ругается на get

молодец что вернулся , а то подумал что я как слон в посудной лавке :)

sivanko
Offline
Зарегистрирован: 25.02.2016

та тута я

 

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

sivanko пишет:

Пробовал с get и put.... Ругается на get

Версия IDE? Это появилось не так давно. В 1.6.5 точно есть

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

вот и я истчЮ....
http://arduino.ru/Reference/Library/EEPROM

нету там такого :(

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

SU-27-16 пишет:

вычисляет же ? надопросчитать ручками ? так ?

Нет, не вычисляет. Можно присобачить самому, только зачем?

Упрщение здесь не за счёт адреса, а за счёт того, не надо побайтово читать числа или там масивы - сам прочитает.

sivanko
Offline
Зарегистрирован: 25.02.2016

1.0.5

Щас попробую поновее

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

SU-27-16 пишет:

вот и я истчЮ....
http://arduino.ru/Reference/Library/EEPROM

нету там такого :(

Ну, Вы нашли где искать. Здесь со времён всемирного потопа ничего не менялось.

Смотрите на официальном сайте - https://www.arduino.cc/en/Reference/EEPROM

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

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

SU-27-16 пишет:

вычисляет же ? надопросчитать ручками ? так ?

Нет, не вычисляет. Можно присобачить самому, только зачем?

Упрщение здесь не за счёт адреса, а за счёт того, не надо побайтово читать числа или там масивы - сам прочитает.

твоя экспертная оценка - мой код имеет место быть ? ( так , для самоуспокоения )

главный вопрос :
ведь можно же прописать функцию записи в EEPROM , например структуры , со входными параметрами 
адрес ( куда писать ) и ссылка на структуру ( что писать ) ?

CPP могуч же ?
спасибо

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

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

SU-27-16 пишет:

вот и я истчЮ....
http://arduino.ru/Reference/Library/EEPROM

нету там такого :(

Ну, Вы нашли где искать. Здесь со времён всемирного потопа ничего не менялось.

Смотрите на официальном сайте - https://www.arduino.cc/en/Reference/EEPROM

пардон ! вроде бы пэнсионеры договаривались на ТЫ ?
извините....

там не был - спасибо ! :)

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

SU-27-16 пишет:

твоя экспертная оценка - мой код имеет место быть ? ( так , для самоуспокоения )

Конечно имеет, а чего не имеет-то?

SU-27-16 пишет:

главный вопрос :

ведь можно же прописать функцию записи в EEPROM , например структуры , со входными параметрами 
адрес ( куда писать ) и ссылка на структуру ( что писать ) ?

CPP могуч же ?
спасибо

Можно, конечно, но это не соответсвуюет духу языка. Для структуры (как и для любого другого класса) правильнее написать не внешнюю функцию, а метод. Тогда параметром будет только адрес. Что писать - и так понятно.

Такой подход более универсальный, чем тот макрос, который я тут рекламировал потому, что он определяет не только что и куда писать, а заодно и "как писать".

Последнее важно. Помните мой пример с указателем? Так вот в методе можно это отрабоать, чтобы писалось именно то, что реально нужно. Ну и вообще, половина полей структуры, возможно, не нуждается в постоянном хранении. Т.е. методы чтения/записи в структуре/классе как раз бы и определелил что и как надо записывать или считывать.

P.S. Вы меня с кем-то путаете, я никогда ни с кем не договаривался о переходе на ты. Я этого никогда не делаю. На ты я называю своих родственников и ближайших друзей (таковой у меня ровно один) и больше никого.

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

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

SU-27-16 пишет:

твоя экспертная оценка - мой код имеет место быть ? ( так , для самоуспокоения )

Конечно имеет, а чего не имеет-то?

SU-27-16 пишет:

главный вопрос :

ведь можно же прописать функцию записи в EEPROM , например структуры , со входными параметрами 
адрес ( куда писать ) и ссылка на структуру ( что писать ) ?

CPP могуч же ?
спасибо

Можно, конечно, но это не соответсвуюет духу языка. Для структуры (как и для любого другого класса) правильнее написать не внешнюю функцию, а метод. Тогда параметром будет только адрес. Что писать - и так понятно.

Такой подход более универсальный, чем тот макрос, который я тут рекламировал потому, что он определяет не только что и куда писать, а заодно и "как писать".

Последнее важно. Помните мой пример с указателем? Так вот в методе можно это отрабоать, чтобы писалось именно то, что реально нужно. Ну и вообще, половина полей структуры, возможно, не нуждается в постоянном хранении. Т.е. методы чтения/записи в структуре/классе как раз бы и определелил что и как надо записывать или считывать.

P.S. Вы меня с кем-то путаете, я никогда ни с кем не договаривался о переходе на ты. Я этого никогда не делаю. На ты я называю своих родственников и ближайших друзей (таковой у меня ровно один) и больше никого.

 

спасибо и извините....

Последнее важно. Помните мой пример с указателем? Так вот в методе можно это отрабоать, чтобы писалось именно то, что реально нужно. Ну и вообще, половина полей структуры, возможно, не нуждается в постоянном хранении. Т.е. методы чтения/записи в структуре/классе как раз бы и определелил что и как надо записывать или считывать.

Тут понятно.... спасибо Вашим урокам !

Пока крайний вопрос :
если пишем предельное кол-во раз в адрес 10 , например....
то откажет память по адресу 10 или ВСЯ EEPROM ? 

 

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

SU-27-16 пишет:

если пишем предельное кол-во раз в адрес 10 , например....

то откажет память по адресу 10 или ВСЯ EEPROM ? 

Сам бы хотел знать. Но я не электронщик ни разу, а только программист :(

Надеюсь, кто-нибудь ответит. А если нет, завтра буду на работе, там есть у кого спросить - отпишусь.

vde69
Offline
Зарегистрирован: 10.01.2016

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

SU-27-16 пишет:

если пишем предельное кол-во раз в адрес 10 , например....

то откажет память по адресу 10 или ВСЯ EEPROM ? 

Сам бы хотел знать. Но я не электронщик ни разу, а только программист :(

Надеюсь, кто-нибудь ответит. А если нет, завтра буду на работе, там есть у кого спросить - отпишусь.

зависит от реализации флеша, в ардуинке скорее всего вся память прейдет в режим Read-Only...

sivanko
Offline
Зарегистрирован: 25.02.2016

Ура, я победил проблему. Обновил ИДЕ, дал адреса 10, 20,30... чтобы с запасом. Использовал get и put. И все заработало!!! Спасибо всем откликнувшимся.

П.С. Почему я не знал про ардуино 3 года назад, когда делал сварку-полуавтомат. Теперь будет 4 в 1 (MMA, MIG, TIG и плазморез в одном флаконе) под управлением ардуинки.

Logik
Offline
Зарегистрирован: 05.08.2014

vde69 пишет:

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

SU-27-16 пишет:

если пишем предельное кол-во раз в адрес 10 , например....

то откажет память по адресу 10 или ВСЯ EEPROM ? 

Сам бы хотел знать. Но я не электронщик ни разу, а только программист :(

Надеюсь, кто-нибудь ответит. А если нет, завтра буду на работе, там есть у кого спросить - отпишусь.

зависит от реализации флеша, в ардуинке скорее всего вся память прейдет в режим Read-Only...

Не. Одна ячейка глючить начнет. 

С ЕЕПРОМ работаю так.

В проекте есть структура данных для ЕЕПРОМ, наприме (из живого проекта выдрано) Она глобальная, в проекте одна и имя фиксированое, описывает весь ЕЕПРОМ, который использован.

typedef struct  EEPROM_STUCT
{
     OneWareDevID DevID[EEPROM_STUCT_DEV_ID_NUMBER];

     TimerInterval TimerIntervals[EEPROM_STUCT_TIMER_INTERVALS_NUMBER];
     byte ExtOutValueON[EEPROM_STUCT_EXT_OUT_NUMBER];             //уровень ШИМ при включенном состоянии
     byte ExtOutTimersMask[EEPROM_STUCT_EXT_OUT_NUMBER];
     byte ExtOutOptions[EEPROM_STUCT_EXT_OUT_NUMBER];               //набор флагов, определяющих специфику устройства
 } ;

В библиотеках макросы и функции

#define offsetof(st, m) ((size_t)(&((st *)0)->m))

#define EEPROM(a)   ((byte)offsetof(EEPROM_STUCT,a))

#define EEPROM_WRITE(adr,val) WriteBlockToEEPROM(EEPROM(adr), &val, sizeof(val));
#define EEPROM_READ(adr,val)  ReadBlockFromEEPROM(EEPROM(adr), &val, sizeof(val));

//*******************************************************************************************
//  Блочная работа с EEPROM

boolean ReadBlockFromEEPROM(byte adr, void* d, byte l)
{
  byte t;
  byte res=true;
   for(byte i=0;i<l;i++,adr++)
   {
     t=EEPROM.read(adr);
     if(d) ((byte*)d)[i]=t;
     if (t!=0xff) 
       res= false;
   }
   return res;
}

void WriteBlockToEEPROM(byte adr, void* d, byte l)
{
   for(byte i=0;i<l;i++,adr++)
   {
     if(EEPROM.read(adr)!=((byte*)d)[i])
       EEPROM.write(adr,((byte*)d)[i]); 
   }
}

Обратите внимание, что чтение возвращает true если вся переменная в 0xff. Это означает что переменная не инициализирована или свободн, соответственно имеем заодно и поиск незанятой записи. Запись с проверкой необходимости её, это достаточно быстро и позволяет не парится с износом памяти при частом перезаписывании.

Ну и работа типа

           byte opt;
           EEPROM_READ(ExtOutOptions[SelectOutDevID], opt);

            opt&=~EXT_OUT_OPT_SMOOTHLY;  
            
           EEPROM_WRITE(ExtOutOptions[SelectOutDevID], opt);

 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

О, кстати спрошу тоже: EEPROM имеет ограничение типа в 100тыс. записей .. Флеш, по сути такая же "еепром", но в ТТХ на микросхемы почему-то прописано только 10тыс. циклов, что несколько напрягает (меня конкретно, ибо обучение и заливок много).

Это "перестраховка" производителя и на самом деле теже 100тыс (как и на отдельных микросхемах флеш-памяти) или таки на порядок меньше по каким-то причинам? Уже год задаюсь этим вопросом и не могу найти ответ .. может подскажете?

А, если флеш память дунек тоже держит 100тыщ .. то почему её тоже не пользовать как еепром? Команды чтения-записи есть .. можно же писать "самомодифицирующийся код" по идее .. не?

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

Arhat109-2 пишет:

Это "перестраховка" производителя и на самом деле теже 100тыс 

Представитель Atmel в России ответил, что нет, действительно: с гарантией 10 тыс.

Другое дело, что если в среднем по заливке в день, то это 27 лет!  А оно ведь так и бывает в какой-то день 10 заливок, а какие-то ни одной.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Упс..

Logik
Offline
Зарегистрирован: 05.08.2014

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

Arhat109-2 пишет:

Это "перестраховка" производителя и на самом деле теже 100тыс 

Представитель Atmel в России ответил, что нет, действительно: с гарантией 10 тыс.

Другое дело, что если в среднем по заливке в день, то это 27 лет!  А оно ведь так и бывает в какой-то день 10 заливок, а какие-то ни одной.

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

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

Logik пишет:

Если активно отлаживается то и десяток заливок в час да на 5 часов

А думать когда? Или "не наш метод"? :)))))))

Logik
Offline
Зарегистрирован: 05.08.2014

я ж написал отлаживать 5 часов! Дольше нельзя и не получится. Думать 24-5=19 часов. "Элементарно Ватсон" ;))

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

Logik пишет:

я ж написал отлаживать 5 часов! Дольше нельзя и не получится. Думать 24-5=19 часов. "Элементарно Ватсон" ;))

Понято, значит 5 часов дрыганий в стиле "чё думать, трясти надо!", а потом на диван и думатель включать! :)))))

Logik
Offline
Зарегистрирован: 05.08.2014

Именно так. Идеи рождаются не за компом. За компом они оформляются в код и 5 часов на то чтоб добится соответствия реализации и замысла как раз. Вобще реально рабочий день разработчика ПО 4-5 часов, это уже сто раз обсуждалось. А думать он не перестает все 19 часов. )))