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

Вопрос Пропадают спецсимволы

Vypra

Member
У меня задача ввести на смартфоне емейл через поле ввода приложения RemoteXY, записать в EEPROM NodeMCU по нажатию кнопки в RemoteXY, считать с памяти EEPROM и вывести обратно через текстовую строку RemoteXY на смартфон. Все работает, но после вывода в текстовую строку убираются с емейла символы @ и точка. На каком этапе символы убираются и как с этим бороться?
Часть кода записи/чтения:
Код:
void EEPROM_write()
{
  RemoteXY_Handler ();
  if (RemoteXY.REC == 1)
  {
    String email_from_in(RemoteXY.email_from_in);
    if (email_from_in != "")
    {
      EEPROM_ESP8266_WRITE (email_from_in, 14);
    }
}

// запись
void EEPROM_ESP8266_WRITE(String buffer, int N)
{
  EEPROM.begin(512);
  delay(10);
  for (int L = 0; L < 32; ++L) {
    EEPROM.write(N + L, buffer[L]);  // EEPROM.write(address, value)
  }
  EEPROM.commit();
}


void EEPROM_read()
{
  RemoteXY_Handler ();
  String email_from_m = EEPROM_ESP8266_READ(14, 39);
  email_from_m.toCharArray(RemoteXY.email_from_m, 26);
}


// чтение
String EEPROM_ESP8266_READ(int min, int max)
{
  EEPROM.begin(512);
  delay(10);
  String buffer;
  for (int L = min; L < max; ++L)
    if (isAlphaNumeric(EEPROM.read(L)))
      buffer += char(EEPROM.read(L));
  return buffer;
}
 

Юрий Ботов

Moderator
Команда форума
Код:
if (isAlphaNumeric(EEPROM.read(L))
       buffer += char(EEPROM.read(L));
Собственно вот тут и убираются. Бороться - закомментировать строку с if.
Но насколько корректно будет при этом работать конструктор интерфейсов - не знаю.
 
Последнее редактирование:

Vypra

Member
Код:
if (isAlphaNumeric(EEPROM.read(L))
       buffer += char(EEPROM.read(L));
Собственно вот тут и убираются. Бороться - закомментировать строку с if.
Но насколько корректно будет при этом работать конструктор интерфейсов - не знаю.
isAlphaNumeric не понимает спецсимволы как буквы? Интересно. Я думал что он приравнивает их к буквам. Значит я ошибался.
Спасибо, попробую.
 

nikolz

Well-known member
isAlphaNumeric не понимает спецсимволы как буквы? Интересно. Я думал что он приравнивает их к буквам. Значит я ошибался.
Спасибо, попробую.
если надо найти конец строки то поставьте if (EEPROM.read(L)!=0) buffer += char(EEPROM.read(L);
если надо найти конкретный символ то сравнивайте с ним.
если надо убрать служебные символы и пробелы то поставьте if (EEPROM.read(L)>32) buffer += char(EEPROM.read(L);
 

Vypra

Member
Код:
if (isAlphaNumeric(EEPROM.read(L))
       buffer += char(EEPROM.read(L));
Собственно вот тут и убираются. Бороться - закомментировать строку с if.
Но насколько корректно будет при этом работать конструктор интерфейсов - не знаю.
Закомментировал, все прекрасно работает. Спасибо.
 

Vypra

Member
Столкнулся с проблемой, когда записываем String меньше чем диапазон записи (мне так нужно), например диапазон записи 0-10, пишем строку в 0-5, 6-10 в пустых ячейках памяти записан 0, потом читаем, то после прочитанного текста появляются пустые символы. В винде 7 они выглядят как пробелы, а в винде 10 как квадратики.
email_from_m.trim(); не убирает эти пробелы
email_from_m.replace(" ",""); тоже не удаляет.
Как определить что за символ появляется, чтоб потом убрать при помощи функции .replace () ?
 

Vypra

Member
Эта тема не касается топика, где Вы советовали пользоваться char. Я это помню.
В данном случае работаем со String.
Пишем с String, читаем в String по этому примеру:

Код:
// запись
void EEPROM_ESP8266_WRITE(String buffer, int N)
{
EEPROM.begin(512);
  for (int L = 0; L < 32; ++L)
    EEPROM.write (N + L, buffer[L]); 
  EEPROM.commit();
  delay(10);
}

// чтение
String EEPROM_ESP8266_READ(int min, int max)
{
  String buffer;
  EEPROM.begin(512);
  for (int L = min; L < max; ++L)
    buffer += char(EEPROM.read(L));
  return buffer;
}
 

Vypra

Member
Serial.print(EEPROM.read(L), BIN);
Так можно идентифицировать символы, которые читаем с памяти? Или в другом формате прочесть.
 

Сергей_Ф

Moderator
Команда форума
@Vypra если вы прочли String длинной max, то он и выведется такой длинны. Вы же не знаете сколько символов реально записано, а признака конца у String нет. Значение 0 в ячейки - это признак конца у массива символов. Если без String совсем никак, то переведите его в []char непосредственно перед записью в EEPROM, и наоборот после чтения.
 
Последнее редактирование:

Vypra

Member
@Vypra если вы прочли String длинной max, то он и выведется такой длинны. Вы же не знаете сколько символов реально записано, а признака конца у String нет.
Я знаю. Но эти пробелы в конце не те символы, которые я записал. Значит можно найти именно их в строке и удалить. Останется чистая строка, которая мне нужна. А для этого нужно понять что за символ добавляется.
 

Сергей_Ф

Moderator
Команда форума
эти пробелы в конце не те символы, которые я записал
это именно вы записали своей горе-функцией. Это мусор, который находился в памяти по адресам сразу за тем, что вернула функция String. Что там, вы узнать можете перед записью. Но не после чтения.
Перестаньте страдать фигнёй, извините за резкость. Работайте с нормальными данными.
 

Vypra

Member
это именно вы записали своей горе-функцией. Это мусор, который находился в памяти по адресам сразу за тем, что вернула функция String. Что там, вы узнать можете перед записью. Но не после чтения.
Перестаньте страдать фигнёй, извините за резкость. Работайте с нормальными данными.
Сергей, при всем уважении к Вам, все же не соглашусь.
Работа со String удобна при парсинге СМС и ответов SIM800. Стандартными функциями ардуино можно удобно и быстро выдергивать подстроки, заменять символы, удалять лишние пробелы, искать нужные части текста и т.д.
Эта горе-функция работает. ))) При записи строки меньшей чем область записи, от конца строки до конца области записи прописываются пустые символы. И они же читаются обратно. Посмотрел через Serial.print(EEPROM.read(L), HEX); и перевел HEX в текст.
Просто добавляем одну строчку if (EEPROM.read(L) != (char)00) и в String эти пустые символы не пишутся.

Код:
String EEPROM_ESP8266_READ(int min, int max)
{
  EEPROM.begin(512);
  String buffer;
  for (int L = min; L < max + 1; ++L)
  {
    if (EEPROM.read(L) != (char)00)
    {
      buffer += char(EEPROM.read(L));
    }
  }
  return buffer;
}
У себя в коде я работаю с нормальными данными )))), но сейчас пишу парсинг СМС и уже написал парсинг ответа SIM800 при установке времени с NTP. Знаю что Вы не любите строки ))).
 

Сергей_Ф

Moderator
Команда форума
@Vypra да при чем тут "люблю", "не люблю". Пользуйтесь сколько хотите. Только перед записью переведите в набор символов и пишите EEPROM. String - это класс С++ , набор функций, если хотите. Он для записи в EEPROM никак не подходит. Только и всего.
Собственно, вы к этому сами и пришли уже. Только зачем то написали собственную функцию, вместо готовой из библиотеки ;)
 
Последнее редактирование:
Сверху Снизу