EEPROM чтение и запись unsigned long

alexval2007
Offline
Зарегистрирован: 10.11.2012

Помогите разобратся с кодом, что то я напутал.

Написл функции чтения и записи 4х байтовой переменной unsigned long Значения 9600 передаётся нормально значение 115200 непойми что 4294951424

#include <EEPROM.h>
//*****************************************************
unsigned long q = 115200;
unsigned long w=0;
//*****************************************************
void EEPROM_write_unsigned_long(uint8_t i, unsigned long data);
int EEPROM_read_unsigned_long(uint8_t i);
//*****************************************************
void setup()
{
  Serial.begin(9600);
   EEPROM_write_unsigned_long(0, q); // пишим в EEPROM 4 байта
   w = EEPROM_read_unsigned_long(0); // читаем из EEPROM 4 байта
  Serial.print(w);
} 
//****************************************************************
  void EEPROM_write_unsigned_long(uint8_t i, unsigned long data)// Для записи 4х байтовго значения пишим номер ячейки первого байта
  {                                                             // и переменную которую нужно сохранить далее функция разобёт переменную типа unsigned_long на 4 ячейки по одному байту и сохранит их.
    EEPROM.write(i, data & 0xFF); 
    EEPROM.write(i+1, (data & 0xFF00) >> 8); 
    EEPROM.write(i+2, (data & 0xFF0000) >> 16); 
    EEPROM.write(i+3, (data & 0xFF000000) >> 24);    
  }  
//*****************************************************************
  int EEPROM_read_unsigned_long(uint8_t i)// Для чтения 4х байтовго значения пишим номер ячейки первого байта 
  { // далее функция прочитает 4 ячейки по одному байту и соберет их в одну переменную типа unsigned long.
    unsigned long data = 0;
    byte val = EEPROM.read(i+3); 
    data = (data << 8) | val; 
    val = EEPROM.read(i+2); 
    data = (data << 8) | val; 
    val = EEPROM.read(i+1); 
    data = (data << 8) | val; 
    val = EEPROM.read(i); 
    data = (data << 8) | val;  
    return data;
  } 
//*****************************************************************
void loop()
{       
}
//*****************************************************************

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

скорее всего не успевает собрать 4 байта, попробуйте библиотеку EEPROM2

alexval2007
Offline
Зарегистрирован: 10.11.2012

спасибо обошолся стандартной библиотекой применил такое решение встретил на форуме 

#include <EEPROM.h>
//*****************************************************
unsigned long q = 115200;
unsigned long w=0;

unsigned long EEPROM_ulong_read(int addr);
void EEPROM_ulong_write(int addr, unsigned long data);
//*****************************************************
void setup()
{
  Serial.begin(9600);
  EEPROM_ulong_write(0, q); // запись в EEPROM 4 байта unsigned long
  w = EEPROM_ulong_read(0); // чтение из EEPROM 4 байта unsigned long
  Serial.print(w);          // Выводим результат в порт
} 
//*****************************************************************
unsigned long EEPROM_ulong_read(int addr) // чтение из EEPROM 4 байта unsigned long
{   
  byte raw[4];
  for(byte i = 0; i < 4; i++) raw[i] = EEPROM.read(addr+i);
  unsigned long &data = (unsigned long&)raw;
  return data;
}
//*****************************************************************
void EEPROM_ulong_write(int addr, unsigned long data) // запись в EEPROM 4 байта unsigned long
{
  byte raw[4];
  (unsigned long&)raw = data;
  for(byte i = 0; i < 4; i++) EEPROM.write(addr+i, raw[i]);
}
//*****************************************************************
void loop()
{       
}
//*****************************************************************

 

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

А почему не воспользоваться EEPROM.put() и EEPROM.get() ? Там вообще никаких проблем - можно просто long передавать и не париться.

alexval2007
Offline
Зарегистрирован: 10.11.2012

не в курсе данного варианта пример можно

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

alexval2007 пишет:

не в курсе данного варианта пример можно

https://www.arduino.cc/en/Tutorial/EEPROMGet - пример, где get'ом читают float'ы, а потом и структуру из 15 байтов одним вызовом функции.

https://www.arduino.cc/en/Tutorial/EEPROMPut - тот же пример, но не читают, а пишут.

alexval2007
Offline
Зарегистрирован: 10.11.2012

спасибо попробую

__Alexander
Offline
Зарегистрирован: 24.10.2012

у вас функция read возвращает int.

alexval2007
Offline
Зарегистрирован: 10.11.2012

а конкретней с цитатой где и что возвращяет и что должна а то я чтото неувидел.

__Alexander
Offline
Зарегистрирован: 24.10.2012

 int EEPROM_read_unsigned_long(uint8_t i)

сравните с кодом из второго вашего поста.

alexval2007
Offline
Зарегистрирован: 10.11.2012

ну если из второго то вот

unsigned long EEPROM_ulong_read(int addr) // чтение из EEPROM 4 байта unsigned long
{  
	  byte raw[4];
	  for(byte i = 0; i < 4; i++) raw[i] = EEPROM.read(addr+i);
	  unsigned long &data = (unsigned long&)raw;
	  return data;
}

если из первого
то вот
 

 int EEPROM_read_unsigned_long(uint8_t i)// Для чтения 4х байтовго значения пишим номер ячейки первого байта
      { // далее функция прочитает 4 ячейки по одному байту и соберет их в одну переменную типа unsigned long.
        unsigned long data = 0;
        byte val = EEPROM.read(i+3);
        data = (data << 8) | val;
        val = EEPROM.read(i+2);
        data = (data << 8) | val;
        val = EEPROM.read(i+1);
        data = (data << 8) | val;
        val = EEPROM.read(i);
        data = (data << 8) | val;
        return data;
    }

Я тут вижу что переменная

unsigned long data; а именно она возвращяется и там и там а то что вы показали переменная адреса вы считаете что ее тоже нужно увеличить до 4х байт
__Alexander
Offline
Зарегистрирован: 24.10.2012

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

alexval2007
Offline
Зарегистрирован: 10.11.2012

непонял возвращяем то unsigned long data;   а в функции int EEPROM_read_unsigned_long(uint8_t i)  uint8_t i адрес ячейки или же вы говорите что функция обявлена как int а должна быть обявлена как unsigned long

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

Именно это он и говорит уже полдня. Слово int перед функцией означает, что результатом работы функции является велична типа int. Вам это надо? Чтобы результат был int? Ну, тогда оставляйте как есть.

Кто Вам сказал, что Вы возвращаете unsigned long data? Глупости это всё. Функция возвращает в точности тот тип, который записан перед её именем в описании. А то что Вы пихаете в int'овый результат свою long'овую data, так это не страшно - она будет спокойненько обкорнана до int и возвращена.

__Alexander
Offline
Зарегистрирован: 24.10.2012

почитайте как объявляются и работает функции.

оператор return возвращает значение размерносью заданой в определении функции, и не важно как переменная была объявлена внутри функции. по остальному всё верно.

alexval2007
Offline
Зарегистрирован: 10.11.2012

Спасибо за разяснение незнал искал сам где почитать про return что он возвращяет из функции и как но подробно ненашол все както сжато теперь буду знать.

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

alexval2007 пишет:

Спасибо за разяснение незнал искал сам где почитать про return что он возвращяет из функции и как но подробно ненашол все както сжато теперь буду знать.

Как же Вы искали-то?

Давайте так, вот Вам книга - people.toiit.sgu.ru/Sinelnikov/PT/C/Kern_Ritch.pdf Прочитайте всю и разберите все примеры (запустите, поэкпериментируйте). И только после этого пытайтесь что-то программировать. Сразу же почувствуете разницу!

alexval2007
Offline
Зарегистрирован: 10.11.2012

за книгу спасибо почитаю

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

CyberLib работала..... http://istarik.ru/blog/arduino/1.html
  или гляньте новую от  Arhat109   http://cyber-place.ru/member.php?u=5117

odemma
Offline
Зарегистрирован: 21.11.2015

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

А почему не воспользоваться EEPROM.put() и EEPROM.get() ? Там вообще никаких проблем - можно просто long передавать и не париться.

Подскажите в чем проблема?

eeprom_write:18: error: 'class EEPROMClass' has no member named 'put'

код

#include <EEPROM.h>
 
void setup()
{
  int addr = 0;
  int val = 234;
    EEPROM.put(addr, val);
      Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.println("OK");
 
}
 
void loop()
{
   
}
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Проблема, наверное, в доисторической версии библиотеки. У меня Ваш пример нормально компилируется. Библиотека у меня ниоткуда не скачанная - стала вместе с IDE и я ничего в ней не менял. IDE у меня 1.6.5.

Вот описание функций put и get на официальном сайте Arduino (насколько в Arduino вообще что-то может быть официальным)

https://www.arduino.cc/en/Tutorial/EEPROMPut
https://www.arduino.cc/en/Tutorial/EEPROMGet

odemma
Offline
Зарегистрирован: 21.11.2015

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

Проблема, наверное, в доисторической версии библиотеки. У меня Ваш пример нормально компилируется. Библиотека у меня ниоткуда не скачанная - стала вместе с IDE и я ничего в ней не менял. IDE у меня 1.6.5.

Спасибо! помогло. Вроде и года не прошло как ставил, а уже устарела.