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

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

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

Для русификации библиотеки 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() с экономным использованием оперативной памяти (с char-строками вместо String).
В посте 46 показан 2.8" TFT Touch Shield для Uno и Mega, и прилагается полный набор библиотек и примеров для него.
В посте 80 описаны изменения в шрифте для проекта Transistor Tester (http://arduino.ru/forum/proekty/transistor-tester-arduino).
В посте 379 дополнительно приведён скетч для демонстрации динамических эффектов из символов, содержащихся в шрифте.
В посте 399 приводится скетч с функцией utf8rus2hex(), которая перекодирует русские буквы и преобразует их в строчные HEX-символы.
В посте 405 приводится вариант функции utf8rus_P() для работы со строками, размещёнными в PROGMEM.

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

1945 пишет:

максимум это 106 размер - #define maxString 106
С такой константой стабильная работа

Для чего опрелена maxString описано в посте #40 (http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafru...)

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

1945 пишет:

максимум это 106 размер - #define maxString 106
С такой константой стабильная работа

1945, у вас скорее всего просто не хватает оперативной памяти для более длинных строк. Эта проблема не имеет никакого отношения к библиотеке и уж точно не связана с типом char :)

kwazimoda
Offline
Зарегистрирован: 26.07.2020

Всем привет!

Если вкратце, то заморочился я с выводом латышских букв... Даже не знаю как сделать правильно, сначала хотел к латинским буквам дорисовывать знаки "различия". НО, потом понял, что при изменении размера шрифта рисовка тоже должна меняться, тогда тупо в файл библиотеки зарисовал латышские буквы и кейсами проверяю.

Хотелось бы чтобы можно было объединить utf8rus и моё творение, поэтому прошу рассмотреть что бы сделать для совмещения. Ах да, зачем мне это надо... я живу в такой стране где в обороте оба языка - латышский и русский, ну и у меня мысль в своём проекте, в меню, сделать выбор языка. Естественно, вызывать одну функцию легче чем двумя крутить. Ну и поскольку с Arduino занимаюсь 4-ый день, то допускаю возможность оптимизации моей задумки.

Прошу сильно не пинать и тапками не бросаться.

String utf8(String source, int x, int y)
{
  int i,k;
  String target;
  unsigned char n;

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

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

    Serial.print(String(i)+" - "); Serial.println(n);
    if (n == 196){
      n = source[i++];// i++;
      switch(n){

         case 128: {
          source.replace("Ā", String(char(244)));
        }
         
         case 129: {
          source.replace("ā", String(char(233)));
        }

         case 140: {
          source.replace("Č", String(char(245)));
        }
        
        case 141: {
          source.replace("č", String(char(234)));
        }

        case 146: {
          source.replace("Ē", String(char(246)));
        }
        
        case 147: {
          source.replace("ē", String(char(235)));
        }

        case 162: {
          source.replace("Ģ", String(char(247)));
        }
        
        case 163: {
          source.replace("ģ", String(char(236)));
        }

        case 170: {
          source.replace("Ī", String(char(248)));
        }
        
        case 171: {
          source.replace("ī", String(char(237)));
        }

        case 182: {
          source.replace("Ķ", String(char(249)));
        }
        
        case 183: {
          source.replace("ķ", String(char(238)));
        }
        
        case 187: {
          source.replace("Ļ", String(char(250)));
        }
        
        case 188: {
          source.replace("ļ", String(char(239)));
        }
      }
    }
    if (n == 197){
      n = source[i++];
            switch(n){
        case 133: {
          source.replace("Ņ", String(char(251)));
        }
        
        case 134: {
          source.replace("ņ", String(char(240)));
        }

        case 160: {
          source.replace("Š", String(char(252)));
        }
        
        case 161: {
          source.replace("š", String(char(241)));
        }

        case 170: {
          source.replace("Ū", String(char(253)));
        }
        
        case 171: {
          source.replace("ū", String(char(242)));
        }
        
        case 189: {
          source.replace("Ž", String(char(254)));
        }
        
        case 190: {
          source.replace("ž", String(char(243)));
        }
      }
    }
  }

return source;

}

 

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

Кwazimoda, обьединить не получится, потому что судя по вашему коду - латышские и русские буквы расположены в таблице в одном и том же диапазоне и пересекаются по кодам
Точнее так - функцию то обьединить можно, но не ясно - зачем. Все равно фонты придется использовать разные, то есть смешивать в одной строке латышские и русские буквы не выйдет, а значит и единая функция не нужна, проще две отдельных

-NMi-
Offline
Зарегистрирован: 20.08.2018

Нафик стока case??? Два массива в виде векторов с общим смещением не?

kwazimoda
Offline
Зарегистрирован: 26.07.2020

b707 пишет:
Кwazimoda, обьединить не получится, потому что судя по вашему коду - латышские и русские буквы расположены в таблице в одном и том же диапазоне и пересекаются по кодам Точнее так - функцию то обьединить можно, но не ясно - зачем. Все равно фонты придется использовать разные, то есть смешивать в одной строке латышские и русские буквы не выйдет, а значит и единая функция не нужна, проще две отдельных

Может я не так расписал. Буквы в те же ячейки я сам накидал. Пробовал "присобачить" сср775, но Arduino IDE меня отшила. Повторюсь, с Arduino и ESP знакомлюсь четвёртый вечер. Латышские буквы можно раскидать по свободным местам, если таковые имеются, я не могу просмотреть весь знакогенератор, а по одному символу разбирать...не серьёзно.

Так же смешивать буквы не надо будет, поскольку текст только или по латышски, или по русски. Ну если уж никак, тогда, да, надо будет 2 набора символов.

К примеру: латышская буква Ā в монитор порта выдаёт код 196 128, ну понятно, что это код юникода, вот как преобразовать в ASCII, не знаю.

kwazimoda
Offline
Зарегистрирован: 26.07.2020

-NMi- пишет:

Нафик стока case??? Два массива в виде векторов с общим смещением не?

Как умею, так пою (могу и с ifами нагородить :D). Можно и 2 массива, только обАрзец можете накидать исходя из моих кейсов? :) Я с массивами (особенно двухмерными) не сильно дружу. Другое дело из таблицы считать данные, и получить массив для сравнения, енто не вопрос, а в таком разрезе пока фантазия так далеко не дошла.

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

kwazimoda пишет:

К примеру: латышская буква Ā в монитор порта выдаёт код 196 128, ну понятно, что это код юникода, вот как преобразовать в ASCII, не знаю.

В ASCII буквы Ā нет. Думаю, правильное (насколько это возможно) преобразование в ASCII должно давать букву A.

kwazimoda
Offline
Зарегистрирован: 26.07.2020

andriano пишет:

kwazimoda пишет:

К примеру: латышская буква Ā в монитор порта выдаёт код 196 128, ну понятно, что это код юникода, вот как преобразовать в ASCII, не знаю.

В ASCII буквы Ā нет. Думаю, правильное (насколько это возможно) преобразование в ASCII должно давать букву A.

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

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

kwazimoda, в сообщении №457 Вы написали "не знаю". Теперь, после моего ответа в сообщении №459 - знаете.

Ну, либо я думаю, что знаете. Если я не очень понятно изложил свою мысль, попытаюсь еще раз: При преобразовании из utf-8 в ASCII буква Ā превращается в букву A. Никаких других правильных вариантов здесь нет. Другими словами, если Вам непременно нужна буква Ā, то ASCII Вам категорически не подходит.

Цитата:
поэтому надо было что-то изобрести.

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

По поводу работы с кодировками - посмотрите эту тему: http://arduino.ru/forum/proekty/s-stm32f103-na-televizor-polnyi-tv-signal

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

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

Исполнилось 5 лет первой публикации кода функции utf8rus(). Архивы с данным кодом скачало более 9 тысяч человек. Надеюсь, что данная тема помогла им русифицировать свои дисплеи.

Yuriy_K
Offline
Зарегистрирован: 23.12.2018

Большая благодарность Автору за создание и подробное разъяснение использования шрифтов в данной библиотеке. Но с появлением дисплеев с большим разрешением, потребовалось несколько доработать Adafruit-GFX. Идеи автора и его доработки подсказали идею применить шрифт 10х16 в glcdfont.c. Сам шрифт полностью перерабатывается под принципы работы библиотеки. На картинке недоработанные символы более тонкие, доработка шрифта и самой библиотеки продолжается...  

2.4&quot; TFT LCD SHIELD

    

EgorKa
Offline
Зарегистрирован: 15.08.2016

Vo_Van_163 пишет:

Архив перезалил, заменив файлы на текущую версию

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

#include <ESP8266WiFi.h>

#include "Wire.h"
#include "TimeClient.h"


Adafruit_PCD8544 display = Adafruit_PCD8544(14, 13, 12, 5, 4);

float utcOffset = 4; // enter your UTC
TimeClient timeClient(utcOffset);

String ssid = "Tenda";

int clockDelay = 1000 ; // clock update period
int updateDelay = 30*60*1000 ; // time server verify period min*sec*millis
unsigned long clockUpdate = 0 ; // 
unsigned long timeUpdate = 0 ; //
 
void syncPrint () ;
void timePrint ();

void setup()   {
  Serial.begin(9600);
  Serial.println();
  Serial.println();

  

  // initialize dispaly
  display.begin();
  // init done
  display.cp437(true);


  // you can change the contrast around to adapt the display
  // for the best viewing!
  display.setContrast(50);

/*  display.display(); // show splashscreen
  delay(2000);
  display.clearDisplay();   // clears the screen and buffer
*/
  WiFi.begin("Tenda", "12345678");

  display.setTextColor(BLACK);

  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
    display.setTextSize(1);
    display.clearDisplay();
    display.setCursor(0,0);
    display.print(utf8rus("Соединяем х"));
    display.display();

    delay(250);
    Serial.print(".");
    display.clearDisplay();
    display.setCursor(0,0);
    display.print(utf8rus("Соединяем +"));
    display.display();
  }

    display.clearDisplay();
    display.setCursor(0,0);
    display.print(utf8rus("Ура!!!"));
    display.setCursor(0,10);
    display.print(utf8rus("Мы в сети:"));
    display.setCursor(0,20);
    display.print(ssid);
    display.display();

    delay (2000);

    clockUpdate = millis () ; // 
    timeUpdate = millis () ; // 

    timeClient.updateTime();

    
}

void loop () {
  unsigned long currentMillis = millis();

   if ((currentMillis - timeUpdate) < 3000){
    syncPrint ();
   }
   
   if ((currentMillis - timeUpdate) > updateDelay) {
   timeClient.updateTime();
   timeUpdate = millis ();
   }
  
  if ((currentMillis - clockUpdate) >= clockDelay ) {
  
 
  timePrint ();
 
  clockUpdate = millis ();
  }
   display.display();
}

void timePrint () {

//  String time = timeClient.getFormattedTime();
  String H = timeClient.getHours();
  String M = timeClient.getMinutes();
  String S = timeClient.getSeconds();
  display.clearDisplay();
  
  display.setCursor(1,24);
//  display.print(time);
  display.setTextSize(3);
  display.print(H); 
//  display.setTextSize(2);
//  display.print("-"); 
  display.setCursor(47,24);
  display.setTextSize(3);
  display.print(M);
  display.setTextSize(1);
  display.setCursor(35,24);
  display.print(S);
  display.display ();
  
}

void syncPrint () {
//   display.clearDisplay();
   display.setTextSize(1);
   display.setCursor(0,0);
   display.print(utf8rus("Сверим часы с")); 
   display.setCursor(0,8);
   display.print("time.nist.gov"); 
   display.display ();
}
  

 

Доброго времени суток, где брать библиотеку для TimeClient.h ?

pigtail000
Offline
Зарегистрирован: 03.09.2019
pigtail000
Offline
Зарегистрирован: 03.09.2019

удалите плиз

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

pigtail000 пишет:

удалите плиз

каво?