Замена строковых данных. латиница на кириллицу

Rewan
Offline
Зарегистрирован: 22.04.2017

Добрый день, собратья! 

 Делаю часы на ардуине, столкнулся с проблемой вывода дня недели на кирилице.

  Используется RTC модуль DS1302, символьный дисплей 16x2 по l2c шине. Библиотека LCD_1602_RUS.h для дисплея и iarduino_RTC.h для модуля часов. 

Проблема вот в чем, при чтении дня недели получаем строку на латинице по типу Mon, Sun и т.д. Попытка отредактировать библиотеку iarduino_RTC.h не привела к успеху.

Редактирую строку, в которой хранятся названия.

const char*	charDayMon				=	"SunMonTueWedThuFriSatJanFebMarAprMayJunJulAugSepOctNovDec";	//	Определяем константу-строку для вывода дня недели или месяца		(Mon ... Sun / Jan ... Dec)

Стало

 const char*	charDayMon				=	"ВсПнВтСрЧтПтСбJanFebMarAprMayJunJulAugSepOctNovDec";	//	Определяем константу-строку для вывода дня недели или месяца		(Mon ... Sun / Jan ... Dec)

Количество символов на вывод данных о дне недели изменил. В итоге получаем данные в виде кракозябр... Как я понимаю с кодировкой проблема либо кирилицу не принимает вообще. Любой текст латиницей подставляю - все работает.

 

 Далее пошел другим путем. Попробовал использовать функцию String.replace.

String dayRep,x;
  x= time.gettime("D");
  dayRep = x;
  dayRep.replace("Sun", "Вс");

На выходе тоже получаем ошибку с кодировкой. Замена на латиницу - все ок. 

 Оба варианта и в Serial выдают несуразицу...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А Вы уверены, что Ваш дисплей поддерживает кириллицу?

Rewan
Offline
Зарегистрирован: 22.04.2017

Да, уверен. С просто печатью кириллицы нет никаких проблем.

Данные, получаемые в Serial порт при подмене - тоже кривые. Если подменять латиницу на латиницу, то все без проблем работает.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Rewan пишет:
Данные, получаемые в Serial порт при подмене - тоже кривые

Убедитесь что кодировка ino файла 1251 а не 65001. Вообще, советую писать скетчи не в среде а в FAR. Или в нормальном редакторе, notepad++ например.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Rewan пишет:

Да, уверен. С просто печатью кириллицы нет никаких проблем.

Вообще-то я не про печать, а про вывод на дисплей.

 

PS. Той информации, что Вы приводите, совершенно недостаточно, чтобы поставить диагноз. Распишите подробно, что Вы делаете, когда у Вас есть кириллица, и что - когда вместо кириллицы кракозябры.

 

PPS, И еще: Вы не заметили что при редактировании измеряете строку и, соответственно, смещения всех названий отнеосительно начала строки?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Rewan пишет:

 Оба варианта и в Serial выдают несуразицу...

Так и должно быть - кодировки в IDE и в консоли разные.

arduinec
Offline
Зарегистрирован: 01.09.2015

При выводе в Serial помогает функция utf8rus(), которая приводится здесь: http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafru...

Rewan
Offline
Зарегистрирован: 22.04.2017

По порядку: 

 -Вывод кириллицы на LCD путем lcd.print("Текст") работает безотказно.

 -Если подменаем латиницу на латиницу путем replace - тоже все хорошо. 

Начал копать глубже, что выяснил: 

 - Библиотека для LCD, которую я использую, написана для кодировки UTF-8. Причем принудительно в UTF-8 загнано все.

//Перевод символа из кодировки ASCII в UTF-8 (для печати расширенных русских символов на LCD)
wchar_t *LCD_1602_RUS::asciiutf8(unsigned char ascii)
{
  if (ascii==168) *char_utf8 = 0x401;//код ASCII буквы Ё
  else if (ascii==184) *char_utf8 = 0x451;//код ASCII буквы ё
  else if ((ascii>=192)&&(ascii<=255))//остальные буквы русского алфавита
  {
    *char_utf8 = ascii+848;
  }
  else *char_utf8 = ascii;

  return char_utf8;
}

 - Скетч тоже написан в кодировке UTF-8. 

 - При замене кодировки скетча UTF-8 На Win-1251, вывод на Serial видим нормальную кирилицу, значит функция String.replace работает корректно.

 Как следствие, вывод на LCD в кодировке Win-1251 с данной библиотекой LCD не корректно работает.

Rewan
Offline
Зарегистрирован: 22.04.2017

В примере к библиотеке LCD_1602_RUS.h наткнулся на возможность ввода данных через Serial и вывода их на LCD.

void loop() {
  unsigned char str;
  
  // when characters arrive over the serial port...
  if (Serial.available())
  {
    // wait a bit for the entire message to arrive
    delay(100);
    // clear the screen
    lcd.clear();
    lcd.setCursor(0,0);
    // read all the available characters
    while (Serial.available() > 0)
    {
      // display each character to the LCD
      str = Serial.read();
      lcd.print(lcd.asciiutf8(str));//Вывод на экран LCD, в т.ч. по-русски. Перевод из ASCII в UTF-8.
    }
    Serial.println();
  }

Как я понимаю, Serial передает текст как отдельные символы? 

И еще, для вывода кириллицы на LCD путем lcd.print используется параметр L. Тоесть командп полностью выглядит как lcd.print(L"Текст");. Но я не врубаюсь как можно данный параметр указать для переменной... Давно этот скетч писал, поэтому забыл про данную приписку к команде...

Rewan
Offline
Зарегистрирован: 22.04.2017

arduinec пишет:

При выводе в Serial помогает функция utf8rus(), которая приводится здесь: http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafru...

Спасибо за ссылку, поразбираюсь, может что и выгорит... =)

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

А зачем Вам вообще что-то заменять? Зачём Вы берётсе строку из библиотеки часов? 

Если (как Вы пишете) Вы умеете "просто" выводить кириллицу, то берите от часов день недели в виде числа (там вроде 0-вс, 1-пн и т.п., а имея число, делайте конструкцию типа такой:

const char *  weekDays[] = {"Вс","Пн","Вт","Ср","Чт","Пт","Сб"};
uint8_t wd = <функция Вашей библиотеки, возвращающая день недели числом>;
<функция вывода на экран>(weekDays[wd]);

Вот всё нормально и выведется безо всяких плясок с бубнами

Rewan
Offline
Зарегистрирован: 22.04.2017

А слона то я и не заметил... Спасибо за наводку!! Пошел оптимизировать код... =)