Русификация библиотеки Adafruit-GFX и вывод русских букв на дисплей в кодировке UTF-8 из Arduino IDE

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

Краткие итоги предыдущих 300 постов

Для русификации библиотеки Adafruit-GFX требуется:
- скачать любой из приведённых ниже архивов;
- заменить файл glcdfont.c в Adafruit-GFX;
- добавить функцию utf8rus() в скетч;
- вставить в начале скетча команду: display.cp437(true);

Применять функцию utf8rus() можно внутри команд печати строк:
display.println(utf8rus("Тест"));

В архивах примеры и библиотеки, различающиеся по виду дисплея:

0.96" OLED 128x64
https://yadi.sk/d/dd7ULuRftVcRV

2.8" TFT Touch Shield 320x240
https://yadi.sk/d/FgUr5NPztVcRd

Nokia 5110 84x48
https://yadi.sk/d/juZ_mZbfsTpez

Более подробная информация в предыдущих постах.
Например:
В посте 27 демонстрируется скетч, с помощью которого можно редактировать шрифты (в том числе и в glcdfont.c).
В посте 40 приводится вариант utf8rus() с экономным использованием оперативной памяти.
В посте 46 показан 2.8" TFT Touch Shield для Uno и Mega, и прилагается полный набор библиотек и примеров для него.
В посте 80 описаны изменения в шрифте для проекта Transistor Tester (http://arduino.ru/forum/proekty/transistor-tester-arduino).

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

arduinec пишет:

pilnikov пишет:

Хочется все таки конструктивных предложений

Взять библиотеку Adafruit графического дисплея (например: PCD8544 = Nokia5110) и переделать её для работы с MAX7219.

Есть для макса с адафрутом https://github.com/markruys/arduino-Max72xxPanel, но она не работает на моем железе (есп32), хотя для авр и есп8266 вполне рабочая. И дело там походу в настройках SPI

blackbird5
Offline
Зарегистрирован: 16.12.2016

Подскажите пожалуйста. Как самому отредактировать шрифт?

В комплекте с моим экраном шла библиотека с вот таким шрифтом

const uint8_t FreeSevenSegNumFontBitmaps[] PROGMEM = {
// 27x46 [0x30 '0']
0x03,0xFF,0xF8,0x00,0xFF,0xFF,0x80,0x3F,0xFF,0xF8,0x03,0xFF,0xFE,0xC3,0x3F,0xFF,
0xBC,0xF0,0x00,0x0F,0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,0x80,
0x00,0xFF,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,0x7F,0xF8,0x00,0x0F,0xFF,
0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,0x80,0x00,0xFF,0xF0,0x00,0x1F,
0xFC,0x00,0x00,0xFE,0x00,0x00,0x07,0x00,0x00,0x00,0x40,0x00,0x00,0x04,0x00,0x00,
0x00,0xE0,0x00,0x00,0x7F,0x00,0x00,0x3F,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,
0x00,0x7F,0xF8,0x00,0x0F,0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,
0x80,0x00,0xFF,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,0x7F,0xF8,0x00,0x0F,
0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0x78,0x00,0x03,0xC6,0x7F,0xFF,0x30,0x1F,0xFF,
0xF0,0x07,0xFF,0xFF,0x00,0x7F,0xFF,0xC0,0x07,0xFF,0xF0,0x00,
// 6x39 [0x31 '1']
0x31,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C,0x30,0x40,0x00,
0x33,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0x00,
// 27x46 [0x32 '2']
0x03,0xFF,0xF8,0x00,0xFF,0xFF,0x80,0x3F,0xFF,0xF8,0x03,0xFF,0xFE,0xC0,0x3F,0xFF,
0xBC,0x00,0x00,0x0F,0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,0x00,
0x00,0xFC,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x0F,0xC0,
0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,0x00,0x00,0xFC,0x00,0x00,0x1F,
0x80,0x00,0x00,0xF0,0x7F,0xFF,0x86,0x1F,0xFF,0xFC,0x4F,0xFF,0xFF,0xE4,0xFF,0xFF,
0xF8,0xE7,0xFF,0xFC,0x1F,0x00,0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x0F,0xC0,
0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,0x00,0x00,0xFC,0x00,0x00,0x1F,
0x80,0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x0F,0xC0,0x00,0x01,0xF8,0x00,0x00,
0x3F,0x00,0x00,0x07,0xE0,0x00,0x00,0x78,0x00,0x00,0x06,0x7F,0xFF,0x00,0x1F,0xFF,
0xF0,0x07,0xFF,0xFF,0x00,0x7F,0xFF,0xC0,0x07,0xFF,0xF0,0x00,
// 25x46 [0x33 '3']
0x0F,0xFF,0xE0,0x0F,0xFF,0xF8,0x0F,0xFF,0xFE,0x03,0xFF,0xFE,0xC0,0xFF,0xFE,0xF0,
0x00,0x00,0xFC,0x00,0x00,0x7E,0x00,0x00,0x3F,0x00,0x00,0x1F,0x80,0x00,0x0F,0xC0,
0x00,0x07,0xE0,0x00,0x03,0xF0,0x00,0x01,0xF8,0x00,0x00,0xFC,0x00,0x00,0x7E,0x00,
0x00,0x3F,0x00,0x00,0x1F,0x80,0x00,0x0F,0xC0,0x00,0x07,0xE0,0x00,0x00,0xF1,0xFF,
0xFE,0x19,0xFF,0xFF,0xC7,0xFF,0xFF,0xF8,0xFF,0xFF,0xF8,0x1F,0xFF,0xF1,0x80,0x00,
0x03,0xC0,0x00,0x07,0xE0,0x00,0x03,0xF0,0x00,0x01,0xF8,0x00,0x00,0xFC,0x00,0x00,
0x7E,0x00,0x00,0x3F,0x00,0x00,0x1F,0x80,0x00,0x0F,0xC0,0x00,0x07,0xE0,0x00,0x03,
0xF0,0x00,0x01,0xF8,0x00,0x00,0xFC,0x00,0x00,0x7E,0x00,0x00,0x3F,0x00,0x00,0x0F,
0x07,0xFF,0xF3,0x07,0xFF,0xFC,0x07,0xFF,0xFF,0x01,0xFF,0xFF,0x00,0x7F,0xFF,0x00,
// 27x39 [0x34 '4']
0x00,0x00,0x01,0x86,0x00,0x00,0x79,0xE0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,
0x7F,0xF8,0x00,0x0F,0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,0x80,
0x00,0xFF,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,0x7F,0xF8,0x00,0x0F,0xFF,
0x00,0x01,0xFF,0xE0,0x00,0x3F,0xF8,0x00,0x01,0xFC,0xFF,0xFF,0x0E,0x3F,0xFF,0xF8,
0x9F,0xFF,0xFF,0xC1,0xFF,0xFF,0xF0,0x0F,0xFF,0xF8,0xC0,0x00,0x00,0x78,0x00,0x00,
0x3F,0x00,0x00,0x07,0xE0,0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,
0x00,0x7E,0x00,0x00,0x0F,0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,
0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x07,
0x80,0x00,0x00,0x60,
// 27x46 [0x35 '5']
0x03,0xFF,0xF8,0x00,0xFF,0xFF,0x80,0x3F,0xFF,0xF8,0x03,0xFF,0xFE,0x03,0x3F,0xFF,
0x80,0xF0,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,
0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x0F,0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,
0x00,0x00,0x07,0xE0,0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,0x00,
0x7C,0x00,0x00,0x0E,0x7F,0xFF,0x81,0x1F,0xFF,0xFC,0x0F,0xFF,0xFF,0xE0,0xFF,0xFF,
0xF8,0x07,0xFF,0xFC,0x60,0x00,0x00,0x3C,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,
0x00,0x7E,0x00,0x00,0x0F,0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,
0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x0F,
0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x03,0xC0,0x7F,0xFF,0x30,0x1F,0xFF,
0xF0,0x07,0xFF,0xFF,0x00,0x7F,0xFF,0xC0,0x07,0xFF,0xF0,0x00,
// 27x46 [0x36 '6']
0x03,0xFF,0xF8,0x00,0xFF,0xFF,0x80,0x3F,0xFF,0xF8,0x03,0xFF,0xFE,0x03,0x3F,0xFF,
0x80,0xF0,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,
0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x0F,0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,
0x00,0x00,0x07,0xE0,0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,0x00,
0x7C,0x00,0x00,0x0E,0x7F,0xFF,0x81,0x1F,0xFF,0xFC,0x0F,0xFF,0xFF,0xE4,0xFF,0xFF,
0xF8,0xE7,0xFF,0xFC,0x7F,0x00,0x00,0x3F,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,
0x00,0x7F,0xF8,0x00,0x0F,0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,
0x80,0x00,0xFF,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,0x7F,0xF8,0x00,0x0F,
0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0x78,0x00,0x03,0xC6,0x7F,0xFF,0x30,0x1F,0xFF,
0xF0,0x07,0xFF,0xFF,0x00,0x7F,0xFF,0xC0,0x07,0xFF,0xF0,0x00,
// 23x42 [0x37 '7']
0x3F,0xFF,0x80,0xFF,0xFF,0x83,0xFF,0xFF,0x83,0xFF,0xFE,0xC3,0xFF,0xFB,0xC0,0x00,
0x0F,0xC0,0x00,0x1F,0x80,0x00,0x3F,0x00,0x00,0x7E,0x00,0x00,0xFC,0x00,0x01,0xF8,
0x00,0x03,0xF0,0x00,0x07,0xE0,0x00,0x0F,0xC0,0x00,0x1F,0x80,0x00,0x3F,0x00,0x00,
0x7E,0x00,0x00,0xFC,0x00,0x01,0xF8,0x00,0x00,0xF0,0x00,0x00,0x60,0x00,0x00,0x40,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x3C,0x00,0x01,0xF8,0x00,0x03,
0xF0,0x00,0x07,0xE0,0x00,0x0F,0xC0,0x00,0x1F,0x80,0x00,0x3F,0x00,0x00,0x7E,0x00,
0x00,0xFC,0x00,0x01,0xF8,0x00,0x03,0xF0,0x00,0x07,0xE0,0x00,0x0F,0xC0,0x00,0x1F,
0x80,0x00,0x3F,0x00,0x00,0x3C,0x00,0x00,0x30,
// 27x46 [0x38 '8']
0x03,0xFF,0xF8,0x00,0xFF,0xFF,0x80,0x3F,0xFF,0xF8,0x03,0xFF,0xFE,0xC3,0x3F,0xFF,
0xBC,0xF0,0x00,0x0F,0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,0x80,
0x00,0xFF,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,0x7F,0xF8,0x00,0x0F,0xFF,
0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,0x80,0x00,0xFF,0xF0,0x00,0x1F,
0xFC,0x00,0x00,0xFE,0x7F,0xFF,0x87,0x1F,0xFF,0xFC,0x4F,0xFF,0xFF,0xE4,0xFF,0xFF,
0xF8,0xE7,0xFF,0xFC,0x7F,0x00,0x00,0x3F,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,
0x00,0x7F,0xF8,0x00,0x0F,0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,
0x80,0x00,0xFF,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,0x7F,0xF8,0x00,0x0F,
0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0x78,0x00,0x03,0xC6,0x7F,0xFF,0x30,0x1F,0xFF,
0xF0,0x07,0xFF,0xFF,0x00,0x7F,0xFF,0xC0,0x07,0xFF,0xF0,0x00,
// 27x46 [0x39 '9']
0x03,0xFF,0xF8,0x00,0xFF,0xFF,0x80,0x3F,0xFF,0xF8,0x03,0xFF,0xFE,0xC3,0x3F,0xFF,
0xBC,0xF0,0x00,0x0F,0xFF,0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,0x80,
0x00,0xFF,0xF0,0x00,0x1F,0xFE,0x00,0x03,0xFF,0xC0,0x00,0x7F,0xF8,0x00,0x0F,0xFF,
0x00,0x01,0xFF,0xE0,0x00,0x3F,0xFC,0x00,0x07,0xFF,0x80,0x00,0xFF,0xF0,0x00,0x1F,
0xFC,0x00,0x00,0xFE,0x7F,0xFF,0x87,0x1F,0xFF,0xFC,0x4F,0xFF,0xFF,0xE0,0xFF,0xFF,
0xF8,0x07,0xFF,0xFC,0x60,0x00,0x00,0x3C,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,
0x00,0x7E,0x00,0x00,0x0F,0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x07,0xE0,
0x00,0x00,0xFC,0x00,0x00,0x1F,0x80,0x00,0x03,0xF0,0x00,0x00,0x7E,0x00,0x00,0x0F,
0xC0,0x00,0x01,0xF8,0x00,0x00,0x3F,0x00,0x00,0x03,0xC0,0x7F,0xFF,0x30,0x1F,0xFF,
0xF0,0x07,0xFF,0xFF,0x00,0x7F,0xFF,0xC0,0x07,0xFF,0xF0,0x00,
};
const GFXglyph FreeSevenSegNumFontGlyphs[] PROGMEM = {
    {   0, 27, 46, 32,  2, -48 }, // 0x30 '0'
    { 156,  6, 39, 32, 23, -45 }, // 0x31 '1'
    { 186, 27, 46, 32,  2, -48 }, // 0x32 '2'
    { 342, 25, 46, 32,  4, -48 }, // 0x33 '3'
    { 486, 27, 39, 32,  2, -45 }, // 0x34 '4'
    { 618, 27, 46, 32,  2, -48 }, // 0x35 '5'
    { 774, 27, 46, 32,  2, -48 }, // 0x36 '6'
    { 930, 23, 42, 32,  6, -48 }, // 0x37 '7'
    {1051, 27, 46, 32,  2, -48 }, // 0x38 '8'
    {1207, 27, 46, 32,  2, -48 }, // 0x39 '9'
};
const GFXfont FreeSevenSegNumFont PROGMEM = {
    (uint8_t  *)FreeSevenSegNumFontBitmaps,
    (GFXglyph *)FreeSevenSegNumFontGlyphs,
    48, 58, 50
};

Отличная стилизация, но! В этом шрифте отсутствует точка и тире. Они мне необходимы.

Как их туда вкорячить? Интуитивно я понял что глифы ссылаются на битмапы, но дальше разобраться не смог.

 

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Что то я не могу сориентироваться.

Как то "рисовал" и выводил шрифты с русскими естественно  в U8G и для lcd от siemens S65 (132x176) и на какойто цетной (128х128).

Без какиз либо преобразований, в первом случаи в u8g_lib библиотеке, в остальных както стряпал из UTFT и шилдовых печатал русскими буквами :

char *out = "xxxxxxxxxxx";
  switch (wd) {
    case 1: out = "Понедельник"; xw = 0; break ;
    case 2: out = "Вторник"; xw = 30;    break ;
    case 3: out = "Среда"; xw = 45;      break ;
    case 4: out = "Четверг"; xw = 30;    break ;
    case 5: out = "Пятница"; xw = 30;    break ;
    case 6: out = "Суббота"; xw = 30;    break ;
    case 7: out = "Воскресенье"; xw = 0; break ;
  }

и получалось соответственно 

Ну и так далее.

Не особо интересно было разбираться с кодировками что и как. Эксперементальным путём определил под каиим номером какая русская буква прячется и получился шрифт.:

#ifndef FONT_8X8_RUS_H
 #define FONT_8X8_RUS_H
 static prog_uint8_t font_8x8_rus[] PROGMEM =
 {
	 0x07, // 7   - количество байт конфигураций
	 0x08, // 8   - разрядность (ширина, кратная байту 8~16~24~32)
	 0x08, // 8   - ширина
	 0x08, // 8   - высота
	 0x02, // 2   - идентификатор
	 0x20, // 32  - первый чар ))
	 0xbf, // 191 - последний чар
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  0x20
  0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10,  // !
  0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,  // "
  0x44, 0x44, 0xfe, 0x44, 0x44, 0xfe, 0x44, 0x44,  // #
  0x10, 0x7c, 0x90, 0x7c, 0x12, 0x12, 0xfc, 0x10,  // $
  0xe2, 0xa4, 0xe8, 0x10, 0x10, 0x2e, 0x4a, 0x8e,  // %
  0x0c, 0x12, 0x12, 0x7e, 0x88, 0x8c, 0x64, 0x00,  // &
  0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,  // '
  0x08, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08,  // (
  0x20, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x20,  // )
  0x00, 0x00, 0x10, 0x38, 0x10, 0x28, 0x00, 0x00,  // *
  0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00,  // + 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,  // ,
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,  // -
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,  // .
  0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x40, 0x80,  // /
  0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c,  // 0
  0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c,  // 1 
  0x7e, 0x02, 0x02, 0x7c, 0x80, 0x80, 0x82, 0xfe,  // 2
  0x7c, 0x82, 0x02, 0x1e, 0x02, 0x02, 0x82, 0x7c,  // 3
  0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, 0x04, 0x04,  // 4
  0xfc, 0x80, 0x80, 0xfc, 0x02, 0x02, 0x82, 0x7c,  // 5
  0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, 0x82, 0x7c,  // 6
  0xfe, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,  // 7 
  0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x82, 0x7c,  // 8 
  0x7c, 0x82, 0x82, 0x7e, 0x02, 0x02, 0x82, 0x7c,  // 9
  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,  // :
  0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x20,  // ;
  0x00, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00,  // <
  0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00,  // =
  0x00, 0x00, 0x60, 0x30, 0x18, 0x30, 0x60, 0x00,  // >
  0x7c, 0x04, 0x04, 0x3c, 0x20, 0x20, 0x00, 0x20,  // ?
  0x7c, 0x82, 0x9a, 0xa6, 0xa6, 0x9b, 0x80, 0x7e,  // @
  0x7c, 0x82, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82,  // A
  0xfc, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82, 0x7c,  // B
  0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e,  // C
  0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc,  // D
  0xfe, 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80, 0xfe,  // E
  0xfe, 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80, 0x80,  // F
  0x7e, 0x80, 0x80, 0x86, 0x82, 0x82, 0x82, 0x7e,  // G
  0x82, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82, 0x82,  // H
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,  // I
  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x3e,  // J
  0x86, 0x8c, 0x98, 0xf0, 0x98, 0x8c, 0x84, 0x86,  // K
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c,  // L
  0x82, 0xc6, 0xee, 0xaa, 0xba, 0x92, 0x92, 0x82,  // M
  0x82, 0xc2, 0xe2, 0xb2, 0x9a, 0x8e, 0x86, 0x82,  // N
  0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c,  // O
  0xfc, 0x82, 0x82, 0x82, 0xfc, 0x80, 0x80, 0x80,  // P
  0x7c, 0x82, 0x82, 0x82, 0x82, 0x8a, 0x7c, 0x02,  // Q
  0xfc, 0x82, 0x82, 0x82, 0xfc, 0x98, 0x8c, 0x82,  // R
  0x7c, 0x82, 0x80, 0x7c, 0x02, 0x02, 0x82, 0x7c,  // S
  0xfe, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,  // T
  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c,  // U
  0x82, 0x44, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10,  // V
  0x82, 0x82, 0x82, 0x92, 0x92, 0xaa, 0xaa, 0x44,  // W
  0x82, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0x82,  // X
  0x82, 0x82, 0x82, 0x7c, 0x10, 0x10, 0x10, 0x10,  // U
  0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe,  // Z
  0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18,  // [
  0xc0, 0x60, 0x30, 0x10, 0x18, 0x0c, 0x06, 0x02,  //  
  0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x30,  // ]
  0x10, 0x28, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00,  // ^
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,  // _
  0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,  // `
  0x00, 0x00, 0x7c, 0x04, 0x7c, 0x44, 0x7c, 0x00,  // a
  0x40, 0x40, 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x00,  // b
  0x00, 0x00, 0x7c, 0x40, 0x40, 0x40, 0x7c, 0x00,  // c
  0x04, 0x04, 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x00,  // d
  0x00, 0x00, 0x7c, 0x44, 0x7c, 0x40, 0x7c, 0x00,  // e
  0x0c, 0x10, 0x18, 0x10, 0x10, 0x10, 0x10, 0x00,  // f
  0x00, 0x00, 0x3c, 0x44, 0x44, 0x3c, 0x04, 0x04,  // g
  0x40, 0x40, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x00,  // h
  0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,  // i
  0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x30,  // j
  0x40, 0x40, 0x4e, 0x58, 0x70, 0x58, 0x4e, 0x00,  // k
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,  // l
  0x00, 0x00, 0xec, 0x92, 0x92, 0x92, 0x92, 0x00,  // m
  0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00,  // n
  0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,  // o
  0x00, 0x00, 0x78, 0x44, 0x44, 0x78, 0x40, 0x40,  // p
  0x00, 0x00, 0x7c, 0x44, 0x44, 0x7c, 0x04, 0x06,  // q
  0x00, 0x00, 0x78, 0x44, 0x40, 0x40, 0x40, 0x00,  // r
  0x00, 0x00, 0x7c, 0x40, 0x7c, 0x04, 0x7c, 0x00,  // s
  0x10, 0x10, 0x38, 0x10, 0x10, 0x10, 0x1c, 0x00,  // t
  0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x3c, 0x00,  // u
  0x00, 0x00, 0x82, 0x44, 0x44, 0x28, 0x10, 0x00,  // v
  0x00, 0x00, 0x92, 0xba, 0xaa, 0xee, 0x44, 0x00,  // w
  0x00, 0x00, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0x00,  // x
  0x00, 0x00, 0x44, 0x44, 0x3c, 0x04, 0x04, 0x38,  // v
  0x00, 0x00, 0x7c, 0x04, 0x38, 0x40, 0x7c, 0x00,  // z
  0x18, 0x10, 0x10, 0x20, 0x20, 0x10, 0x10, 0x18,  // {
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,  // |
  0x30, 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, 0x30,  // }
  0x00, 0x00, 0x00, 0x32, 0x7e, 0x4c, 0x00, 0x00,  // ~
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  0x7F del
  
  0x00, 0x00, 0x78, 0x44, 0x44, 0x78, 0x40, 0x40,  // р
  0x00, 0x00, 0x3c, 0x40, 0x40, 0x40, 0x3c, 0x00,  // с
  0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x00,  // т
  0x00, 0x00, 0x44, 0x44, 0x3c, 0x04, 0x08, 0x30,  // у
  0x00, 0x00, 0x7c, 0x92, 0x92, 0x92, 0x7c, 0x10,  // ф
  0x00, 0x00, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0x00,  // х
  0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x3e, 0x02,  // ц
  0x00, 0x00, 0x44, 0x44, 0x7c, 0x04, 0x04, 0x00,  // ч
  0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0xfe, 0x00,  // ш
  0x00, 0x00, 0x94, 0x94, 0x94, 0x94, 0xfe, 0x02,  // щ
  0x00, 0x00, 0x60, 0x3c, 0x22, 0x22, 0x3e, 0x00,  // ъ
  0x00, 0x00, 0x82, 0x82, 0xf2, 0x8a, 0xf2, 0x00,  // ы
  0x00, 0x00, 0x40, 0x78, 0x44, 0x44, 0x7c, 0x00,  // ь
  0x00, 0x00, 0x78, 0x04, 0x3c, 0x04, 0x78, 0x00,  // э
  0x00, 0x00, 0x8c, 0x92, 0xf2, 0x92, 0x8c, 0x00,  // ю
  0x00, 0x00, 0x7c, 0x44, 0x7c, 0x34, 0x64, 0x00,  // я
  
  0x7c, 0x82, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82,  // А
  0xfc, 0x80, 0x80, 0xfc, 0x82, 0x82, 0x82, 0xfc,  // Б
  0xfc, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82, 0xfc,  // В
  0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // Г
  0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0xfc, 0x82,  // Д
  0xfe, 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80, 0xfe,  // Е
  0x92, 0x54, 0x38, 0x10, 0x38, 0x54, 0x54, 0x82,  // Ж
  0xfc, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0xfc,  // З
  0x82, 0x86, 0x8e, 0x9a, 0xb2, 0xe2, 0xc2, 0x82,  // И
  0xb2, 0xa6, 0x8e, 0x9a, 0xb2, 0xe2, 0xc2, 0x82,  // Й
  0x86, 0x8c, 0x98, 0xf0, 0x98, 0x8c, 0x86, 0x82,  // К
  0x1e, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xc2,  // Л
  0x82, 0xc6, 0xee, 0xaa, 0xba, 0x92, 0x92, 0x82,  // М
  0x82, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82, 0x82,  // Н
  0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c,  // О
  0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,  // П
  0xfc, 0x82, 0x82, 0x82, 0xfc, 0x80, 0x80, 0x80,  // Р
  0x7c, 0x82, 0x80, 0x80, 0x80, 0x80, 0x82, 0x7c,  // С
  0xfe, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,  // Т
  0x82, 0xc2, 0x62, 0x3c, 0x18, 0x30, 0x60, 0xc0,  // У
  0x7c, 0x92, 0x92, 0x92, 0x7c, 0x10, 0x10, 0x10,  // Ф
  0x82, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0x82,  // Х
  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0xfe, 0x02,  // Ц
  0x82, 0x82, 0x82, 0x82, 0x7e, 0x02, 0x02, 0x02,  // Ч
  0x82, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xfe,  // Ш
  0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xff, 0x01,  // Щ
  0xc0, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x3c,  // Ъ
  0x82, 0x82, 0x82, 0xfa, 0x8a, 0x8a, 0x8a, 0xfa,  // Ы
  0x80, 0x80, 0x80, 0xfc, 0x82, 0x82, 0x82, 0xfc,  // Ь
  0xfc, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x02, 0xfc,  // Э
  0x9c, 0xa2, 0xa2, 0xe2, 0xa2, 0xa2, 0xa2, 0x9c,  // Ю
  0x7e, 0x82, 0x82, 0x82, 0x7e, 0x32, 0x62, 0xc2,  // Я
  
  0x00, 0x00, 0x7c, 0x04, 0x7c, 0x44, 0x7c, 0x00,  // а
  0x7c, 0x40, 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x00,  // б
  0x00, 0x00, 0x78, 0x44, 0x7c, 0x44, 0x78, 0x00,  // в
  0x00, 0x00, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00,  // г
  0x00, 0x00, 0x38, 0x28, 0x28, 0x28, 0x7c, 0x82,  // д
  0x00, 0x00, 0x38, 0x44, 0x78, 0x40, 0x38, 0x00,  // е
  0x00, 0x00, 0xd6, 0x54, 0x38, 0x54, 0xd6, 0x00,  // ж
  0x00, 0x00, 0x7c, 0x04, 0x1c, 0x04, 0x7c, 0x00,  // з
  0x00, 0x00, 0x44, 0x44, 0x44, 0x4c, 0x34, 0x00,  // и
  0x00, 0x10, 0x44, 0x44, 0x44, 0x4c, 0x34, 0x00,  // й
  0x00, 0x00, 0x4c, 0x58, 0x70, 0x58, 0x4c, 0x00,  // к
  0x00, 0x00, 0x3c, 0x24, 0x24, 0x64, 0x44, 0x00,  // л
  0x00, 0x00, 0x44, 0x6c, 0x7c, 0x54, 0x54, 0x00,  // м
  0x00, 0x00, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x00,  // н
  0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,  // о
  0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x00   // п
 };
 #endif

Для u8g выглядит он конечно по другому но факт в том, что преобразований не нужно было. 

 switch (mon) {
      case 1: u8g.print("Янв"); break;
      case 2: u8g.print("Фев"); break;
      case 3: u8g.print("Мар"); break;
      case 4: u8g.print("Апр"); break;
      case 5: u8g.print("Май"); break;
      case 6: u8g.print("Июн"); break;
      case 7: u8g.print("Июл"); break;
      case 8: u8g.print("Авг"); break;
      case 9: u8g.print("Сен"); break;
      case 10: u8g.print("Окт"); break;
      case 11: u8g.print("Ноя"); break;
      case 12: u8g.print("Дек"); break;
      default: u8g.print("ERR");
    }

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

А вот с Adafruit-GFX так не получается. Русские символы вобще под другими номерами. Например "п" которая была последняя под номером 191, теперь имеет номер 239.

Как то одир раз удалось скомпелировать, но хорошего по немножку. 

Мне кажется чего то не хватает в Adafruit-GFX что есть в u8g и других.

P.S. Вся эта история была на Arduino 1.0.5

 

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Ну в общем у меня получилось такое:

tft.SetFont(font_8x8_rus);
tft.setCursor(50, 50);
tft.print("Hello World!");
tft.setCursor(50, 70);
tft.print("Привет Мир!");
tft.SetFont(font_12x15_rus);
tft.setCursor(50, 100);
tft.print("Hello World!");
tft.setCursor(50, 120);
tft.print("Привет Мир!");
tft.setTextSize(2);
tft.setCursor(50, 170);
tft.print("Hello World!");
tft.setCursor(50, 210);
tft.print("Привет Мир!");

Фигня в том, что тексты в этой либе не содержат русских, а с русскими символами у меня есть несколько шрифтов. Для вывода я не стал добавлять обсуждаемое раннее преобразование. Проанализиролал немного как именно выводятся русские символы, немного поменял массив символов (теперь русские в массиве расположены подряд, сначала большие, потом маленькие).

Добавил свою функцию выбора шрифта, по оброзу и подобию уже имеющихся, ну и по тихому подменил саму функцию вывода символа, т.к. читать данные из массива нужно по другому. Класс Print подмены не запетил как видно в коде.

В итоге изменений конечно больше чем предлогалось ранее, но зато не имеет значение какие символы выводить и можно использовать готовые шрифты.

P.S. Arduino 1.6.11

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

hugoboss317 пишет:

В итоге изменений конечно больше чем предлогалось ранее, но зато не имеет значение какие символы выводить и можно использовать готовые шрифты.

Это все относится к "методам" и "подходу".

Уважаемый arduinec подошел к проблеме русификации путем подмены шрифта (файла glcfont) + добавления внешнего костыля для декодирования кирилицы (по сути сдвига внутри таблицы со шрифтом) , практически не задев при этом основное тело либы. Т.е. при очередном обновлении GFX'а будет несложно все вернуть на нужные рельсы. 

Вы же подошли кардинальнее - покопавшись в "брюшке у свинки". Результат - отсутствие внешнего костыля, но после обновления нужно будет копаться снова.

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Согласен!

Ну и на десерт вобще полная хрнь.

Может так только у меня но, видимо, компелятор попутал чего то и делает это переодически.

Только вроде(как описывал ранее) подпилил под, очевидно, UTF-8, как вдруг при очередной загрузке русские символы опять поменяли значения.

Чтоб понятней было попробую пояснить так:

Очевидно так в UTF-8

 // 0 - 127 | 128 - 191 | 192 - 223 224 - 255 |
 //  ENGL   |  --||--   |  А  -  Я   а  -  я  | 

А так (не знаю какая кодировка) скажем НЕ UTF-8

 // 0 - 127 | 128 - 143 | 144 - 175| 176 - 191 |
 //  ENGL   |  р  -  я  |  А  -  Я |  а  -  п  |

И выводится двумя байтами и первый байт больше значения последнего символа.

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

 

 

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

hugoboss317 пишет:

Очевидно так в UTF-8

 // 0 - 127 | 128 - 191 | 192 - 223 224 - 255 |
 //  ENGL   |  --||--   |  А  -  Я   а  -  я  | 

Очевидно, что это не просто не так, но это никак не может быть "так", т.к. в диапазоне 128-255 вообще нет ни одного UTF-8 символа (не может быть по стандарту).

На всякий случай: кириллическая "А" кодируется двумя байтами 0xD090, что в десятичной системе соответствует 53392. Если у Вас получается что-то другое, значит, Вы где-то ошиблись.

 

Думаю, вся проблема в этом:

hugoboss317 пишет:

Не особо интересно было разбираться с кодировками что и как.

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Да я и не спорю, очевидно так и есть. Дело вообще в том, что нет точного значения той же буквы "А" (и др.) в кирилице.

uint8_t a  = 'А';
uint16_t A = 'А';
Serial.print("A (2 байта)= ");
Serial.println(A);
Serial.print("А (1 байт) = ");
Serial.print(a);

на выходе получаем:

A (2 байта)= 65472
А (1 байт) = 192

При этом кирилица из массива символов будет читаться так:

// 0 - 127 | 128 - 191 | 192 - 223 224 - 255 |
//  ENGL   |  --||--   |  А  -  Я   а  -  я  | 

и при вызове функции print(); на экран выводится только один русский символ.

но при невыясненный обстоятельствах на выходе может получится и это:

А (1 байт) = 144 

НЕ 192 хотя символ тот же.

символы из массива читаются как во втором случаи (от 128 до 191)

и при вызове функции print(); на экран выводится 2 символа, первый и больше 191.

Как решить эту проблему я понял. Я не понимаю почему так происходит.

 

 

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

hugoboss317 пишет:

Да я и не спорю, очевидно так и есть. Дело вообще в том, что нет точного значения той же буквы "А" (и др.) в кирилице.

Вообще-то и не должно быть. Буква - это символ, предназначенный для записи речи. О каком-то числовом значении речи вообще не идет. Другое дело, что иногда возникает необходимось обрабатывать текст на компьютере, а компьютер ни с чем кроме чисел работать не может. Вот тогда появляется идея - сопоставить каждой букве число. Таблица соответствия называется кодировкой символов. А кодировок таких - существенно больше одной.

Цитата:

Как решить эту проблему я понял. Я не понимаю почему так происходит.

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

DarkGenius
Offline
Зарегистрирован: 09.07.2015

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

Кириллица в Юникоде

Windows-1251
 

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Какая разница вобще что я пишу если никто не читает, не говоря о том, понимает или нет?

XIII
XIII аватар
Offline
Зарегистрирован: 18.02.2016

Всем привет, я новичок, языков программирования не знаю но есть желание постигать эту науку.

Есть у меня дисплей 5110 тестовый код с перекодировкой на  Русский у меня работает. Но немного не хватает соображения как на дисплей вывести показания с датчика температуры DHT22. Могли бы вы объяснить что за чем должно следовать. Прошу не бить сильно по рукам так как работаю большее время ими а не головой

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Если бтблтотека не Adafruit-GFX, то вобще не по адресу. А вобще в чём проблема вывода? В библиотеке DHT22 если примеры как снять показания с датчика и напечатать в порт. Только нужно напечатать на экран. 

DenSyo
Offline
Зарегистрирован: 13.01.2017

hugoboss317

беглый поиск дает наводку о связи между кодировкой файла проекта и получаемой кодировкой после компиляции

http://arduino.ru/forum/programmirovanie/kodirovka-kompilyatora

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

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

to hugoboss317

Мы тут гадаем на кофейной гуще имхо. но гнетут меня смутные сомнения в том, что сами файлы скетча(они же файлы с расширением .ino не правда ли) написаны с использованием различных кодировок (ака windows 1251 utf8 и т.д.). И если оно так то есть два пути проверить это:

1. Открыть файл проекта во внешнем текстовом редакторе (ака Akelpad) и посмотреть кодировку. 

2. В цикле while после строк 

  while (i < k)
  {
    n = source[i];

 (у меня такие переменные, но смысл тот же), в месте где входная строка разбирается посимвольно, добавить 

Serial.println (n, HEX);

Для вывода на экран кодов входящих символов в HEX.

 

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

По поводу кодировок есть неплохой ответ здесь (в конце статьи): http://pashkevich.me/article/1.html

Цитата:
Кодировка символов представляет собой набор правил, определяющих интерпретацию значений байтов. Байт с десятичным значением 110 в кодировке ASCII интерпретируется как символ "n", а в кодировке EBCDIC - как символ ">". Почему? Потому что так кто то решил - в самих кодах и в символах нет ничего такого, что заставляло бы предпочесть одну кодировку другой. Байты одинаковы, меняется только интерпретация.
Джеффри Фридл

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

XIII пишет:

Всем привет, я новичок, языков программирования не знаю но есть желание постигать эту науку.


Есть у меня дисплей 5110 тестовый код с перекодировкой на  Русский у меня работает. Но немного не хватает соображения как на дисплей вывести показания с датчика температуры DHT22. Могли бы вы объяснить что за чем должно следовать. Прошу не бить сильно по рукам так как работаю большее время ими а не головой

XIII на форуме уже почти 2 года. Неужели за это время ничему не научился?

XIII
XIII аватар
Offline
Зарегистрирован: 18.02.2016

занимаюсь когда свободное время есть

XIII
XIII аватар
Offline
Зарегистрирован: 18.02.2016

arduinec пишет:

По поводу кодировок есть неплохой ответ здесь (в конце статьи): http://pashkevich.me/article/1.html

Спасибо, мне это то же очень полезно для изучения я как рас начинающий 

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

XIII пишет:

arduinec пишет:

По поводу кодировок есть неплохой ответ здесь (в конце статьи): http://pashkevich.me/article/1.html

Спасибо, мне это то же очень полезно для изучения я как рас начинающий 

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

shaman1010
Offline
Зарегистрирован: 15.08.2012

Всем привет. В руки попал "классический" 1.44 на ST7735, в уже готовом изделии. Спасибо этой ветке за реализацию русификации на Adafruit_GFX.

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

По порядку.

1) Шрифты брал здесь (удобно, выбор большой, скачивание бесплатное).

2) glcdfont.c здесь у топикстартера, за что ему спасибо. 

3) utf8rus тоже здесь, но вложил всю функцию в файл utf8rus.h и положил рядом с glcdfont.c внутри Adafruit-GFX-Library-master.

4)  Правим или заменяем файлик (стянул здесь же, авторство не мое, изменен алгоритм конвертации с учетом кириллицы, первоисточник) Adafruit-GFX-Library-master/fontconvert/fontconvert.c

5) Этот пункт, возможно, будет для некоторых сложным моментом. Но для linux/macos просто заходим в Adafruit-GFX-Library-master/fontconvert с терминала и делаем make :) Т.е. собираем бинарник конвертора. 1 сек, и у нас появляется правильный исполняемый файл fontconvert, который мы и будем использовать.

6) Закидываем любой понравившийся файл с фонтом (ttf, otf без разницы) рядом с fontconvert. Из терминала коммандуем примерно так: 

/fontconvert Phenomena.otf 10 20 255 > Phenomena10.h

здесь:

Phenomena.otf - исходный файл фонта,
10 - размер фонта, который мы получим в (.h),
20 и 255 - начало и конец перекодируемой таблицы (т.е. если нужна только кириллица можно указать 128 и 255, соответственно),
Phenomena10.h - результирующий файл фонта, который мы будем подключать и использовать.
 
В результате в этой же папке будет Phenomena10.h в который нужно заглянуть для 2 вещей: 1) Убедиться, что после 0x80 есть жизнь (т.е. массивы существуют, и они различаются. Если массивов нет - значит не верно указали параметр начала и конца нужной таблицы. Если есть, но данные в каждом одинаковые, то в исходном файле нет кириллицы). 2) Нужен будет идентификатор, который находится в конце файла, в этой строке:
const GFXfont Phenomena10pt8b PROGMEM = {

В данном случае это Phenomena10pt8b, а 8b в конце говорит о том, что используется 8 битная кодировка, которая нужна для кириллицы.

7) Закидываем Phenomena10.h в папочку Fonts, которая чуть выше в этой же библиотеке.

8) Дальше все просто, открываем скетч, добавляем в начало (#include <Adafruit_ST7735.h> - для моего дисплея, для своего - свою либу):

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <utf8rus.h>
#include <Fonts/Phenomena10.h>
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

В секцию setup (инит для моего дисплея, tft.cp437(true) - для всех ОБЯЗАТЕЛЬНО):

 tft.initR(INITR_144GREENTAB);
 tft.cp437(true);

И непосредственно в месте использования переключаемся на нужный фонт (обратите внимание на & перед идентификатором):

tft.setFont(&Phenomena10pt8b); 

Если дальше он не нужен - отключаем его:

tft.setFont(); 

Используем стандартно:

tft.println(utf8rus("Классика")); 

Мелкий русский остается благодаря правленному glcdfont.c и используется аналогично.

Фонтов можно линковать несколько, но помните, что RAM в микроконтроллерах - дорогой ресурс :)

Все!!!

Скачивание - 2 сек, конвертация - 2 сек, размещение в Fonts - 1 сек, подключение в скетче - 5 сек.

Итого: 10сек на скачивание, конвертацию и подключение.  Самое ценное, судя по всему, это правильный способ конвертирования (glcdfont.c | utf8rus | fontconvert.c). А самое интересное, что полученные таким образом шрифты легко цепляются и к другим распространенным библиотекам, не только к Adafruit-овской.

Надеюсь кому-то сэкономлю немного времени, которое потратил на объединение всего в одном месте.

Свой рабочий комплектик закинул на GoogleDisk. Пользуйтесь, кому нужно.

Вот так выглядит немного допиленный пример топикстартера на 128х128.

 

 
blackbird5
Offline
Зарегистрирован: 16.12.2016

Здравствуйте капитан Очевидность. Все написали просто отлично, но как и никто в этой ветке не смогли описать процесс компиляции fontconvert.c в среде Windows.

Браво!

shaman1010
Offline
Зарегистрирован: 15.08.2012

blackbird5 пишет:
в среде Windows.

где ее взять? :)

Начинайте отсюда, отсюда и отсюда.

Когда все получится - дополните мой пост своей реализацией под винду.

blackbird5
Offline
Зарегистрирован: 16.12.2016

А вот за это спасибо! ) Похоже то, что надо. Покопаю. Хотя все проблемы решил другим путем. Сам нарисовал нужный мне шрифт ))). Оказалось проще, чем устанавливать ВМ и на ней Линукс. )))

DarkGenius
Offline
Зарегистрирован: 09.07.2015

Я подошёл к этой проблеме с другой стороны(пост №68 этой ветки), написал в автоите скрипт(под спойлером), в фотошопе(не обязательно в нём) пишет символ анализирует, пишет нужное в файлы битмапс и глифс, стирает и так далее все символы. Долго, топорно, но понятно и можно самому вносить изменения если что то не нравится.
 

Global $Width;ширина символа
Global $Height;высота символа
Global $xAdvance; Смещение до следующего символа
Global $XcoordFind;x координата начала поиска
Global $YcoordFind;y координата начала поиска
Global $Step = 16 ;шаг поиска
Global $Paused
Global $WrightCount = 0
Global $ByteCount = 0
HotKeySet("{END}", "_Pause");Pause
HotKeySet("{DELETE}", "_Terminate");Exit
Opt("PixelCoordMode", 1)    ;1=absolute, 0=relative, 2=client
Opt("MouseCoordMode", 1)    ;1=absolute, 0=relative, 2=client
Opt("SendKeyDelay", 500)
Opt("SendKeyDownDelay", 500)
;ToolTip ("Pause",10,10,"Font")
$BitmapsFile = FileOpen("Bitmaps.txt", 1)
$GlyphsFile = FileOpen("Glyphs.txt", 1)
$XstartCoord = InputBox("Вопрос", "Координата Х начала отсчёта", "740", "", -1, -1, Default, Default)
$YstartCoord = InputBox("Вопрос", "Координата Y начала отсчёта", "848", "", -1, -1, Default, Default)
;$FontSize = InputBox("Вопрос", "Размер шрифта", "48", "", -1, -1, Default, Default)
#RequireAdmin
Local $hWnd = WinWait("[CLASS:Photoshop]", "", 10)
For $CharCount = 33 To 255
   Global $BiteCount = 256
   Global $Result = 0
   ;$CreatChar = InputBox("Вопрос", "Введите символ", "a", "", -1, -1, Default, Default)
   $CreatChar = Chr ( $CharCount )
   If Asc($CreatChar) < 127 Or Asc($CreatChar) = 168 Or Asc($CreatChar) = 184 Or Asc($CreatChar) > 191 Then
	  WinActivate($hWnd)
	  WinWaitActive($hWnd)
	  Send("{"&$CreatChar&"} ")
	  ToolTip ("Смещение до следующего символа",10,10,"Font")
	  For $Count = 0 to 64
		 If _QColor(PixelGetColor($XstartCoord + ($Count * $Step),$YstartCoord)) = "Black" Then
			If _QColor(PixelGetColor($XstartCoord + ($Count * $Step),$YstartCoord - 4)) = "Black" Then
			   $xAdvance = $Count
			   ExitLoop
			EndIf
		 EndIf
		 If $Count = 64 Then
			MsgBox(0, "Результат", 'Смещение не определено')
			_Terminate()
		 EndIf
	  Next
	  ;MsgBox(0, "Результат", 'Смещение = ' & $xAdvance)
	  ToolTip ("Определение смещения и размера массива",10,10,"Char = "&$CreatChar)
	  Global $Xmin = 64
	  Global $Ymin = 10
	  Global $Xmax = 0
	  Global $Ymax = -40
	  For $YCount = 5 to -20 Step -1; 10: -40
		 For $XCount = 0 to $xAdvance
			If _QColor(PixelGetColor($XstartCoord + ($XCount * $Step),$YstartCoord + ($YCount * $Step) - 4)) = "White" Then
			   ;MsgBox(0, "Результат", 'Pixel ' & $XCount & ',' & $YCount)
			   If $Xmin > $XCount Then
				  $Xmin = $XCount
				  ;MsgBox(0, "Результат", 'min x = ' & $XCount)
			   EndIf
			   If $Xmax < $XCount Then
				  $Xmax = $XCount
				  ;MsgBox(0, "Результат", 'max x = ' & $XCount)
			   EndIf
			   If $Ymin > $YCount Then
				  $Ymin = $YCount
				  ;MsgBox(0, "Результат", 'min y = ' & $YCount)
			   EndIf
			   If $Ymax < $YCount Then
				  $Ymax = $YCount
				  ;MsgBox(0, "Результат", 'max y = ' & $YCount)
			   EndIf
			EndIf
			ToolTip ("X min-max " & $Xmin & ',' & $Xmax & "  Y min-max " & $Ymin & ',' & $Ymax,10,10,"Font Scan = " & $XCount & ',' & $YCount)

		 Next
	  Next
	  $Width = ($Xmax - $Xmin)+1
	  $Height = ($Ymax - $Ymin)+1
	  FileWrite($GlyphsFile, "{")
	  FileWrite($GlyphsFile, $ByteCount)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, $Width)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, $Height)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, $xAdvance)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, $Xmin)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, $Ymin)
	  FileWrite($GlyphsFile, "}")
	  FileWrite($GlyphsFile, ",   // 0x")
	  If Asc($CreatChar) < 16 Then FileWrite($GlyphsFile, "0")
	  FileWrite($GlyphsFile, StringFormat("%X", Asc($CreatChar)))
	  FileWrite($GlyphsFile, " ")
	  If Asc($CreatChar) <> 47 Then FileWrite($GlyphsFile, $CreatChar)
	  FileWrite($GlyphsFile,  Chr(13))
	  $XcoordFind = $XstartCoord + ($Xmin * $Step)
	  $YcoordFind = $YstartCoord + ($Ymin * $Step)
	  ;MsgBox(0, "Результат", $XcoordFind & ' , ' & $YcoordFind)
	  For $Y = 0 to $Height - 1
		 For $X = 0 to $Width - 1
			If _QColor(PixelGetColor($XcoordFind + ($X * $Step),$YcoordFind + ($Y * $Step) - 4)) = "White" Then ;цвет включенного пикселя
			   _WriteBite(1)
			   ;MouseMove($XcoordFind + ($X * $Step),$YcoordFind + ($Y * $Step) - 4)
			   ;MsgBox(0, "Результат", 'max y = ' & $X & ',' & $Y)
			Else
			   _WriteBite(0)
			EndIf
			ToolTip ("Font Wright",10,10,"Font Wright = " & $X & ',' & $Y)
		 Next
	  Next
	  Do
		 _WriteBite(0)
	  Until $BiteCount = 128
   Else
	  FileWrite($GlyphsFile, "{")
	  FileWrite($GlyphsFile, $ByteCount)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, 0)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, 0)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, 0)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, 0)
	  FileWrite($GlyphsFile, ",")
	  FileWrite($GlyphsFile, 0)
	  FileWrite($GlyphsFile, "}")
	  FileWrite($GlyphsFile, ",   // 0x")
	  FileWrite($GlyphsFile, StringFormat("%X", Asc($CreatChar)))
	  FileWrite($GlyphsFile,  Chr(13))
   EndIf
Send("{BACKSPACE}")
Send("{BACKSPACE}")
Sleep(500)
;ConsoleWrite("+" & $ByteCount & @LF)
;Until 0
Next
FileClose($BitmapsFile)
FileClose($GlyphsFile)
Exit
Func _WriteBite($Bite)
   If $BiteCount = 1 Then
	  FileWrite($BitmapsFile, " 0x")
	  If $Result < 16 Then FileWrite($BitmapsFile, "0")
	  FileWrite($BitmapsFile, StringFormat("%X", $Result))
	  FileWrite($BitmapsFile, ",")
	  $Result = 0
	  $BiteCount = 256
	  $ByteCount = $ByteCount + 1
	  $WrightCount = $WrightCount + 1
	  If $WrightCount = 12 Then
		 $WrightCount = 0
		 FileWrite($BitmapsFile,  Chr(13))
	  EndIf
   EndIf
   $BiteCount = $BiteCount/2
   If $Bite = 1 Then $Result = $Result + $BiteCount
EndFunc
;= QuantizationColor =================================================================================================
Func _QColor($nColor)
	$Rez=""
	$Red=BitAND(BitShift($nColor,16),0xFF)
	$Green=BitAND(BitShift($nColor,8),0xFF)
	$Blue=BitAND($nColor,0xFF)
	$Max=0
	If $Red>$Max Then $Max=$Red
	If $Green>$Max Then $Max=$Green
	If $Blue>$Max Then $Max=$Blue
	$Min=$Max
	If $Red<$Min Then $Min=$Red
	If $Green<$Min Then $Min=$Green
	If $Blue<$Min Then $Min=$Blue
	$Grad=51
	If ($Max-$Min)<=$Grad Then
		$MaxGrad=int($Max/$Grad)
		If $MaxGrad<1 Then $Rez="Black"
		If $MaxGrad>=1 Then $Rez="Gray"
		If $MaxGrad>=2 Then $Rez="LightGray"
		If $MaxGrad>=3 Then $Rez="White"
	Else
		$RGColor=Abs($Red-$Green)
		$RBColor=Abs($Red-$Blue)
		$BGColor=Abs($Blue-$Green)
		$MaxMin=int(($Max-$Min)/2)
		If $Max=$Red Then
			If $RGColor>=$MaxMin And $RBColor>=$MaxMin Then $Rez="Red"
			If $RGColor< $MaxMin And $RBColor>=$MaxMin Then $Rez="Yellow"
			If $RGColor>=$MaxMin And $RBColor< $MaxMin Then $Rez="Purple"
		ElseIf $Max=$Green Then
			If $RGColor>=$MaxMin And $BGColor>=$MaxMin Then $Rez="Green"
			If $RGColor< $MaxMin And $BGColor>=$MaxMin Then $Rez="Yellow"
			If $RGColor>=$MaxMin And $BGColor< $MaxMin Then $Rez="LightBlue"
		ElseIf $Max=$Blue Then
			If $BGColor>=$MaxMin And $RBColor>=$MaxMin Then $Rez="Blue"
			If $BGColor< $MaxMin And $RBColor>=$MaxMin Then $Rez="LightBlue"
			If $BGColor>=$MaxMin And $RBColor< $MaxMin Then $Rez="Purple"
		EndIf
	EndIf
	Return $Rez
EndFunc
Func _Terminate()
   FileClose($BitmapsFile)
   FileClose($GlyphsFile)
   Exit
EndFunc
;= Pause ==============================================================================================================
Func _Pause()
	$Paused = NOT $Paused
	While $Paused
		ToolTip ("Pause",10,10,"Font")
		Sleep(100)
	WEnd
	ToolTip ("Work",10,10,"Font")
EndFunc

 

Gomez
Offline
Зарегистрирован: 09.09.2017

blackbird5 пишет:

но как и никто в этой ветке не смогли описать процесс компиляции fontconvert.c в среде Windows.

Так та инструкция (средняя ссылка), которую указывал выше shaman1010

https://github.com/adafruit/Adafruit-GFX-Library/blob/master/fontconvert/fontconvert_win.md

вполне себе под винду - в том смысле, что никаких загрузочных дисков, перезагрузок и прочего не надо.

Правда, я не понял одного - "20 и 255 - начало и конец перекодируемой таблицы (т.е. если нужна только кириллица можно указать 128 и 255, соответственно)". А разве у любых шрифтов начало и конец нужной таблицы одинаков? Если нет, то чем смотреть?

shaman1010
Offline
Зарегистрирован: 15.08.2012

Gomez пишет:

А разве у любых шрифтов начало и конец нужной таблицы одинаков? Если нет, то чем смотреть?

Стандартная ASCII таблица.

Если нужны только цифры - можно отрезать только диапазо 48-57. Для микроконтроллеров это существенно, там память очень ограничена. По-этому под проект в итоге лучше оставлять только используемые куски шрифта.

Gomez
Offline
Зарегистрирован: 09.09.2017

shaman1010, спасибо! Теперь получается делать и русские шрифты!

За напоминание про только цифры тоже спасибо, я взял диапазон 45-57, чтобы захватить "-" и "."

Genri5
Offline
Зарегистрирован: 31.05.2016

hugoboss317, приветствую. Хотел воспользоваться Вашей библиотекой PCF8812_NEW, у меня собралось LCD3410, но вижу, что нужна коррекция. 

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Да, действительно, нужна коррекция. Только для 3410 кажется нужна библиотека не PCF8812_NEW.

Вероятно это экран от Siemens A52(55)

Предлогаю уйту в ту тему.

 

Genri5
Offline
Зарегистрирован: 31.05.2016

Экран от Nokia и чип все - таки  PCF8812. Дайте пожалуйста конкретную ссылку на тему, а то их было не одна.

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Да, действительно кто-то отметил схожесть с 3410. Уходим.

http://arduino.ru/forum/programmirovanie/pomogite-pozhaluista-podklyuchi...

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

DarkGenius пишет:

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

Кириллица в Юникоде

Windows-1251
 

Всё не совсем так просто... И для корректной работы с символьными строками с этим нужно разобраться:

UNICODE - это чисто теоретическая таблица, присвоение кодов символов самым замысловатым языкам ... например, музыкальным нотам. Код UNICODE - всегда 4 байта. Но нигде, ни в одном языке и ОС в таком виде не используется ... не для того предназначается.

UTF-32 - способ кодирования UNICODE значений, каждый символ кодируется как uint32_t.

UTF-16 - способ кодирования UNICODE значений,  каждый символ кодируется uint16_t. Это то, как UNICODE понимается в Windows - сдостаточно старый способ представления UNICODE.

UTF-8 - способ кодирования UNICODE значений последовательностью байт переменной длины (это очень важно!) - каждый символ (код UNICODE) представляется как последовательность байт длиной от 1 до 6 (первоначально) байт ... позже, в угоду совместимости с Windows в стандарте было решено не использовать 5 и 6 байтные последовательности (но многим POSIX-ОС это не указ) - это новая кодировка UNICODE, первоначально придуманая авторами UNIX для операционной системы Plan 9 (~2004г.).

В языка C/C++ для представления локализованных символов введен (стандарт C89, позже C99) тип данных wchar_t - широкие символы. И вот тут начинается неразбериха ... в разных ОС wchar_t имеют разные представления: в Windows - uint16_t, в Linux и других новых ОС - uint32_t ("чистый" UNICODE). Никакого отношения wchar_t к UTF-8 не имеют!

Кодировки, кодовые страницы: CP-866, CP-1251, KOI-8r, ... и ещё 1001 шт. - это прошлый, ... или даже позапрошлый день... когда все иноязычные символы представлялись 1-м байтом.

Все способы кодирования UNICODE - UTF-8, UTF-16, UTF-32 - к кодовым страницам никакого отношения не имеют, они в единой кодировке представляют все возможные в природе символы.

Все новые языки программирования: Python, Go, Swift, Kotlin, Tust ... - используют кодировку UTF-8 по умолчанию.

Но для аппаратного обмена (индикаторы, дисплеи, светодиодные панели, ...) нужно преобразовывать любое представление в 1-байтовое. И вот это (как это делать) заслуживает детального обсуждения. 

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

Olej, все достаточно просто: существует мнение, что для микроконтроллеров на все случаи жизни достаточно 95 символов, входящих в таблицу ACSII. По крайней мере, сегодня.

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

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

Конечно, время от времени возникает какая-нибудь экзотика. Но на то она и экзотика, чтобы относиться к ней именно как к экзотике, а не как к стандартному случаю.

Пример такой экзотики - кириллица в МК: вот лично я написал библиотечку с поддержкой кириллицы ( http://arduino.ru/forum/proekty/asoled-kompaktnaya-biblioteka-dlya-oled-displeya-128kh64-s-kirillitsei-utf-8 ), но сам ни разу этой возможностью (т.е. кириллицей в своих проектах) не воспользовался. Собственно, когда писал - знал, что вряд ли воспользуюсь, и писал для тренировки - в первые две недели знакомства с Ардуино.

Т.е. при выводе на экран нужно понять: в МК доступно максимум предопределенных 95 символов. И именно ими и следует пользоваться. А от экзотики не требовать, чтобы она поддерживалась "искаропки".

По поводу "преобразовывать любое представление в 1-байтовое", думаю, тезис в общем случае неверен. Возможно, в некоторых частных случаях (например, когда общее количество используемых символов меньше 255) однобайтовое представление и имеет смысл. И то вряд ли всегда даже в этих ограничениях.

Заслуживает ли это детального обсуждения - не знаю: с одной стороны, проблема кириллицы всплывает постоянно. С другой - она всплывает исключительно потому, что спрашивающие вообще не знают, что такое кодировка. Отвечающие - нередко тоже (живой пример: статья, которая при поисковом запросе почему-то выводится первой, написана человекаом, который о кодировках имеет весьма смутное представления и поэтому пишет в своей статье чушь http://robocraft.ru/blog/892.html ).

Так что с кем Вы собираетесь обсуждать?

С теми, кто знает - им это неинтересно.

С теми, кто не знает - с ними бесполезно.

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

andriano пишет:

С теми, кто знает - им это неинтересно.

С теми, кто не знает - с ними бесполезно.

С теми, кто знает и понимае о том:

- чем это будет отличаться при использовании Arduino IDE под Windows (где под UNICODE понимают UTF-16), под Linux (где под UNICODE понимают UTF-8) ... и со всеми новыми языками программирования, которые используют исключительно кодирование UTF-8...

- при обменах через Serial с операционной системой, самописанными приложениями на этих языках (Python, Go и т.д.), и со средой Processing ...

- при сетевых обменах, когда жёстко стандартизуется сетевой порядок байт (hton(), ntoh() и т.п.), и когда на другом конце сетевого соединения может быть неизвестно кто, с порядком байт LE или GE.

Это всё немножко другой класс задач, чем писать простые автономные контроллеры ... и такие задачи тоже являются сферой удачного использования Arduino (хотя бы для быстрого моделировния "рук-ног" - внешних интерфейсов для тех же Linux-приложений).

P.S. А тем, кому оно не интересно - тем оно и не надо, те и читать не станут. 

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

andriano пишет:

Заслуживает ли это детального обсуждения - не знаю: с одной стороны, проблема кириллицы всплывает постоянно. С другой - она всплывает исключительно потому, что спрашивающие вообще не знают, что такое кодировка. Отвечающие - нередко тоже (живой пример: статья, которая при поисковом запросе почему-то выводится первой, написана человекаом, который о кодировках имеет весьма смутное представления и поэтому пишет в своей статье чушь http://robocraft.ru/blog/892.html ).

В этом деле есть одна отличительная сторона: те разработчики, которые сидят исключительно в Windows, и не держали в руках другие операционные системы, и не смотрят стандарты, выходящие за рамки Windows - они имеют совершенно искажённые и превратные представления, бытующие, зачастую, внутри Windows-сообщества.

Вот потому они затем и пишут чушь, как они сами её представляют.

 

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

Olej пишет:

С теми, кто знает и понимае о том:

- чем это будет отличаться при использовании Arduino IDE под Windows (где под UNICODE понимают UTF-16), под Linux (где под UNICODE понимают UTF-8) ... и со всеми новыми языками программирования, которые используют исключительно кодирование UTF-8...

- при обменах через Serial с операционной системой, самописанными приложениями на этих языках (Python, Go и т.д.), и со средой Processing ...

- при сетевых обменах, когда жёстко стандартизуется сетевой порядок байт (hton(), ntoh() и т.п.), и когда на другом конце сетевого соединения может быть неизвестно кто, с порядком байт LE или GE.

Это всё немножко другой класс задач, чем писать простые автономные контроллеры ... и такие задачи тоже являются сферой удачного использования Arduino (хотя бы для быстрого моделировния "рук-ног" - внешних интерфейсов для тех же Linux-приложений).

P.S. А тем, кому оно не интересно - тем оно и не надо, те и читать не станут. 

На самом деле, все 3 приведенных Вами направления продразумевают безусловный обмен данными с "большими" компьютерами. Притом, с большой вероятностью, обработку достаточно произвольных данных (а, скажем, не фиксированный набор команд).

В то же время, минимум, значительная, а вероятно - бОльшая часть применений контроллеров относится к их автономной работе.

Поэтому описанный Вами круг проблем - лишь небольшое подмножество от небольшого подмножества. Другими словами - не типичный случай.

Но он тоже заслуживает рассмотрения.

Да и банальный FAQ по работе с кириллицей на Ардуино не помешал бы.

Так что создавайте тему - будеи обсуждать.

Только крайне желательно не упоминать в ней оценочные суждения вообще и сравнение Windows vs Linux в частности. Иначе там заведомо будет 99% флейма.

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

Вот тут https://github.com/lorol/esp8266-oled-ssd1306 очень интересный проект с интересными же ресурсами. В частности есть конвертор шрифтов для adafruit gfx, работающий из под виндовс. Правда строковый, но разобраться можно. В самом проекте используется графическая библиотека MiniGrafx, являющаяся модифицированным форком adafruit gfx. Автор - швейцарец Squix78. Для этой библиотеки в проекте по ссылке выше есть также неплохой оффлайновый редактор шрифтов. Также имеется уже встроенная в либу миниграф поддержка конвертации utf8 - ascii 

DenSyo
Offline
Зарегистрирован: 13.01.2017

pilnikov пишет:
Вот тут https://github.com/lorol/esp8266-oled-ssd1306 очень интересный проект с интересными же ресурсами.

а если там пойти бродить по ссылкам дальше, можно выйти в эту тему)

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

мир тесен однако

Просто я в свое время долго не мог найти конвертер шрифтов чтоб под виндой работал.

7am
7am аватар
Offline
Зарегистрирован: 09.09.2015

Всем привет, помогите разобраться, почему то шрифт не на всю ширину да и в буквах и символах пробелы пиксельные(((
экран i2c oled, адрес подклбчения 0x3C

Код

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// software SPI:
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define maxString 21
char target[maxString + 1] = "";
unsigned char i1,i2,c3;

void setup(){                 
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.cp437(true);
}

void loop() {
  TEST_display_1();
  delay(10000);
  TEST_display_2();
  delay(10000);
  TEST_display_3();
  delay(8000);
  TEST_display_4();
  delay(4000);
  TEST_display_5();
  delay(6000);
}

void TEST_display_1()
{
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  
  for(i1=0; i1<8; i1++) {
    for(i2=0; i2<16; i2++) {
      c3=i1*16+i2;
      if(c3 == 0x0A || c3 == 0x0D) display.print(" ");
      else display.write(c3);
    }
    display.println("");
  }
  display.display();
}

void TEST_display_2()
{
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  
  for(i1=8; i1<16; i1++) {
    for(i2=0; i2<16; i2++)
      display.write(i1*16+i2);
    display.println("");
  }
  display.display();
}

void TEST_display_3()
{
  display.clearDisplay(); 
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);

  display.println(utf8rus("АБВГДЕЖЗИЙКЛМНОП"));
  display.println(utf8rus("РСТУФХЦЧШЩЪЫЬЭЮЯ"));
  display.println(utf8rus("абвгдежзийклмноп"));
  display.println(utf8rus("рстуфхцчшщъыьэюя"));
  display.println(utf8rus("Ёё123ABCabc!@#\xBC\xBD"));
  display.println(utf8rus("10\x83 10\x8A\x82 10\x81\x80 2\x85"));

  display.display();  
}

void TEST_display_4()
{
  display.clearDisplay(); 
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  display.setTextSize(1);
  display.println(utf8rus("Размер шрифта 1"));

  display.setTextSize(2);
  display.println(utf8rus("Размер 2"));

  display.setTextSize(3);
  display.println(utf8rus("Разм 3"));

  display.display();  
}

void TEST_display_5()
{
  display.clearDisplay(); 
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);

  display.println(utf8rus("Строка более 21 символа длиной"));
  display.println(utf8rus("Stroka bolee 21 simvola dlinoj"));

  display.display();  
}

/* Recode russian fonts from UTF-8 to Windows-1251 */
char *utf8rus(char *source)
{
  int i,j,k;
  unsigned char n;
  char m[2] = { '0', '\0' };

  strcpy(target, ""); k = strlen(source); i = j = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (n == 0x81) { n = 0xA8; break; }
          if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (n == 0x91) { n = 0xB8; break; }
          if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
          break;
        }
      }
    }

    m[0] = n; strcat(target, m);
    j++; if (j >= maxString) break;
  }
  return target;
}

utf8rus
 

/* Recode russian fonts from UTF-8 to Windows-1251 */

String utf8rus(String source)
{
  int i,k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };

  k = source.length(); i = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xBF) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (n == 0x81) { n = 0xA8; break; }
          if (n >= 0x90 && n <= 0xBF) n = n + 0x2F;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (n == 0x91) { n = 0xB7; break; }
          if (n >= 0x80 && n <= 0x8F) n = n + 0x6F;
          break;
        }
      }
    }
    m[0] = n; target = target + String(m);
  }
return target;
}

 
 

7am
7am аватар
Offline
Зарегистрирован: 09.09.2015

можешь подсказать что не так?

7am
7am аватар
Offline
Зарегистрирован: 09.09.2015

можешь подсказать что не так?

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

7am пишет:

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

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

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

7am пишет:

Всем привет, помогите разобраться,

Привет! Дата регистрации почти совпадает с моей, поэтому ответы с юмором.

7am пишет:

почему то шрифт не на всю ширину

Похоже букв на всю ширину не хватает :)

7am пишет:

да и в буквах и символах пробелы пиксельные(((

А какие должны быть? Векторные? :)

P.S. В приведённом коде две разных функции utf8rus: одна работает с классом String, другая с char-строками.

7am
7am аватар
Offline
Зарегистрирован: 09.09.2015
7am
7am аватар
Offline
Зарегистрирован: 09.09.2015

..

7am
7am аватар
Offline
Зарегистрирован: 09.09.2015

arduinec пишет:

Привет! Дата регистрации почти совпадает с моей, поэтому ответы с юмором.

А какие должны быть? Векторные? :)

P.S. В приведённом коде две разных функции utf8rus: одна работает с классом String, другая с char-строками.

[/quote]

 

действительно)) почти в одно время регистрации))

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

OLED_I2C

iarduino_OLED.h

по горизонтали нет осттупов, будто текст в полосках как тут 

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

7am пишет:

Судя по всему я не один такой

Каждый день на форуме появляется несколько новичков с глупыми вопросами.
Неужели за 2,5 года нахождения на форуме не научились правильно вопросы задавать?