Как записать байтовый массив в EEPROM?

SERGEI TOKAREV
Offline
Зарегистрирован: 21.12.2019

Объясните, плиз, почему с int все работает, а с byte - нет!

Вот код

#include <EEPROM.h>
int EEMEM intArray_adr[6];
byte EEMEM byteArray_adr[6];
 
void setup() {
  int intArray[6] = {1,2,3,4,5,6};
  EEPROM.put((int)&intArray_adr, intArray);

  byte byteArray[6] = {1,2,3,4,5,6};
  EEPROM.put((byte)&byteArray_adr, byteArray);
}

В Ардуино ИДЕ выходит предупреждение

 warning: cast from 'byte (*)[6] {aka unsigned char (*)[6]}' to 'byte {aka unsigned char}' loses precision [-fpermissive]
 
   EEPROM.put((byte)&byteArray_adr, byteArray);
 
А в tinkercad вообще идет как ошибка.
In function 'void setup()': 12:21: error: cast from 'byte (*)[6] {aka unsigned char (*)[6]}' to 'byte {aka unsigned char}' loses precision [-fpermissive]
 
Как правильно записать байтовый массив?
 
wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

SERGEI TOKAREV пишет:

В Ардуино ИДЕ выходит предупреждение

А в tinkercad вообще идет как ошибка.

а инструкцию почитать не пробовал?

https://www.arduino.cc/en/Reference/EEPROMPut

b707
Offline
Зарегистрирован: 26.05.2017

Сергей Токарев, а попробуйте обьяснить своими словами. что по вашему делает эта строчка?

EEPROM.put((byte)&byteArray_adr, byteArray);

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Надо квона в пост призвать, он тут размахивал EEMEM'ом направо и налево. 

А товарищ, imho, хочет положить массив из RAM в массив EEMEM, но не понимает, как это сделать штатными средствами.

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

А товарищ, imho, хочет положить массив из RAM в массив EEMEM, но не понимает, как это сделать штатными средствами.

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

Это вообще какой-то вывих мозга, смысл которого мне непонятен - и поэтому я прошу ТС обьяснить. что он такое делает.

SERGEI TOKAREV
Offline
Зарегистрирован: 21.12.2019

Цитата:

 

 инструкцию почитать не пробовал?

my english is fery bad. Only if "address: the location to write to, starting from 0 (int)"....

Цитата:

а попробуйте обьяснить своими словами. что по вашему делает эта строчка?

Поместить по адресу, что храниться в указателе byteArray_adr, содержимое byteArray...

Но адрес должен быть int. Т.е. вся проблема в преобразовании (byte)&byteArray_adr?

(int)&byteArray_adr - все проходит без ошибок.

Все проблема в приведении к типу?

b707
Offline
Зарегистрирован: 26.05.2017

Сергей, в чем смысл сначала создавать в EMEM неинициализированный массив - а потом класть по этому адресу другой массив?  Вместо 3х строчек


byte EEMEM byteArray_adr[6];
byte byteArray[6] = {1,2,3,4,5,6};
EEPROM.put((byte)&byteArray_adr, byteArray);

не проще все записать в одну?

byte EEMEM byteArray_adr[6] = {1,2,3,4,5,6};
 

А формально ошибка у вас возникает потому, что адреса памяти имеют тип инт

SERGEI TOKAREV
Offline
Зарегистрирован: 21.12.2019

Цитата:

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

Это вообще какой-то вывих мозга, смысл которого мне непонятен - и поэтому я прошу ТС обьяснить. что он такое делает.

Все мои основные знания про ЕЕПРОМ отсюда https://alexgyver.ru/lessons/eeprom/#%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0-eepromh

Почему не инициализированный?

byte EEMEM byteArray_adr[6]; //Определяем адрес для шестибайтового массива
 
09   byte byteArray[6] = {1,2,3,4,5,6}; // Определяем массив
10

  EEPROM.put((int)&byteArray_adr, byteArray); //Записываем

 

b707
Offline
Зарегистрирован: 26.05.2017

SERGEI TOKAREV пишет:

Все мои основные знания про ЕЕПРОМ отсюда

ну тогда все понятно. Не читайте больше этого автора. Алекс Гайвер известный блоггер, но программист из него весьма посредственный, что он сам и не скрывает. Лучше читайте оргинальные описания к функциям. а не гайверовские пояснения. в которых просто куяча ляпов и групых ошибок.

Цитата:
Почему не инициализированный?

а где он инициализируется? - номер строчки укажите?

 
 
 
1

 

 

SERGEI TOKAREV
Offline
Зарегистрирован: 21.12.2019

Цитата:

не проще все записать в одну?

А формально ошибка у вас возникает потому, что адреса памяти имеют тип инт

Код предельно упрощен для вопроса и понимания сути.

byte EEMEM byteArray_adr[6] - это ведь должно быть только в глобальных переменных.

в реальной задаче три массива и порядка 15 матриц... инициализация в отдельной функции нужна.

с int'ом для адреса понял.

Всем спасибо

b707
Offline
Зарегистрирован: 26.05.2017

SERGEI TOKAREV пишет:

byte EEMEM byteArray_adr[6] - это ведь должно быть только в глобальных переменных.

зачем вообще нужен этот массив?

Цитата:
в реальной задаче три массива и порядка 15 матриц... инициализация в отдельной функции нужна.

ооо что-то мне это напоминает...

ЗЫ Сергей - а вы случаем не были тут зарегены под ником b612 ? :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Библиотека EEPROM.h кривая с точки зрения программирования на Си, но "замечательно адаптирована" под "новичков Ардуино". При нормальном программировании  к примеру переменная int a, должна находится по указателю int* p=&a; Но если в обычном ОЗУ это работает, то EEPROMе логика идет лесом. По факту указатель на переменную в ЕЕPROM{на адрес ячейки ЕЕPROM} всегда int. И да вместо реферального класса идут костыли EEPROM.put() и EEPROM.get()

SERGEI TOKAREV
Offline
Зарегистрирован: 21.12.2019

Нет раньше тут не был.
Да и вообще это первые опыты с программированием ардуинки.
С/С++ учил только в институте лет так 30 назад:)
Потому и "поплыл" с типизацией

Schwarz78
Offline
Зарегистрирован: 19.01.2019

SERGEI TOKAREV пишет:
Нет раньше тут не был. Да и вообще это первые опыты с программированием ардуинки. С/С++ учил только в институте лет так 30 назад:) Потому и "поплыл" с типизацией

С логикой.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

qwone пишет:

Библиотека EEPROM.h кривая с точки зрения программирования на Си

Пух, ну я ведь тебя по-дружески просил:

Ворота пишет:
я тебя прошу, будь другом, не превращайся в Великого. Кривизна wiring, это его тема, а не твоя.

Ну, чего так так неймётся-то? Так хочется поговорить о кривых библиотеках? Ну, хочется , так хочется , давай поговорим. Например, вот об этой.

Ой, блин №1

#include "qwonelib.h"

struct data_t { // некая пользовательская структура
  byte  bData;
  data_t(byte bd) : bData(bd) {}
} dt(0);

void setup() {
	Serial.begin(57600);
	Serial.println("Start");
	eeRef <data_t> eeData(& dt);
	data_t m1 = eeData;
	Serial.print("bData=");
	Serial.println(m1.bData);
}
void loop() {}

Ой, блин №2

#include "qwonelib.h"

struct data_t { // некая пользовательская структура
  char f1[128];
  char f2[128];
} dt;

void setup() {
	Serial.begin(57600);
	Serial.println("Start");
	eeRef <data_t> eeData(& dt);
	data_t m1 = eeData;
	Serial.print("f1=");
	Serial.println(m1.f1);
}
void loop() {}

Ой, блин №3

#include "qwonelib.h"

struct data_t { // некая пользовательская структура
  char f1[255];
} dt,dtNew;

void setup() {
	Serial.begin(57600);
	Serial.println("Start");
	eeRef <data_t> eeData(& dt);
	eeData.setNewAdr((const data_t *)10);
	strcpy(dtNew.f1, "Some string");
	eeData.update(dtNew);
}
void loop() {}

Я уж не говорю, что в твоём update ты сначала пытаешься сравнить данные целиком, а потом ещё и (на всякий случай) сравниваешь их побайтово.

Ну, что, продолжим разговор о кривых библиотеках? О какой ещё поговорим?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ворота пишет:
Ну, что, продолжим разговор о кривых библиотеках? О какой ещё поговорим?

И что от этого кривая библиотека исправится. А то что вы привели из моего творчества ту библиотеку не выпрямит. Может если я буду обсерать вас поможет выпрямить EEPROM.h.  Можно попробовать, но думаю бесполезно.   И та свои библиотеки тоже гигхаб не выкладываю. Так как тоже в них много косяков. Так что Ворота не становись ВЕЛИКИМ КРИТИКОМ или ВЕЛИКИМ ГУРМАНОМ.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

qwone пишет:
выпрямить EEPROM.h. 
Да, нет в неё никакой кривизны. Нормальная, вполне профессионально написанная библиотека. То, что предъявляют как её кривизну - просто неумение ею пользоваться и непонимание принципов построения шаблонов.

qwone пишет:
я буду обсерать вас
Ты можешь делать что тебе нравится. Но я никого не обсирал. Я показал объективные, легко проверяемые ошибки и готов помочь в их исправлении. Обсираешь как раз ты EEPROM - хаешь не указав ни одной ошибки.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ворота пишет:
Ты можешь делать что тебе нравится. Но я никого не обсирал. Я показал объективные, легко проверяемые ошибки и готов помочь в их исправлении. Обсираешь как раз ты EEPROM - хаешь не указав ни одной ошибки.

Для тех кто в танке повторю. Указатель на данные в  EEPROM  c типом int. По идее должен быть *тип данных. 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

qwone пишет:

Ворота пишет:
Ты можешь делать что тебе нравится. Но я никого не обсирал. Я показал объективные, легко проверяемые ошибки и готов помочь в их исправлении. Обсираешь как раз ты EEPROM - хаешь не указав ни одной ошибки.

Для тех кто в танке повторю. Указатель на данные в  EEPROM  c типом int. По идее должен быть *тип данных. 

Пух, ты имеешь в виду EEPtr? Так это не указатель на данные, а указатель на ячейку, где хранятся данные. Емнип, там это в комментариях к коду даже написано. Почувствуй разницу действительности со своими ожиданиями ;) - нет там указателя на данные.

Так что, если речь идёт про EEPtr, то там всё норм и сделано ровно так, как задумывалось. Где "кривизна" - в упор не вижу.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/*
 * EEPROM Read
 *
 * Reads the value of each byte of the EEPROM and prints it
 * to the computer.
 * This example code is in the public domain.
 */

#include <EEPROM.h>

// start reading from the first byte (address 0) of the EEPROM
int address = 0;//<--- Вот этот указатель. Посмотрите на тип.
byte value;

void setup() {
  // initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() {
  // read a byte from the current address of the EEPROM
  value = EEPROM.read(address);

  Serial.print(address);
  Serial.print("\t");
  Serial.print(value, DEC);
  Serial.println();

  /***
    Advance to the next address, when at the end restart at the beginning.

    Larger AVR processors have larger EEPROM sizes, E.g:
    - Arduno Duemilanove: 512b EEPROM storage.
    - Arduino Uno:        1kb EEPROM storage.
    - Arduino Mega:       4kb EEPROM storage.

    Rather than hard-coding the length, you should use the pre-provided length function.
    This will make your code portable to all AVR processors.
  ***/
  address = address + 1;
  if (address == EEPROM.length()) {
    address = 0;
  }

  /***
    As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an
    EEPROM address is also doable by a bitwise and of the length - 1.

    ++address &= EEPROM.length() - 1;
  ***/

  delay(500);
}

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Пух, ты сегодня под чем? Грибы, соль, насвай? В коде же ясно видно, что переменная с именем address (ВНЕЗАПНО!) - это не указатель на данные, это АДРЕС ячейки, где (ВНЕЗАПНО!) может хранится только часть данных, потому что (ВНЕЗАПНО!) данные какого-либо типа могут (ВНЕЗАПНО!) не вместиться в одну ячейку хранилища.

Если что и кривое - так это твоё понимание, не более того.

sadman41
Offline
Зарегистрирован: 19.10.2016

Мне кажется, что Квон подвергся атаке бактерий перфекционизма. Как и те, кто сказал "Все в линуксе есть файл". И теперь работа что с данными на диске, что с устройствами, что с пайпами, что с оперативной памятью - всё едино и однотипно.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

DIYMan пишет:
Если что и кривое - так это твоё понимание, не более того.

Просто ошибка очень фундаментальная. Я бы и дальше объяснял почему и как , но зачем.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

qwone пишет:

DIYMan пишет:
Если что и кривое - так это твоё понимание, не более того.

Просто ошибка очень фундаментальная. Я бы и дальше объяснял почему и как , но зачем.

Нет там никакой ошибки, ни фундаментальной, никакой. Я бы тебе объяснил, почему и как, но зачем, если ты не готов понимать, от слова "совсем"?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну нет так нет. Зачем мне жевать для вас одно и тоже. Не хотите и не надо.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Нет пророка в своём Отечестве :)))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну да . Гениальные изобретения которые мы потеряли. https://www.youtube.com/watch?v=eNyWcpHV7-g

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Глянул вскользь твою библиотеку, Пух. Ну что сказать - умиляет. Нашёл, о какой кривизне ты говоришь :) Принудительное приведение типов в setNewAddr - это пять, Пух! Кривизна реализации update - это тоже пять! Молодец! 

Чья бы корова, как говорится...

SERGEI TOKAREV
Offline
Зарегистрирован: 21.12.2019

Ой, кажется я разбудил древний холивар. Ей богу не хотел :)

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

DIYMan пишет:

Принудительное приведение типов в setNewAddr - это пять, Пух! Кривизна реализации update - это тоже пять! Молодец! 

А как насчёт объявление переменной типа T в одном из методов? Стоит подсунуть структуру с неумолчательным конструктором и компилятор поднимает вой "шозанах" - как раз мой первый пример.

И вот, знаешь Дим, я всё жду, когда до Пуха дойдёт, что расширение функциональности в ООП делается наследованием, а не костыльными классами с указателями на расширяемый. Думаешь, дойдёт когда-нибудь? Или 

qwone пишет:
но зачем.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

SERGEI TOKAREV пишет:

Ой, кажется я разбудил древний холивар. Ей богу не хотел :)

Та не, не переживай. Разве ж это холивар? Так, порезвились чуток. Все нормально.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ворота пишет:

бъявление переменной типа T в одном из методов? Стоит подсунуть структуру с неумолчательным конструктором и компилятор поднимает вой "шозанах" - как раз мой первый пример.

А точно, проглядел я этот момент, сразу по ссылке сунулся и вполглаза, чтоб не вытекли, просмотрел :)) Увидел, что хотел - штатная EEPROM в плане дизайна и имплементации - годная, в отличие от.

Ворота пишет:

Думаешь, дойдёт когда-нибудь? 

Риторический вопрос, так то.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ворота пишет:
И вот, знаешь Дим, я всё жду, когда до Пуха дойдёт, что расширение функциональности в ООП делается наследованием, а не костыльными классами с указателями на расширяемый. Думаешь, дойдёт когда-нибудь? 

Расширение функциональности делается с помощью расширения функциональности, а наследование это просто метод апдейта существующих классов при сохранение совместимости со старыми. Фактически откладывание решения на будущее.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Фонд золотых цитат Пуха :)) Вот не перестаю удивляться - как на серьёзных щах можно нести всякую дичь :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ладно. Потом объясню, из-за чего Ворота выпрыгивает из трусов, а другие воспринимают это за норму.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

ua6em пишет:

вы уж определитесь

Так все давно определились.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

qwone пишет:

из-за чего Ворота выпрыгивает из трусов

Пух, ты прямо скажи, приведённые мною в #14 примеры нормально работают и не являются багами? Или ты можешь привести пример, в котором не работает штатная EEPROM? А если нет, то, может, поумерить пыл?

Schwarz78
Offline
Зарегистрирован: 19.01.2019

ua6em пишет:

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

Свой

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

Ворота! Надо признать, что Пух учится и код его постепенно становится менее странным ;).

С точки зрения абстрактной задачки, вполне красивая задача - написать класс для работы с EEPROM, как с обычными переменными. Нужно это или нет - не так важно. Ошибки у Пуха можно поправить, если он перестанет стоять в позе "оскорбленной невинности" ;)).

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

wdrakula пишет:

Ошибки у Пуха можно поправить, если он перестанет стоять в позе "оскорбленной невинности" ;)).

Безусловно. И первая его ошибка - это бездумное копирование кода со штатной EEPROM и масштабирование его на любой тип данных, без понимания как side-эффектов, так и принципов, руководствуясь которыми, в том же штатном EEPROM реализованы различные операторы.

Взять тот же метод update - в оригинале идёт оперирование одним байтом, и всё сделано, основываясь на этом: прочитали из EEPROM, сравнили, если не сходится - записали. У Пуха же - впрочем, там всё видно и так.

Это я к тому, что масштабирование методом "в лоб" - не всегда возможно.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

wdrakula пишет:

Ошибки у Пуха можно поправить, если он перестанет стоять в позе "оскорбленной невинности" ;)).

Можно, если он откажется от своей главной идеи - делать костыльный класс сбоку от основного, а сделает, как все нормальные люди, через наследование (через интерфейс "eepromable" или типа того). Но он же в этом принципиален - наследования в классах нет в природе. Ты видел его (наследование) хоть раз в его теме про классы?

А вообще, мне глубоко пофиг, что и как он пишет. Эти ошибки я видел давно, но помалкивал. И дальше бы помалкивал, он сам напросился. Я ведь по-человечески просил его не распространяться о кривизне wiring (у меня на это аллергия ещё с Великого). Но "не вынесла душа поэта".

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Schwarz78 пишет:

ua6em пишет:

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

Свой

...тихо сам с собою я веду беседу?... так не умею )))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ворота пишет:

Эти ошибки я видел давно, но помалкивал. 

Бдишь, не даёшь никому расслабиться :))) И это - правильно ;)