Запись и чтение FM24Cxx

Доброго времени суток. Столкнулся с проблеммой: записи и чтения ID RFID метки в память. Считываю ID с метки, записываю в память FM24C02C. Считываю ID из памяти, считываю ID с метки сравниваю и… они не совпадают! Хотя в COM терминале они обсолютно одинаковы. Если ID прописать: String idkey00 = “ID метки”; и сравнить со считываным с метки - они совподают.

/* arduino-1.8.15 плата arduino NANO
*/
#include <avr/wdt.h>
/*   Wire   */
#include <Wire.h>
//#include "FM24I2C.h"
#define ROM  0x50 // I2C адрес памяти
/*   SoftwareSerial   */
#include <SoftwareSerial.h>
#define DISABLED -1
SoftwareSerial rfid(03, DISABLED); // RX, TX
char adrT1[8];  // датчик температуры в шкафу
char adrT2[8];  // датчик температуры в подвале
char adrV12[8]; // датчик АКБ 12 вольт
char adrV24[8]; // датчик АКБ 24 вольта
String idkey00 = "30005FCEE4"; // id RFID ключей
String idkey01;
String idkey02;
String idkey03;
String idkey04;
String idkey05;
String idkey06;
String idkey07;
String idkey08;
String idkey09;
bool flagIdkey = 0; // флаг совпадения RFID метки
String str;
String soldData;
String spData;   // переменная для считывания UART
uint8_t wireEn = 1;
uint8_t rfwireEn;
bool writeUart = 0; // флаг записи через UART
/*****   SETUP   ******************************************************************/
void setup()
{ Serial.begin(9600);
  Wire.begin();
  //readKeyEEPROM("K00");
  readKeyEEPROM("K01"); readKeyEEPROM("K02"); readKeyEEPROM("K03"); readKeyEEPROM("K04");
  readKeyEEPROM("K05"); readKeyEEPROM("K06"); readKeyEEPROM("K07"); readKeyEEPROM("K08"); readKeyEEPROM("K09");
  //idkey00 = "30005FCEE4";
  Serial.println("readKeyEnd");
  rfid.begin(9600);
}
/*****   VOID   ******************************************************************/
void loop()
{ readrfid();
  serial();
}
/*****   RFID   ******************************************************************/
inline void readrfid()
{ String strData;
  boolean recievedFlag = 0;
  while (rfid.available() > 0)          // ПОКА есть что то на вход
  { strData += (char)rfid.read();        // забиваем строку принятыми данными
    recievedFlag = 1;                   // поднять флаг что получили данные
    delay(5);                              // ЗАДЕРЖКА. Без неё работает некорректно!
  }
  if (recievedFlag) // если данные получены
  { strData.remove(10, 3);
    if (soldData != strData)            
    { soldData = strData;
      Serial.print(str + "length() " + soldData.length() + " Считано: -" + soldData + "-");
      if (soldData.equals(idkey00)) Serial.print(F("ключ совпал 0"));
      if (soldData.equals(idkey01)) Serial.print(F("ключ совпал 1"));
      if (soldData.equals(idkey02)) Serial.print(F("ключ совпал 2"));
      if (soldData == idkey03) Serial.print(F("ключ совпал 3"));
      if (soldData == idkey04) Serial.print(F("ключ совпал 4"));
      if (soldData == idkey05) Serial.print(F("ключ совпал 5"));
      if (soldData == idkey06) Serial.print(F("ключ совпал 6"));
      if (soldData == idkey07) Serial.print(F("ключ совпал 7"));
      if (soldData == idkey08) Serial.print(F("ключ совпал 8"));
      if (soldData == idkey09) Serial.print(F("ключ совпал 9"));
      Serial.println("");
    }
  }
}
/*****  SERIAL  ******************************************************************/
inline void serial()
{ boolean rcvdFlag = false;
  while (Serial.available() > 0)          // ПОКА есть что то на вход
  { spData += (char)Serial.read();        // забиваем строку принятыми данными
    rcvdFlag = true;                   // поднять флаг что получили данные
    delay(2);                              // ЗАДЕРЖКА. Без неё работает некорректно!
  }
  if (rcvdFlag) // если данные получены
  { String eerom = spData.substring(0, 3);
    if (eerom == "AT")
    { writeUart = 1;
      Serial.println(F(" Для чтения из памяти ID ключей: вводим команду - key ."));
      Serial.println(F(" Для записи ID ключа приложите его к считывателю, после считывания вводим: KХХ ,"));
      Serial.println(F(" где ХХ номер ячейки от 00 до 09. '/n'  Для выхода ввелите: end ."));
    }
    if (writeUart == 1)
    { if (eerom.substring(0, 2) == "K0" ) writeKeyEEPROM(eerom);
      else if (eerom == "key")
      { readKeyEEPROM("K00"); readKeyEEPROM("K01"); readKeyEEPROM("K02"); readKeyEEPROM("K03"); readKeyEEPROM("K04");
        readKeyEEPROM("K05"); readKeyEEPROM("K06"); readKeyEEPROM("K07"); readKeyEEPROM("K08"); readKeyEEPROM("K09");
      }
      else if (eerom == "end")
      { writeUart = 0;
        Serial.println(F(" сеанс завершен"));
        wdt_enable(WDTO_2S);
      }
      spData = "";                          // очистить
    }
    else Serial.println(F("Введите команду 'AT' "));
    spData = "";                          // очистить
  }
}
/*....................................EEROM..............................*/
/***функция записи в EEROM ID ключей*******************************************************/
void writeKeyEEPROM(String EEROM)
{ char addr[10];
  char addend[2];
  uint8_t adrStart; // адрес начальной ячейки памяти для считывания
  uint8_t length = 8; // число байт для передачи.
  soldData.toCharArray(addr, 11); // переводим строку в массив
  addend[0] = addr[8];
  addend[1] = addr[9];
  if (EEROM == "K00")
  { adrStart = 48; Serial.print(F("Ключ 0 запись"));
  }
  if (EEROM == "K01")
  { adrStart = 64; Serial.print(F("Ключ 1 запись"));
  }
  if (EEROM == "K02")
  { adrStart = 80; Serial.print(F("Ключ 2 запись"));
  }
  if (EEROM == "K03")
  { adrStart = 96; Serial.print(F("Ключ 3 запись"));
  }
  if (EEROM == "K04")
  { adrStart = 112; Serial.print(F("Ключ 4 запись"));
  }
  if (EEROM == "K05")
  { adrStart = 128; Serial.print(F("Ключ 5 запись"));
  }
  if (EEROM == "K06")
  { adrStart = 144; Serial.print(F("Ключ 6 запись"));
  }
  if (EEROM == "K07")
  { adrStart = 160; Serial.print(F("Ключ 7 запись"));
  }
  if (EEROM == "K08")
  { adrStart = 176; Serial.print(F("Ключ 8 запись"));
  }
  if (EEROM == "K09")
  { adrStart = 192; Serial.print(F("Ключ 9 запись"));
  }
  Serial.println(str + " ячейка памяти: " + adrStart);
  //Serial.println("");
  // записываем 8 байт на страничку
  Wire.beginTransmission(ROM);
  Wire.write(adrStart);
  Wire.write(addr, length);
  byte a = Wire.endTransmission(); // закрыть передачу
  delay(10);
  if (a == 0) Serial.print(F("запись 8 bit прошла успешно! "));
  else Serial.print(F("Ошибка записи!"));
  // добпвляем еще два байта на следующую страничку (спицифика FM24C02C)
  Wire.beginTransmission(ROM);
  Wire.write(adrStart + 8);
  Wire.write(addend, 2);
  a = Wire.endTransmission(); // закрыть передачу
  delay(10);
  if (a == 0) Serial.println(F(" + запись 2 bit прошла успешно!"));
  else Serial.println(F("Ошибка записи!"));
  if (EEROM == "K00")readKeyEEPROM("K00");
  if (EEROM == "K01")readKeyEEPROM("K01");
  if (EEROM == "K02")readKeyEEPROM("K02");
  if (EEROM == "K03")readKeyEEPROM("K03");
  if (EEROM == "K04")readKeyEEPROM("K04");
  if (EEROM == "K05")readKeyEEPROM("K05");
  if (EEROM == "K06")readKeyEEPROM("K06");
  if (EEROM == "K07")readKeyEEPROM("K07");
  if (EEROM == "K08")readKeyEEPROM("K08");
  if (EEROM == "K09")readKeyEEPROM("K09");
}
/*****   чтение KeyEEROM addr[10]   ******************************************************************/
// считываем из памяти 10 ключей EEROM = 1-10
void readKeyEEPROM(String EEROM)
{ char addr[10];
  uint8_t adrStart; // адрес начальной ячейки памяти для считывания
  uint8_t length = 10;  // число байт для приема.
  if (EEROM == "K00")
  { adrStart = 48; Serial.print(F("K00 ID ключа 00 "));
  }
  if (EEROM == "K01")
  { adrStart = 64; Serial.print(F("K01 ID ключа 01 "));
  }
  if (EEROM == "K02")
  { adrStart = 80; Serial.print(F("K02 ID ключа 02 "));
  }
  if (EEROM == "K03")
  { adrStart = 96; Serial.print(F("K03 ID ключа 03 "));
  }
  if (EEROM == "K04")
  { adrStart = 112; Serial.print(F("K04 ID ключа 04 "));
  }
  if (EEROM == "K05")
  { adrStart = 128; Serial.print(F("K05 ID ключа 05 "));
  }
  if (EEROM == "K06")
  { adrStart = 144; Serial.print(F("K06 ID ключа 06 "));
  }
  if (EEROM == "K07")
  { adrStart = 160; Serial.print(F("K07 ID ключа 07 "));
  }
  if (EEROM == "K08")
  { adrStart = 176; Serial.print(F("K08 ID ключа 08 "));
  }
  if (EEROM == "K09")
  { adrStart = 192; Serial.print(F("K09 ID ключа 09 "));
  }
  Serial.print(str + " Чтение - adrStart; " + adrStart + "  считываем ");
  Wire.beginTransmission(ROM);
  Wire.write(adrStart);
  Wire.endTransmission();
  Wire.requestFrom(ROM, length);
  delay(5);
  if (Wire.available())
  { for (int i = 0; i < length ; i++)
    { addr[i] = Wire.read();
      delay(1);
    }
  }
  if (EEROM == "K00")
  { idkey00 = String(addr);
    Serial.print(str + " - " + idkey00 + " - ");
  }
  if (EEROM == "K01")
  { idkey01 = String(addr);
    Serial.print(str + " - " + idkey01 + " - ");
  }
  if (EEROM == "K02")
  { idkey02 = String(addr);
    Serial.print(str + " - " + idkey02 + " - ");
  }
  if (EEROM == "K03")
  { idkey03 = String(addr);
    Serial.print(str + " - " + idkey03 + " - ");
  }
  if (EEROM == "K04")
  { idkey04 = String(addr);
    Serial.print(str + " - " + idkey04 + " - ");
  }
  if (EEROM == "K05")
  { idkey05 = String(addr);
    Serial.print(str + " - " + idkey05 + " - ");
  }
  if (EEROM == "K06")
  { idkey06 = String(addr);
    Serial.print(str + " - " + idkey06 + " - ");
  }
  if (EEROM == "K07")
  { idkey07 = String(addr);
    Serial.print(str + " - " + idkey07 + " - ");
  }
  if (EEROM == "K08")
  { idkey08 = String(addr);
    Serial.print(str + " - " + idkey08 + " - ");
  }
  if (EEROM == "K09")
  { idkey09 = String(addr);
    Serial.print(str + " - " + idkey09 + " - ");
  }
  Serial.println("");
  delay (500);
}


В плюсах не силён, если что извините, но не могу понять смысл стр117 из 1 поста.
Вы хотите получить массив символов из строки soldData с начальным индексом addr, который является указателем(uint16_t) на локальный массив addr[10]?

P.S. Прошу пардону, как говорится… Что-то из C# залетело)).
Пересмотрел ардуино класс String, всё верно у вас написано.

Так распечатайте побайтно и сравните глазами.

Идет считывание из памяти:
16:42:21.467 → K01 ID ключа 01 Чтение - adrStart; 64 считываен -32007F4AAD-
16:42:21.987 → K02 ID ключа 02 Чтение - adrStart; 80 считываен -30005FCEE4-
16:42:22.507 → K03 ID ключа 03 Чтение - adrStart; 96 считываен -4900B60C67-
16:42:23.027 → K04 ID ключа 04 Чтение - adrStart; 112 считываен -490050B6BB-
16:42:23.547 → K05 ID ключа 05 Чтение - adrStart; 128 считываен -490084D01A-
16:42:24.067 → K06 ID ключа 06 Чтение - adrStart; 144 считываен -490084D01A-
16:42:24.587 → K07 ID ключа 07 Чтение - adrStart; 160 считываен -490084D01A-
16:42:25.147 → K08 ID ключа 08 Чтение - adrStart; 176 считываен -490084F1BE-
16:42:25.667 → K09 ID ключа 09 Чтение - adrStart; 192 считываен -4900B60C67-
16:42:26.187 → readKeyEnd
Считывание из метки. ID первого ключа прописано в скетче, он совпал
16:42:36.537 → length() 10 Считано: -30005FCEE4-ключ совпал 0
ID второго считанного из памяти увы нет.
16:42:45.897 → length() 10 Считано: -32007F4AAD-

16:43:19.777 → Для чтения из памяти ID ключей: вводим команду - key .
16:43:19.857 → Для записи ID ключа приложите его к считывателю, после считывания вводим: KХХ ,
16:43:20.017 → где ХХ номер ячейки от 00 до 09. ‘/n’ Для выхода ввелите: end .
Считанно с метки:
16:43:37.137 → length() 10 Считано: -4900B60C67-
записываем в память:
16:43:56.457 → Ключ 8 запись ячейка памяти: 176
16:43:56.497 → запись 8 bit прошла успешно! + запись 2 bit прошла успешно!
считываем из памяти:
16:43:56.617 → K08 ID ключа 08 Чтение - adrStart; 176 считываен -4900B60C67-
вроде визуально одинаковые!

Получилось как то так:
добавил idkey10 и стал сравнивать со считанным из памяти idkey01

String idkey10 = "32007F4AAD";

if (idkey01 == idkey10) Serial.println("СОВПАЛО");
  else Serial.println("НЕ совпало!");
 
  Serial.print(str + " 0=" + idkey01.charAt(0) + "-  1=" + idkey01.charAt(1) + "-  2=" + idkey01.charAt(2) + "-  3=" + idkey01.charAt(3) + "-  4=" + idkey01.charAt(4) + "-");
  Serial.println(str + " 5=" + idkey01.charAt(5) + "-  6=" + idkey01.charAt(6) + "-  7=" + idkey01.charAt(7) + "-  8=" + idkey01.charAt(8) + "-  9=" + idkey01.charAt(9) + "-");
  Serial.println(" id10");
  Serial.print(str + " 0=" + idkey10.charAt(0) + "-  1=" + idkey10.charAt(1) + "-  2=" + idkey10.charAt(2) + "-  3=" + idkey10.charAt(3) + "-  4=" + idkey10.charAt(4) + "-");
  Serial.println(str + " 5=" + idkey10.charAt(5) + "-  6=" + idkey10.charAt(6) + "-  7=" + idkey10.charAt(7) + "-  8=" + idkey10.charAt(8) + "-  9=" + idkey10.charAt(9) + "-");

  if (idkey01.charAt(0) == idkey10.charAt(0)) Serial.println("СОВПАЛО 0");
  if (idkey01.charAt(1) == idkey10.charAt(1)) Serial.println("СОВПАЛО 1");
  if (idkey01.charAt(2) == idkey10.charAt(2)) Serial.println("СОВПАЛО 2");
  if (idkey01.charAt(3) == idkey10.charAt(3)) Serial.println("СОВПАЛО 3");
  if (idkey01.charAt(4) == idkey10.charAt(4)) Serial.println("СОВПАЛО 4");
  if (idkey01.charAt(5) == idkey10.charAt(5)) Serial.println("СОВПАЛО 5");
  if (idkey01.charAt(6) == idkey10.charAt(6)) Serial.println("СОВПАЛО 6");
  if (idkey01.charAt(7) == idkey10.charAt(7)) Serial.println("СОВПАЛО 7");
  if (idkey01.charAt(8) == idkey10.charAt(8)) Serial.println("СОВПАЛО 8");
  if (idkey01.charAt(9) == idkey10.charAt(9)) Serial.println("СОВПАЛО 9");

получилось:

22:45:32.489 → НЕ совпало!
22:45:32.489 → 0=3- 1=2- 2=0- 3=0- 4=7- 5=F- 6=4- 7=A- 8=A- 9=D-
22:45:32.569 → id10
22:45:32.569 → 0=3- 1=2- 2=0- 3=0- 4=7- 5=F- 6=4- 7=A- 8=A- 9=D-
22:45:32.659 → СОВПАЛО 0
22:45:32.659 → СОВПАЛО 1
22:45:32.659 → СОВПАЛО 2
22:45:32.699 → СОВПАЛО 3
22:45:32.699 → СОВПАЛО 4
22:45:32.739 → СОВПАЛО 5
22:45:32.739 → СОВПАЛО 6
22:45:32.779 → СОВПАЛО 7
22:45:32.779 → СОВПАЛО 8
22:45:32.819 → СОВПАЛО 9

если сравнивать строки:
if (idkey01 == idkey10) - НЕ совпало!, а если по байтно, то все красиво! :face_with_symbols_on_mouth:

И всё же

    void writeKeyEEPROM(String EEROM)
    { char addr[10];
      char addend[2];
      uint8_t adrStart; // адрес начальной ячейки памяти для считывания
      uint8_t length = 8; // число байт для передачи.
      soldData.toCharArray(addr, 11); // переводим строку в массив

char addr[10]; - здесь лучше выделять 11 байт, иначе конец строки(‘\0’), запишется по за выделенным пространством, и (не факт конечно, но) могут быть повреждены нужные данные

Поменял, но… чудо не произошло! По байтно idkey01и idkey10 совпадает, а вот после такой процедуры опять не совпадает

idkey11[0] = idkey01[0];
idkey11[1] = idkey01[1];
idkey11[2] = idkey01[2];
idkey11[3] = idkey01[3];
idkey11[4] = idkey01[4];
idkey11[5] = idkey01[5];
idkey11[6] = idkey01[6];
idkey11[7] = idkey01[7];
idkey11[8] = idkey01[8];
idkey11[9] = idkey01[9];
if (idkey11 == idkey10) НЕ совпало!
Где собака порыта???

А напечатать перед сравнением и, посмотреть. Может длина разная.

Длину я сравнивал я раньше - совпадает.
Тут интереснее получается:

idkey11[0] = idkey10[0];
idkey11[1] = idkey10[1];
idkey11[2] = idkey10[2];
idkey11[3] = idkey10[3];
idkey11[4] = idkey10[4];
idkey11[5] = idkey10[5];
idkey11[6] = idkey10[6];
idkey11[7] = idkey10[7];
idkey11[8] = idkey10[8];
idkey11[9] = idkey10[9];

if (idkey11 == idkey10) НЕ совпадает!

Так если тупо байты присваивать, то , наверно и не должно совпадать. Ведь в String -e, в отличие от простой строки есть ещё и служебные байты, кроме ‘\0’

Ну, вроде при считывании метки, я ее то же перевожу в String и она совпадает с тем, что я прописываю: String idkey00 = “30005FCEE4”;. При считывании из памяти я то же перевожу в String. Может попробую перевести char в uint8_t. Сравнивать по байтно это извращение! Вариант использовать ESP с файловой системой, но “железо” уже сделано.

Я , String знаю слабо, возможно ошибаюсь.
Может кто более грамотный подскажет

Я вапще нихрена не понимаю. ID метки это uint32, т.е. 4 байта, нахрена его как String записывать и иметь потом головную боль со сравнением? Пиши и читай как uint32 и сравнивай потом лехко и непринужденно.

Как говорится: будем посмотреть. Либо кто то подскажет, либо может что нибудь “придет в голову”, хотя мало вероятно, т.к у меня это хобби. Ну и костыли никто не отменял.

Чотто я когдатто колдовал с фрамкой. Там у фрамок разной емкости разная организация блоков памяти. Сейчас прямо не найду, завтра поисчу и выложу фунцыи на чтение и запись, и тестирование тож одним флаконом. Библиотеку не стал писать - лень было. Даже фотку фрамки навешенной на espшку пришью.

У данной памяти есть свои тараканы: там ячейка памяти 8 байт и надо строго записывать в нее, причем если число больше 8 байт, что выше нужно записывать с указанием ячейки. Автоматически в последующию ячейку не пишет.

Так вроде ж больше -
32007F4AAD - 38 разрядов?

Чо?

так я и не знаю, что он туда пишет

А я только хотел посчитать!