Запись char в энергонезависимую память

Добрый день.

Суть задачи: надо записать float в энергонезависимую память. Я перевожу число в строку, записываю в память, но при чтении получается мусор.

#include <AT24Cxx.h>
#define i2c_address 0x50

AT24Cxx eep(i2c_address, 01);

static float f_val = -123456.54;

static char outstr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static char outstr2[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

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

  dtostrf(f_val, 6, 2, outstr);
Serial.println(outstr);

  for (int i = 0; i <= 9; i++) {
    Serial.print(outstr[i]);
    eep.write(i, outstr[i]);
  }

  Serial.println();

  for (int w = 0; w <= 9; w++) {
    Serial.print(eep.read(w));
    outstr2[w] = eep.read(w);
  }

  Serial.println();

  float k = strtod(outstr2, NULL);
  Serial.println(k);
}

void loop() {
}

А зачем float в строку переводить? Пиши как float и проблем не будет и память сыканомишь

так не выходит

  eep.write(1, f_val);
float k = eep.read(1);
Serial.println(k);

По этому огрызку кода нихрена угадать нельзя.

С чего ты взял, что этот метод читает float?

1 лайк

float занимает 4 байта, так вероятно надо считывать адреса 0, 1, 2 и 3, но я не знаю как соединить их в одно число

есть методы put() и get()

#include <AT24Cxx.h>
#define i2c_address 0x50

AT24Cxx eep(i2c_address, 01);

static float f_val = -123456.54;
static char outstr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static char outstr2[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

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

  eep.write(1, f_val);
float k = eep.read(1);
  Serial.println(k);
}

void loop() {
}

библиотека AT24Cxx.h их не содержит

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

Решение вот тут есть:

да, спасибо, этот пост я видел

#include <AT24Cxx.h>
#define i2c_address 0x50

AT24Cxx eep(i2c_address, 01);

static float f_val = -1.4;
static float f1_val;

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

  byte *x = (byte *)&f_val;

  for (int i = 0; i <= 4; i++) eep.write(i, x[i]);

  byte xx[4];
  for (int w = 0; w <= 4; w++) xx[w] = eep.read(w);

  float *y = (float *)&xx;
  f1_val = y[0];

  Serial.println(f1_val);
}

void loop() {
}

Может поможет

Спойлер
float val = 1.2345;

byte fmass[4] = {0};

float *fp;

float val2 = 0;

void setup() {

Serial.begin(9600);

fp = &val;

for(byte i = 0; i < 4; i++)

fmass[i] =(byte) *((byte*)fp + i);//кладём float в массив

for(byte ii = 0; ii < 4; ii++)

Serial.println(fmass[ii]);

fp = (float*)fmass;

val2 = *fp; //берём из массива

Serial.println(val2, 4);

}

void loop() {

}
Спойлер

Я так тоже умею) Без записи в память преобразование float в строку символов и обратно у меня получается делать. Затык именно в записи и чтение модуля памяти. Мне кажется это частая задача и должен быть какой-то стандартный способ это делать.

Я же показал, как float в массив байтов записать.

Пипец, ты угораешь что ли ?
Что тебе мешает в том коде, который “ты видел”, заменить стандартный EEPROM на твой внешний ?

// чтение
float EEPROM_float_read(int addr) {    
  byte raw[4];
  for(byte i = 0; i < 4; i++) raw[i] = myCastomEEPROM.read(addr+i);
  float &num = (float&)raw;
  return num;
}

// запись
void EEPROM_float_write(int addr, float num) {
  byte raw[4];
  (float&)raw = num;
  for(byte i = 0; i < 4; i++) myCastomEEPROM.write(addr+i, raw[i]);
}

2 лайка

Если от @Kakmyc не помогло, то это и подавно не поможет.

Пока писал пример, не заметил, что уже ответили.

А это не любитель запрещать температуры ниже нуля к нам в новом обличии пришёл ? А может это возвращатель указателя на char ???

Вот так это делается для POD-типов.

template <class T> void write_POD(int addr, const T &data) {
  for (int i = 0; i < sizeof(T); ++i) {
    write_byte(addr + i, *(((uint8_t*)&data) + i));
  }
}

template <class T> T read_POD(int addr) {
  T data;
  for (int i = 0; i < sizeof(T); ++i) {
    read_byte(addr + i, *(((uint8_t*)&data) + i));
  }
  return data;
}
1 лайк

ну… почти

#include <AT24Cxx.h>
#define i2c_address 0x50
AT24Cxx eep(i2c_address, 01);

void setup()
{ 
  float val_1 = -123456.17;
  float val_2 = 0;
  
  EEPROM_float_write(0, val_1);
  val_2 = EEPROM_float_read(0);

  // выводим в сериал
  Serial.begin(9600);
  Serial.println(val_2);
}

void loop(){}


void EEPROM_float_write(int addr, float val) // запись в ЕЕПРОМ
{  
  byte *x = (byte *)&val;
  for(byte i = 0; i < 4; i++) eep.write(i+addr, x[i]);
}

float EEPROM_float_read(int addr) // чтение из ЕЕПРОМ
{    
  byte x[4];
  for(byte i = 0; i < 4; i++) x[i] = eep.read(i+addr);
  float *y = (float *)&x;
  return y[0];
}

но выводит

-102287.56

вместо

-123456.17