Запись девятизначного числа во FRAM

SPIREX
Offline
Зарегистрирован: 05.05.2016

Привет! Прошу предоставить простой код, с возможностью записи 6 и 9 значного числа из переменной long, во внешнюю память FRAM.

Наверняка есть что-то простое как этот ниже, абсолютно рабочий, для встроенной EEPROM.

Память FM24CL64B. Побайтно пишу без проблем, 3 дня бьюсь с объединением кода в единое целое, всё безрезультатно.

Всё что находил в инете? перепробовал всё, не могу сделать рабочий вариант, поэтому прошу как алкаш в переходе,  с табличкой "подайте на бухло".  За то честно и прямо, напишите мне код :)

#include <EEPROM.h>
long data = 123456789;
int address = 0;

void setup() {
  Serial.begin(9600);
  EEPROM.put(address, data);
  delay(10);
  EEPROM.get(address, data);
  Serial.print(data, DEC);
}
void loop() {
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

SPIREX пишет:

Наверняка есть что-то простое как этот ниже, абсолютно рабочий, для встроенной EEPROM.

#include <EEPROM.h>
long data = 123456789;
int address = 0;

void setup() {
  Serial.begin(9600);
  EEPROM.put(address, data);
  delay(10);
  EEPROM.get(address, data);
  Serial.print(data, DEC);
}
void loop() {
}

 

если вы этим кодом проверяете запись в ЕЕПРОМ - хочу вас "обрадовать" - этот код бессмысленный, он ничего не проверяет.

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

вам такой же бессмысленный код нужен для ФРАМ? :)

 

 

SPIREX
Offline
Зарегистрирован: 05.05.2016

Само собой, если закомментировать запись, и стереть значение long, то чтение идёт из памяти правильное на TFT дисплее всё отображается верно, у меня это работает в конструкции.

Этот код только для примера, насколько он короткий и понятный.

Просто мне нужно сохранить около двухсот 9-значных значений, и хотелось бы код покороче.

FRAM по сути внешняя еепром. Есть такой код, но для запоминания 9 знаков, его нужно допилить.

 

#include <Wire.h>
#include "Adafruit_EEPROM_I2C.h"
Adafruit_EEPROM_I2C i2ceeprom;
#define EEPROM_ADDR 0x50
int value;
long data = 123456789;
int address = 0;

void setup(void) {
  Serial.begin(9600);
  (i2ceeprom.begin(0x50));


  i2ceeprom.write8(address, data);  // запись

  data = i2ceeprom.read8(address);  // чтение


  Serial.print(data, DEC);



  for (int address = 0; address < 10; address++) { // чтение первых 10 байт
    value = i2ceeprom.read8(address);
    Serial.print("\n");
    Serial.print(address, DEC);
    Serial.print("   dec ");
    Serial.print(value, DEC);
    Serial.print("   hex ");
    Serial.print(value, HEX);
  }
}

void loop(void) {
}

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

SPIREX пишет:
За то честно и прямо, напишите мне код :)

Заявку в "Ищу исполнителя" размещай. 500р. Телега @wdrakula.

b707
Онлайн
Зарегистрирован: 26.05.2017

wdrakula пишет:

Заявку в "Ищу исполнителя" размещай. 500р. Телега @wdrakula.

я смотрю,, бармалею скоро придется снижать цены :)

b707
Онлайн
Зарегистрирован: 26.05.2017

SPIREX пишет:

Просто мне нужно сохранить около двухсот 9-значных значений, и хотелось бы код покороче.

Возьми свой "побайтный код" и оберни в функцию или просто в цикл.- и сможешь писать хоть тысячу значений десятком строчек...

А хочешь красиво - найди исходник ЕЕПРОМ.put и get и сделай по аналогии

andriano
andriano аватар
Онлайн
Зарегистрирован: 20.06.2015

SPIREX пишет:

Прошу предоставить...

Круто!

SPIREX
Offline
Зарегистрирован: 05.05.2016

b707,

Понял, попробую.

Kakmyc
Онлайн
Зарегистрирован: 15.01.2018

Их у меня есть.

На не реви только

long EEPROM_long_read(int addr) { byte raw[4]; for(byte i = 0; i < 4; i++) raw[i] = EEPROM.read(addr+i); long &num = (long&)raw; return num; } 
  void EEPROM_long_write(int addr, long num){ byte raw[4]; (long&)raw = num; for(byte i = 0; i < 4; i++) EEPROM.write(addr+i, raw[i]); }

 

SPIREX
Offline
Зарегистрирован: 05.05.2016

Адрес моей внешней FRAM   0x50

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

Например вписать что то типа этого (eeprom.begin(0x50));

b707
Онлайн
Зарегистрирован: 26.05.2017

SPIREX пишет:

Адрес моей внешней FRAM   0x50

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

нет

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

В конце концов, если уж так все плохо с соображалкой (что уж миндальничать) - так закажите код Дракуле, или 500 рублей тоже нет?

SPIREX
Offline
Зарегистрирован: 05.05.2016

b707

всё просто, я копи-пастер, на этом этапе с FRAM я сильно застрял.

Я вообще сомневаюсь что это FRAM, поэтому большинство скетчей, которые вроде как работают у других, у меня с ними не всё отображается в плане всё что записывается. Хотя побайтно пишется. Одну FRAM я протестировал, 60 миллионов записей прошла, ячейки свойство сохранять информацию сохранили. Хотя может перемаркированная стойкая EEPROM попалась.

Бьюсь с кодами дальше...

Kakmyc
Онлайн
Зарегистрирован: 15.01.2018

Я одного понять не могу.

Ты пишешь можешь писать один байт.

Как записать и прочитать long побайтно я тебе выложил .

Что тебе ещё надо ?

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

SPIREX пишет:

Всё что находил в инете? перепробовал всё, не могу сделать рабочий вариант, поэтому прошу как алкаш в переходе,  с табличкой "подайте на бухло".  За то честно и прямо

Давайте я тоже Вам скажу честно и прямо.

Вы сейчас делаете три вещи

1. Не лазите ни по каким интернетам, а открываете библиотеку EEPROM и вытаскиваете оттуда функцию put. которая у Вас работает (выкладываете еёё в виде кода)

2. Сморите на неё и пытаетесь понять какие именно два пальца надо "чиркнуть" об асфальт, чтобы она работала с Вашей функцией записи одного байта. Вашу пробу выкладываете тоже.

Скорее всего (ну 95%) шаг три не понадобится, но если таки ..., то я обещаю

3. в ответ выложить Вам готовое решение - всего-то поменять одну (прописью "ОДНУ") строку в put, чтобы у Вас всё заработало.

Договорились?

Только давайте честно и прямо, т.е. п. 2 Вы честно пытаетесь выполнить.

SPIREX
Offline
Зарегистрирован: 05.05.2016

Kakmyc,

спасибо! это заработало)) я нашёл куда код подоткнуть. Теперь попытаюсь отвязать библиотеку Adafruit_EEPROM_I2C.h.

ЕвгенийП,  попробую и это, голова реально кипит, отпишусь.

Пока этот код работает. При проверке, само собой запись, и значение long 987654321 закомментировать.

#include <Wire.h>
#include "Adafruit_EEPROM_I2C.h"
Adafruit_EEPROM_I2C i2ceeprom;
#define EEPROM_ADDR 0x50
int value;
long data = 987654321;
int address = 0;

void setup(void) {
  Serial.begin(9600);
  (i2ceeprom.begin(0x50));

  EEPROM_long_write(address, data);
  data = EEPROM_long_read(address);

  Serial.print(data, DEC);
}

void loop(void) {
} long EEPROM_long_read(int addr) {
  byte raw[4];
  for (byte i = 0; i < 4; i++) raw[i] = i2ceeprom.read8(addr + i);
  long &num = (long&)raw;
  return num;
}
void EEPROM_long_write(int addr, long num) {
  byte raw[4];
  (long&)raw = num;
  for (byte i = 0; i < 4; i++) i2ceeprom.write8(addr + i, raw[i]);
}

 

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

SPIREX пишет:

Пока этот код работает. 

Этот код значительно хуже put. Вернее, не хуже, а "менее универсален". Он только для long, а так, как сделано в put вы сразу получаете функцию для записи переменной любого типа. Хоть long, хоть long long, хоть структуры или массива - одна функция на всё. 

Так что постарайтесь, там одну строку изменить надо - вместо её функции записи байта вызывать Вашу И ВСЁ. Если что, то моё обещание в силе, но уверен. что не понадобится.

SPIREX
Offline
Зарегистрирован: 05.05.2016

ЕвгенийП, смотрю на этот кусок кода с файла еепром, и честно, нифига не понимаю куда его вставить.... в мой код записи одного байта.

 

#include <Wire.h>
#include "Adafruit_EEPROM_I2C.h"
Adafruit_EEPROM_I2C i2ceeprom;
#define EEPROM_ADDR 0x50
int value;
long data = 123456789;
int address = 0;

void setup(void) {
  Serial.begin(9600);
  (i2ceeprom.begin(0x50));

  i2ceeprom.write8(address, data);  // запись

  data = i2ceeprom.read8(address);  // чтение



////////  ВЫВОД НА МОНИТОР ПОРТА ЗНАЧЕНИЯ data и 10 байт для контроля ////////
  Serial.print(data, DEC);
  for (int address = 0; address < 10; address++) { // чтение первых 10 байт
    value = i2ceeprom.read8(address);
    Serial.print("\n");
    Serial.print(address, DEC);
    Serial.print("   dec ");
    Serial.print(value, DEC);
    Serial.print("   hex ");
    Serial.print(value, HEX);
  }
}

void loop(void) {
}

 

SPIREX
Offline
Зарегистрирован: 05.05.2016
    //Functionality to 'get' and 'put' objects to and from EEPROM.
    template< typename T > T &get( int idx, T &t ){
        EEPtr e = idx;
        uint8_t *ptr = (uint8_t*) &t;
        for( int count = sizeof(T) ; count ; --count, ++e )  *ptr++ = *e;
        return t;
    }
    
    template< typename T > const T &put( int idx, const T &t ){
        EEPtr e = idx;
        const uint8_t *ptr = (const uint8_t*) &t;
        for( int count = sizeof(T) ; count ; --count, ++e )  (*e).update( *ptr++ );
        return t;
    }

 

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

SPIREX пишет:

ЕвгенийП, смотрю на этот кусок кода с файла еепром, и честно, нифига не понимаю куда его вставить.... в мой код записи одного байта.

Так не его надо вставить, а в него вставить вызов Вашей функции!

У Вас же сть функция записи одно байта? Как она называется? ZapisatBait? И у неё два  параметра? Тот самый байт и адрес? Так? Типа ZapisatBait(bt, addr); и всё запишется?

Если так, то просто вставляете это в код put

SPIREX пишет:

    template< typename T > const T &put( int idx, const T &t ){
        EEPtr e = idx;
        const uint8_t *ptr = (const uint8_t*) &t;
        for( int count = sizeof(T) ; count ; --count, ++e )  (*e).update( *ptr++ );
        return t;
    }

Строку № 2 выбрасываете, она не нужна, а вместо их записи байта вставляете свою, делов-то

    template< typename T > const T &put( int idx, const T &t ){
        const uint8_t *ptr = (const uint8_t*) &t;
        for( int count = sizeof(T) ; count ; --count, idx++ )  ZapisatBait(*ptr++, idx);
        return t;
    }

Ну, собственно и всё, если я ничего не наляпал (ночь-таки глубокая). Можете записывать еъ хоть массивы, хоть структуры, что угодно.

SPIREX
Offline
Зарегистрирован: 05.05.2016

Вот рабочий скетч на основе кода, который предоставил Kakmyc, на мониторе порта всё хорошо, но как Вы предупреждали, будут проблемы, и они появились в реальной конструкции, я перевёл код на внешнюю FRAM, при чтении из ячеек памяти всё виснет, поскольку нет возврата адреса что ли, как Вы подметили, что put и get работет правльно. С встроенной еепром у меня всё работает. Я всё ровно не понял куда вставить, то что я вытащил из библиотеки еепром. При вставке в этот скетч что прикрепил ниже, компилятор материться на template. Можете вставить куда надо? скетч ниже.

 

https://drive.google.com/file/d/1HkxISdY7XWJhsH0imjKBW3SXR9zyOGE8/view?usp=sharing

 

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

Не, давайте скетч нормально вставляйте.

Возможно, я сегодня не смогу посмотреть, если так, потерпите до завтра, у меня сегодня беготной день.

b707
Онлайн
Зарегистрирован: 26.05.2017

SPIREX пишет:

Я всё ровно не понял куда вставить, то что я вытащил из библиотеки еепром. При вставке в этот скетч что прикрепил ниже, компилятор материться на template. Можете вставить куда надо? скетч ниже.

э, нет. Условие было - put get вы пишете сами. А вы даже две строчки поменять не осилили, Евгению и это пришлось самому делать. Я бы на его месте ничего вам дописывать не стал....

SPIREX
Offline
Зарегистрирован: 05.05.2016

Зависания кода на основе кода от Kakmyc победил, я балбес посадил выбор ячеек памяти в код вращения энкодера, при прерываниях я так понимаю происходит сбой (на внутреннюю еепром это не влияло и всё работало). Сделал управление кнопками, каналы плюс - каналы минус, прошил во все ячейки фрам 0, и всё заработало отлично, пустые каналы содержат пустые ячейки, и при записи частоты сохраняются.

Про put get, мне не ясно. В данный момент у меня есть скетч, он использует библиотеку Adafruit_EEPROM_I2C.h.

Итого, файл скетча, и два файла библиотеки,  Adafruit_EEPROM_I2C.h  и  Adafruit_EEPROM_I2C.cpp. Куда мне вставлять этот кусок кода PUT GET от библиотеки EEPROM? куда не вставь компилятор матерится на всё что в этом куске, оно и понятно, кусок от библы EEPROM, и всё что в нем есть, завязано на всё что связано с библиотекой EEPROM. Или мне нужно прикрепить дополнительно в скетч штатную библиотеку EEPROM, но у меня же внешняя EEPROM-FRAM...

#include "Adafruit_EEPROM_I2C.h"
Adafruit_EEPROM_I2C i2ceeprom;
#define EEPROM_ADDR 0x50
int value;
long data  = 123456789; // WRITE PRI PROVERKE ZATERET V O
int address = 0;

void setup(void) {
  Serial.begin(9600);
  (i2ceeprom.begin(0x50));

  FRAM_write(address, data);  // WRITE PRI PROVERKE ZAKOMMENTIROVAT

  data = FRAM_read(address);  // READ

  Serial.print(data, DEC);
}
void loop(void) {
}

long FRAM_read(int addr) {
  byte raw[4];
  for (byte i = 0; i < 4; i++) raw[i] = i2ceeprom.read8(addr + i);
  long &num = (long&)raw;
  return num;
}
void FRAM_write(int addr, long num) {
  byte raw[4];
  (long&)raw = num;
  for (byte i = 0; i < 4; i++) i2ceeprom.write8(addr + i, raw[i]);
}

 

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

SPIREX пишет:
Куда мне вставлять этот кусок кода PUT GET от библиотеки EEPROM?

До сих пор я не видел ни одной попытки от Вас что-нибудь куда-нибудь вставить :-(

Значит, оно Вам не надо :-(

SPIREX пишет:
оно и понятно, кусок от библы EEPROM, и всё что в нем есть, завязано на всё что связано с библиотекой EEPROM.

Неужели? Что именно в моей функции из поста #18 "завязано" на EEPROM? Ответ "всё" не принимается. Конкретно, хоть одну букву покажите, которая "завязана"? Ничего там не завязано - совершенно независимый код.

SPIREX пишет:
куда не вставь компилятор матерится на всё что в этом куске,

Да, неужели? Он матерится ТОЛЬКО на функцию ZapisatBait - так я Вам сразу сказал, "допустим, она у Вас есть", разумеется надо туда Вашу функцию вставить

Почему вот я вставил в Ваш последний код свою функцию из поста #18 (только вместо ZapisatBait разумное что-то написал) и никто не матерится? Ну, совсем никто?

#include "Adafruit_EEPROM_I2C.h"
Adafruit_EEPROM_I2C i2ceeprom;
#define EEPROM_ADDR 0x50
int value;
long data  = 123456789; // WRITE PRI PROVERKE ZATERET V O
int address = 0;



template< typename T > const T &put( int idx, const T &t ){
    const uint8_t *ptr = (const uint8_t*) &t;
    for( int count = sizeof(T) ; count ; --count, idx++ )  i2ceeprom.write8(idx, *ptr++);
    return t;
}

void setup(void) {
  Serial.begin(9600);
  (i2ceeprom.begin(0x50));

  FRAM_write(address, data);  // WRITE PRI PROVERKE ZAKOMMENTIROVAT

  data = FRAM_read(address);  // READ

  Serial.print(data, DEC);
}
void loop(void) {
}

long FRAM_read(int addr) {
  byte raw[4];
  for (byte i = 0; i < 4; i++) raw[i] = i2ceeprom.read8(addr + i);
  long &num = (long&)raw;
  return num;
}
void FRAM_write(int addr, long num) {
  byte raw[4];
  (long&)raw = num;
  for (byte i = 0; i < 4; i++) i2ceeprom.write8(addr + i, raw[i]);
}

И где он ругается? Честно, Вы хоть что-нибудь в этом "своём" коде понимаете?

Теперь сделайте также get. Только сразу предупреждаю. С put Вы моё условие не выполнили - сами не попытались (я ни одной попытки не видел). Если с get будет также - на меня не рассчитывайте. Пока не начнёте думать и делать сами, я больше Вам ничего писать не буду.

SPIREX
Offline
Зарегистрирован: 05.05.2016

Ладно, вопрос закрыт.

Живите долго, не болейте...

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

ЕвгенийП пишет:
До сих пор я не видел ни одной попытки от Вас что-нибудь куда-нибудь вставить :-(

Зачем ты взываешь к тому, чего нет?  Организм тебе в первом сообщении прямо сказал "Подайте код зарадихриста".   Эх, опять ты плохой, не так помогаешь. 

 

b707
Онлайн
Зарегистрирован: 26.05.2017

SPIREX пишет:

Ладно, вопрос закрыт.

Живите долго, не болейте...

выпросил код нахаляву еще и обиделся в итоге...

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

И Вам не хворать.

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

b707 пишет:

SPIREX пишет:

Ладно, вопрос закрыт.

Живите долго, не болейте...

выпросил код нахаляву еще и обиделся в итоге...

Так понятно, он же дал четкую заявку

SPIREX пишет:

Привет! Прошу предоставить простой код

А ему тут мозги выносить начали, сделай то.. пробуй так.. Написано ж четко "Прошу предоставить"

 
 
b707
Онлайн
Зарегистрирован: 26.05.2017

Logik пишет:

Написано ж четко "Прошу предоставить"

 
ну да, надо было сразу послать...
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

ну да, надо было сразу послать...

Послать код? В смысле "предоставить"?