ARDUINO Не работает EEPROM

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Доброго дня.
Дошли руки до освоения EEPROM. Изучив уроки Алекса, накидал несколько строчек, но компилятор говорит что нет таких функций в библиотеке (((
ВОт что пишет VScode :

template<class T> const T &EEPROMClass::put(int idx, const T &t)
отсутствуют экземпляры шаблон функции "EEPROMClass::put", соответствующие списку аргументов -- типы аргументов: (uint16_t *, int) -- тип объекта: EEPROMClass



в шапке накидал параметры для сохранения:
#include <Arduino.h>
#include <GyverButton.h>
#include <AccelStepper.h>
#include <GyverTimer.h>
#include <EEPROM.h>


//******* EEPROM******
uint16_t EEMEM r_D1;
uint16_t EEMEM r_D2;
uint16_t EEMEM p_Set;
int32_t EEMEM step_M;
uint8_t EEMEM w_Mode;
uint32_t EEMEM vol_D1;
uint32_t EEMEM vol_D2;
#define INIT_ADDR 1023
#define INIT_KEY 50

void setup {
if (EEPROM.read(INIT_ADDR) != INIT_KEY) { // первый запуск
EEPROM.write(INIT_ADDR, INIT_KEY); // записали ключ
// записали параметры, потом их записали

BackupWrite();
BackupRead();
}else{
BackupRead();
}

// Пишем первые минимальные параметры, типа "настройки по умолчанию" *************************************
void BackupWrite(){
EEPROM.put(&r_D1, 100);
EEPROM.put(&r_D2, 10);
EEPROM.put(&p_Set, 5);
EEPROM.put(&step_M, 100);
EEPROM.put(&w_Mode, 0);
EEPROM.put(&vol_D1, 0);
EEPROM.put(&vol_D2,0);
}
//Восстановить параметры из EEPROM
void BackupRead(){
uint32_t tmp;
EEPROM.get(&r_D1, tmp);
CapCap.setRate(tmp, true);
EEPROM.get(&r_D2, tmp);
CapCap.setRate(tmp, false);
EEPROM.get(&p_Set, CapCap.rD1_percent);
EEPROM.get(&step_M, tmp);
stepper2.setCurrentPosition(tmp);
EEPROM.get(&w_Mode, workMode);
EEPROM.get(&vol_D1, CapCap.cntDrops1);
EEPROM.get(&vol_D2, CapCap.cntDrops2);
}

viod loop{}


Какие могут быть варианты? Уже мозг набекрень(((
В какую сторону копать впринципе, при такой ошибке ?
 
Изменено:

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Может угловые скобки в инклудах надо заменить на обычные двойные кавычки?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Я вот специально , ради интереса, открыл ардуину иде и скопировал туда код - и ошибка на ошибке. И скорее всего из за того, что код не оформлен как код.

И самое главное.. при записи в еепром надо сначала писать адрес, а потом переменную
template< typename T > const T &put( int idx, const T &t ){
 
Изменено:

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Я вот специально , ради интереса, открыл ардуину иде и скопировал туда код - и ошибка на ошибке. И скорее всего из за того, что код не оформлен как код.
Я не говорил что это рабочий код - тут только не рабочий кусок. Зачем писать 1500 рабочих строчек , и 3 строчки с ошибкой..
Главно, что какие функции ( get и put) использую и какая ошибка при этом, библиотеку подключил , как было прочитано, качать её не надо, при подключении EEPROM.h автоматически подключается avr/eeprom.h
Синтаксис строки без нареканий : EEPROM.put(&r_D1, 100);
адреса переменных функция EEMEM распределила автоматически, тут я точно не мог накосячить.

Полагаю что библиотека не совсем правильная, как будто.
Версия EEPROM 2.0 , кстати.

Давайте посмотрим что пишет компилятор :

src\main.cpp: In function 'void BackupWrite()':
src\main.cpp:205:34: error: no matching function for call to 'EEPROMClass::put(uint16_t*, uint16_t)'
EEPROM.put(&r_D1, 100);
^
In file included from src\main.cpp:6:0:
C:\Users\Couch\.platformio\packages\framework-arduino-avr\libraries\EEPROM\src/EEPROM.h:137:37: note: candidate: template<class T> const T& EEPROMClass::put(int, const T&)
template< typename T > const T &put( int idx, const T &t ){
^
C:\Users\Couch\.platformio\packages\framework-arduino-avr\libraries\EEPROM\src/EEPROM.h:137:37: note: template argument deduction/substitution failed:
src\main.cpp:205:34: note: cannot convert '& r_D1' (type 'uint16_t* {aka unsigned int*}') to type 'int'
EEPROM.put(&r_D1, 100);


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

Укоротил лишний код, оставил то будет работать в IDE:
#include <Arduino.h>
#include <EEPROM.h>

//void BackupWrite();
//void BackupRead();

//******* EEPROM******
uint16_t EEMEM r_D1;
#define INIT_ADDR 1023
#define INIT_KEY 50

void setup() {
if (EEPROM.read(INIT_ADDR) != INIT_KEY) { // первый запуск
EEPROM.write(INIT_ADDR, INIT_KEY); // записали ключ
// записали параметры, потом их записали
BackupWrite();
BackupRead();
}else{
BackupRead();
}
}

// Пишем первые минимальные параметры, типа "настройки по умолчанию" *************************************
void BackupWrite(){ EEPROM.put(&r_D1, 100);}

//Восстановить параметры из EEPROM
void BackupRead(){
uint32_t tmp;
EEPROM.get(&r_D1, tmp);
}

void loop(){}
 
Изменено:

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Может угловые скобки в инклудах надо заменить на обычные двойные кавычки?
Кавычки и уголки - это говорит компилятору лишь где искать эту библиотеку, дело не в них, но на всякий случай проверил - не помогло, как и ожидалось.
Библиотека на месте, весь синтксис написал как в уроке было описано. Урок по EEPROM
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Я так и записываю, сначала адрес, потом сразу пишу значение , которое надо записать по этому адресу.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
сначала адрес, потом сразу пишу значение
Тут тоже ?

/ Пишем первые минимальные параметры, типа "настройки по умолчанию" *************************************
void BackupWrite(){ EEPROM.put(&r_D1, 100);}

//Восстановить параметры из EEPROM
void BackupRead(){
uint32_t tmp;
EEPROM.get(&r_D1, tmp);
}

void loop(){}
C++:
#include <Arduino.h>
#include <EEPROM.h>

//void BackupWrite();
//void BackupRead();

//******* EEPROM******
uint16_t r_D1;
#define INIT_ADDR 1023
#define INIT_KEY 50

void setup() {
  if (EEPROM.read(INIT_ADDR) != INIT_KEY) { // первый запуск
    EEPROM.write(INIT_ADDR, INIT_KEY); // записали ключ
    // записали параметры, потом их записали
    BackupWrite();
    BackupRead();
  } else {
    BackupRead();
  }
}

// Пишем первые минимальные параметры, типа "настройки по умолчанию" *************************************
void BackupWrite() {
  EEPROM.put(100,r_D1);
}

//Восстановить параметры из EEPROM
void BackupRead() {
  uint32_t tmp;
  EEPROM.get(100,r_D1);
}

void loop() {}
 

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
@Mix_man, верно. Это разный способ поиска библиотек. И сам однажды на эти грабли наступал, когда имелась версия "встроенная в ИДЕ" и случайно обозвал также свою. Мне показалось что если укомпилятор пишет "отсутствует функция в библиотеке" то стоит смотреть какую библиотеку подключаете .. но у Вас там темплейт .. это может быть из иной оперы.
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
@Старик Похабыч,
Почему в твоём спойлере так написано? : EEPROM.put(100,r_D1);

100 - это не адрес ячейки, Бро... 100 - это значение которое надо будет написать по адресу &r_D1
Поэтому у меня написано вот так: EEPROM.put(&r_D1, 100);

отсюда алгоритм работы следующий:
Включили "мозги", проверяем EEPROM на непорченность, если мозги свежие, то пишем в них заводские настройки параметров:
void BackupWrite() {
EEPROM.put(100,r_D1);
//далее еще список
}
Затем читаем эти параметры в мой объект.

Иначе (настройки уже были записаны) сразу читаем настройки в объект.

Дальше там в ходе работы кода будет вестись запись текущей работы .
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Адрес это число! его не надо передавать ссылкой. просто числом. тогда пиши так
EEPROM.put(r_D1, 100);
То, что ты что то увидел и путаешь себя путает и других.
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
@Mix_man, верно. Это разный способ поиска библиотек. И сам однажды на эти грабли наступал, когда имелась версия "встроенная в ИДЕ" и случайно обозвал также свою. Мне показалось что если укомпилятор пишет "отсутствует функция в библиотеке" то стоит смотреть какую библиотеку подключаете .. но у Вас там темплейт .. это может быть из иной оперы.
Так и из какой ?


Похоже тип данных Адреса не правильно указан,
template< typename T > const T &put( int idx, const T &t )

А я пишу тип указателя , как у моих переменных .

Надо тут разобраться похоже.
 
  • Лойс +1
Реакции: Arhat109

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Адрес это число! его не надо передавать ссылкой. просто числом. тогда пиши так
EEPROM.put(r_D1, 100);
То, что ты что то увидел и путаешь себя путает и других.
Я щас не у компа, не могу проверить твою теорию в работе.
В уроке Алекса было чётко сказано, что в функцию put надо передать адрес переменной, которую распределила EEMEM , тобишь писать надо именно &r_D1.

Ты проверил , ошибка пропала если писать без оператора взятия адреса?

Я так понял EEMEM распределяет переменные которые я обозначил в памяти EEPROM друг за другом, в сооствествии с типом данных которые я указываю. они как бы теперь распределены по EEPROM но мы не знаем адресацию (знаем конечно как он распределяет, но мы с этим не мучаемся и не следим къебеням)

Поэтому и надо писать EEPROM.put(&r_D1, 100);
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Всё! Отбой похожэ. Это из разряда - смотришь в книгу видишь фигу. :oops::giggle:

Не туда посмотрел в уроке. Там как раз написано , что надо привести к целочисленному типу сперва.
EEPROM.put((int)&r_D1, 100);

Так будет работать.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Уж поверь мне, старому ветеринару.. (с)
Это не теория. Ты видимо путаешь адрес и указатель
EEMEM размещает переменную в памяти, это не всегда хорошо, т.к. изменяя переменную меняешь еепром, что пагубно сказывается на ее состоянии.
Но не важно. Посмотри урок еще раз. Для чтения и записи данных в ЕЕПРОМ, помеченных ЕЕМЕМ есть спец функции типа eeprom_write_byte и eeprom_read_byte.
Очень похоже на изобретение велосипеда. Но разбирайся
 
  • Лойс +1
Реакции: Arhat109

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Уж поверь мне, старому ветеринару.. (с)
Не, нифига. Акела промахнулся :ROFLMAO:;)

Не заметили вы простейшего, не познали еще дзэн разбирателя . А всё просто- компилятор всё написал, что ему не нравится. И стоило обратиться к источнику сразу была замечена ошибка.

EEPROM.put((int)&r_D1, 100);
Так будет работать.
И оно работает :)
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Да я видел, только нафига такой изваращенный способ ? И вот сейчас возник вопрос... когда определяется адрес положения вот этого r_D1 ? в какой момент ?
При изменении кода и новой компиляции будет тот же адрес ?
Я не против, нравиться - пожалуйста ) но чем плохо это?
C++:
byte EEMEM r_D1;
...
eeprom_write_byte (&r_D1 ,100)
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Да я видел, только нафига такой изваращенный способ ? И вот сейчас возник вопрос... когда определяется адрес положения вот этого r_D1 ? в какой момент ?
На сколько я понял, адресация раздаётся при компиляции, а уже после заливки , если в ходе работы не предусмотрено изменение адресов, то так и будет.
Этот способ очень удобен тем, что не надо парить мозги с адресацией, когда у меня 10 параметров... И данные разных типов.