• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Отрицательное число int в EEPROM

mishgan

Member
Пробую писать отрицательные числа в eeprom. Пишу в память так
Код:
EEPROM.begin (30);
for (byte j = 0; j <=12 ; j++) {        
st[j]=atoi(pars_string (buff , "S"+String(j)));
byte hi = highByte(st[j]);
byte low = lowByte(st[j]);
EEPROM.write(j, hi); delay (5);
EEPROM.write(j+15, low);delay (5);
}
EEPROM.end();
а читаю так

Код:
EEPROM.begin (30);
for(int j = 0; j <=12 ; j++)  {
byte hi = EEPROM.read(j); delay (5);
byte low = EEPROM.read(j+15); delay (10);
st[j]= word(hi, low);  Serial1.println(st[j]);}
EEPROM.end();
если пишу отрицательное число, то на выходе получаю непонятно что.
Например -11 както преобразуется в 65525.
Что я не так делаю?
 

Сергей_Ф

Moderator
Команда форума
@mishgan не изобретайте велосипед
Arduino Playground - EEPROMWriteAnything
надо чуть чуть подправить для esp, в соответствии с вызовами eeprom для неё.

Код:
int my_data = -354;
const uint16_t eeprom_addr = 0;

uint16_t eeprom_end_addr;

eeprom_end_addr = eeprom_addr + EEPROM_writeAnything(eeprom_addr, my_data); // записываем

int data_from_eeprom;
EEPROM_readAnything(eeprom_addr, data_from_eeprom); //читаем
 
Последнее редактирование:

Юрий Ботов

Moderator
Команда форума
Что я не так делаю?
Все так делаешь.

Как хранятся в памяти отрицательные числа? Именно так в дополнительном коде.
то есть одни и теже 16 бит памяти если смотреть на них как на int это -11, а если смотреть на них же как на unsigned int то это 65525.

По примерам не видно кто такой st. Тип у него какой?
Если используешь отрицательные числа то видимо должен быть int16_t
 

Vypra

Member
@mishgan не изобретайте велосипед
Arduino Playground - EEPROMWriteAnything
надо чуть чуть подправить для esp, в соответствии с вызовами eeprom для неё.

Код:
int my_data = -354;
const uint16_t eeprom_addr = 0;

uint16_t eeprom_end_addr;

eeprom_end_addr = eeprom_addr + EEPROM_writeAnything(eeprom_addr, my_data); // записываем

int data_from_eeprom;
EEPROM_readAnything(eeprom_addr, data_from_eeprom); //читаем
Простите за некую некрофилию к теме 2016 года... но возникла проблема с записью int в EEPROM
Код:
#include <EEPROM.h>
#include <Arduino.h> 

void setup()
{
  Serial.begin (9600);

  int my_data = -11;
  const uint16_t eeprom_addr = 0;

  uint16_t eeprom_end_addr;

  eeprom_end_addr = eeprom_addr + EEPROM_writeAnything(eeprom_addr, my_data); // записываем

  Serial.print ("my_data:");
  Serial.println(my_data);

  int data_from_eeprom;
  EEPROM_readAnything(eeprom_addr, data_from_eeprom); //читаем
  Serial.print ("data_from_eeprom:");
  Serial.println(data_from_eeprom);
}

void loop()
{}


template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
  EEPROM.begin(512);
  delay(15);
  const byte* p = (const byte*)(const void*)&value;
  unsigned int i;
  for (i = 0; i < sizeof(value); i++)
    EEPROM.write(ee++, *p++);
  return i;
  EEPROM.commit();
}

template <class T> int EEPROM_readAnything(int ee, T& value)
{
  EEPROM.begin(512);
  delay(15);
  byte* p = (byte*)(void*)&value;
  unsigned int i;
  for (i = 0; i < sizeof(value); i++)
    *p++ = EEPROM.read(ee++);
  return i;
}
Результат:
my_data:-11
data_from_eeprom:-65392
 

Vypra

Member
Этот же код компильнул на работе, и был удивлен:
my_data:-11
data_from_eeprom:-1

Я не знаю почему, но вот так. Все равно не -11, а -1. Версия платы одна и та же, Arduino IDE 1.8.8. и там и там. Разница в компах только в том, что дома винда 7, на работе 10. ((((
 

Vypra

Member
Попробуйте подождать пока запишется.
Да. Нужно ждать. Получилось. Спасибо.
Код:
#include <EEPROM.h>
#include <Arduino.h>

void setup()
{
  Serial.begin (9600);

  int my_data = -11;
  const uint16_t eeprom_addr = 0;

  uint16_t eeprom_end_addr;

  eeprom_end_addr = eeprom_addr + EEPROM_writeAnything(eeprom_addr, my_data); // записываем

  Serial.print ("my_data:");
  Serial.println(my_data);

  int data_from_eeprom;
  EEPROM_readAnything(eeprom_addr, data_from_eeprom); //читаем
  Serial.print ("data_from_eeprom:");
  Serial.println(data_from_eeprom);
}

void loop()
{}


template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
  Serial.print ("value");
  Serial.println(value);

  const byte* p = (const byte*)(const void*)&value;
  unsigned int i;
  for (i = 0; i < sizeof(value); i++)
  {
    EEPROM.begin(512);
    EEPROM.write(ee++, *p++);
    delay(10);
    EEPROM.commit();
  }
  return i;
}


template <class T> int EEPROM_readAnything(int ee, T& value)
{
  {
    EEPROM.begin(512);
    delay(15);
    byte* p = (byte*)(void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
    {
      *p++ = EEPROM.read(ee++);
      delay(10);
    }
    return i;
  }
}
 

Vypra

Member
так вы дыру в памяти протрете, вынесите за цикл.
Посмотрели бы пример как делают авторы.
esp8266/Arduino
Код:
#include <EEPROM.h>
#include <Arduino.h>

void setup()
{
  Serial.begin (9600);

  int my_data = -11;
  const uint16_t eeprom_addr = 0;

  uint16_t eeprom_end_addr;

  eeprom_end_addr = eeprom_addr + EEPROM_writeAnything(eeprom_addr, my_data); // записываем

  Serial.print ("my_data:");
  Serial.println(my_data);

  int data_from_eeprom;
  EEPROM_readAnything(eeprom_addr, data_from_eeprom); //читаем
  Serial.print ("data_from_eeprom:");
  Serial.println(data_from_eeprom);
}

void loop()
{}


template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
  Serial.print ("value");
  Serial.println(value);

  const byte* p = (const byte*)(const void*)&value;
  unsigned int i;
  for (i = 0; i < sizeof(value); i++)
    EEPROM.begin(512);
  {
    EEPROM.write(ee++, *p++);
    delay(10);
  }
  EEPROM.commit();
  return i;
}


template <class T> int EEPROM_readAnything(int ee, T& value)
{
  {
    EEPROM.begin(512);
    byte* p = (byte*)(void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
    {
      *p++ = EEPROM.read(ee++);
      delay(10);
    }
    return i;
  }
}
 

CodeNameHawk

Moderator
Команда форума
Код:
  for (i = 0; i < sizeof(value); i++)
    EEPROM.begin(512);
  {
    EEPROM.write(ee++, *p++);
    delay(10);
  }
и как это будет работать?
 

Vypra

Member
Код:
  for (i = 0; i < sizeof(value); i++)
    EEPROM.begin(512);
  {
    EEPROM.write(ee++, *p++);
    delay(10);
  }
и как это будет работать?
Я поспешил ответить. После моего ответа появился пример. Возможно Вы откорректировали свой ответ. )))

Код:
 EEPROM.begin(512);
  for (i = 0; i < sizeof(value); i++)
  {
    EEPROM.write(ee++, *p++);
    delay(10);
  }
  EEPROM.commit();
Вот так работает.
 

CodeNameHawk

Moderator
Команда форума
Попробуйте delay(10); выкинуть из цикла, перенесите его после EEPROM.commit();
 

Vypra

Member
Пробуем для нескольких данных. Диапазон записи определим ручками.

А вы сделайте проверку содержимого на равенство записываемого
Код:
#include <EEPROM.h>
#include <Arduino.h>

void setup()
{
  Serial.begin (9600);

  int my_data = -1000;
  int my_data2 = 20000;

  EEPROM_writeAnything(0, 3, my_data); // записываем
  Serial.print ("my_data:");
  Serial.println(my_data);

  EEPROM_writeAnything(4, 7, my_data2); // записываем
  Serial.print ("my_data2:");
  Serial.println(my_data2);

  int data_from_eeprom;
  int data_from_eeprom2;

  EEPROM_readAnything(0, 3, data_from_eeprom); //читаем
  Serial.print ("data_from_eeprom:");
  Serial.println(data_from_eeprom);

  EEPROM_readAnything(4, 7, data_from_eeprom2); //читаем
  Serial.print ("data_from_eeprom2:");
  Serial.println(data_from_eeprom2);

  if (my_data = data_from_eeprom)
  {
    Serial.println ("data_from_eeprom - Ok");
  }
  else
  {
    Serial.println ("data_from_eeprom - Bad");
  }


  if (my_data2 = data_from_eeprom2)
  {
    Serial.println ("data_from_eeprom2 - Ok");
  }
  else
  {
    Serial.println ("data_from_eeprom2 - Bad");
  }
}



void loop()
{}

template <class T> int EEPROM_writeAnything(int ee1, int ee2, const T & value)
{
  const byte* p = (const byte*)(const void*)&value;
  unsigned int i;
  EEPROM.begin(512);
  for (i = 0; i < ee2 + 1; i++)
  {
    EEPROM.write(ee1++, *p++);
  }
  EEPROM.commit();
  delay(20);
  return i;
}


template <class T> int EEPROM_readAnything(int ee1, int ee2, T & value)
{
  {
    EEPROM.begin(512);
    byte* p = (byte*)(void*)&value;
    unsigned int i;
    for (i = 0; i < ee2 + 1; i++)
    {
      *p++ = EEPROM.read(ee1++);
    }
    return i;
  }
}
Результат:
my_data:-1000
my_data2:20000
data_from_eeprom:-1000
data_from_eeprom2:20000
data_from_eeprom - Ok
data_from_eeprom2 - Ok

Это на работе только что попробовал. Все гуд.
Но вчера дома этот же блок записи int вставил в код устройства с датчиками, так не пошло. WD перезагружал NodeMCU. И явно ребутится когда доходит код до блока чтения с памяти. Разбираться не было времени ночью.
nikolz, что не так? Вы ж не просто так спросили?
 

nikolz

Well-known member
суть предложения следующая.
можно проверять на совпадение вместо задержки и вместо записи
алгоритм такой
ставите цикл пока не совпадает - пишите
или условный если не совпадает то пишите
 

Сергей_Ф

Moderator
Команда форума
@nikolz вы бы поаккуратнее с такими предложениями. А то новички в цикле писать будут. До дырки во флеш ;)
 
Сверху Снизу