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

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

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

Для русификации библиотеки 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.

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

Gogi пишет:

arduinec Грубо ответил. Я спрашивал не о дисплее а о матрице MAX7219.

Если матрица использует библиотеку Adafruit-GFX, то руссификация распространяется и на неё.

Gogi пишет:

Я не программист. Информация: Плата Arduino Uno. 8 матриц MAX7219 в 1 ряд.  DHT11, DS1307

Принято к сведению, но я спрашивал: что из ниже перечисленного удалось сделать:

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

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

Gogi
Offline
Зарегистрирован: 17.09.2017

Да матрица её использует-иначе бы на ней не было бы русского шрифта. (Видео:https://www.youtube.com/watch?v=x7MATkNGZt0)

Библиотека русифицирована. Для надёжности скачал вашу и всё сделал как описано.

Но куда вставлять команду: display.cp437(true); не понимаю и нужна ли она в моём случае?

Посмотрите скетч по ссылке. Результат тот же: знака градус нет.

Получилось у меня такое: методом тыка я нашёл Alt код Alt+192 он выводит на матрицу букву Б в нулевой степени-этот ноль похож на градус, но буква Б тут естественно не клеится.

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

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

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

Gogi пишет:

Но куда вставлять команду: display.cp437(true); не понимаю и нужна ли она в моём случае?

Команда скорее всего будет: matrix.cp437(true);
В старой библиотеке она не нужна, а в новой без неё не будет правильного отображения русских букв.

Gogi пишет:

Посмотрите скетч по ссылке. Результат тот же: знака градус нет.

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

У меня нет матрицы MAX7219, но на форуме её смогли руссифицировать - например здесь: http://arduino.ru/forum/programmirovanie/led-matritsa-max7219-maxmatrixl...

Gogi
Offline
Зарегистрирован: 17.09.2017

Команда скорее всего будет: matrix.cp437(true); В старой библиотеке она не нужна, а в новой без неё не будет правильного отображения русских букв. 

Русские буквы отображаются правильно. И этот пост я читал и пробовал с его библиотеками-резальтат тот же. И скетч этот работает. Хозяин помощи не просит(люди злые пошли нынче).

Извините не понял что нужно перебрать? В каком цикле? Я использовал таблицу символов Windows.

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

andriano пишет:

есть ли вообще символ градуса, и, если есть, между какими символами он находится.

В переделанном шрифте в glcdfont.c символ градуса имеет код 0xB0 (= 176 в десятичной системе).

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

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

В терминологии Ардуино массив знакогенератора называется фонтом. Т.е. нужно вывести для каждого из используемых фонтов все символы, начиная с первого (обычно это "пробел" - код 32) и заканчивая последним доступным символом (обычно 95, но возможны варианты).

Gogi
Offline
Зарегистрирован: 17.09.2017

arduinec]</p> <p>[quote=andriano пишет:

есть ли вообще символ градуса, и, если есть, между какими символами он находится.

В переделанном шрифте в glcdfont.c символ градуса имеет код 0xB0 (= 176 в десятичной системе).

Об этом я уже знаю

Gogi
Offline
Зарегистрирован: 17.09.2017

[quote=andriano]

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

В терминологии Ардуино массив знакогенератора называется фонтом. Т.е. нужно вывести для каждого из используемых фонтов все символы, начиная с первого (обычно это "пробел" - код 32) и заканчивая последним доступным символом (обычно 95, но возможны варианты).

Теоретически понятно. Но как практически это сделать что и куда писать

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

Gogi пишет:

Об этом я уже знаю

Ну так если есть знания и нет желания приводить свой скетч, то что от нас нужно?

Gogi
Offline
Зарегистрирован: 17.09.2017

arduinec пишет:

Gogi пишет:

Об этом я уже знаю

Ну так если есть знания и нет желания приводить свой скетч, то что от нас нужно?

Вы как то изъясняетесь не совсем понятно. Скетч я брал с этого форума ссылку на него я озвучил.

Он рабочий автор помощи не просит .Вы всё время боитесь или не хотите помоч.

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

Gogi пишет:

Вы всё время боитесь

Ой, боюсь-боюсь-боюсь... :)

Gogi
Offline
Зарегистрирован: 17.09.2017

arduinec пишет:

Gogi пишет:

Вы всё время боитесь

Ой, боюсь-боюсь-боюсь... :)

Так поможете или нет? А то вокруг да около... На Alt+127 закончило правильно показывать символы. Дальше пошли кракозябры. а потом русские буквы Знака градус до этого не было. Тут скетч :https://yadi.sk/d/fFLfhD103NmaAM

arduino328
Offline
Зарегистрирован: 01.09.2016

Gogi пишет:

На Alt+127 закончило правильно показывать символы.

На матрице нужно символы перебирать (как в посте #1 данной темы - там кстати все символы из glcdfont.c отображены), а не Alt с цифрами нажимать.

Gogi
Offline
Зарегистрирован: 17.09.2017

arduino328 пишет:

Gogi пишет:

На Alt+127 закончило правильно показывать символы.

На матрице нужно символы перебирать (как в посте #1 данной темы - там кстати все символы из glcdfont.c отображены), а не Alt с цифрами нажимать.

Так Alt c цифрами я в скетч вводил и заливал в ардуино-на матрице отображалось. Я бы как видел что каждый код обозначает. Alt+196 знак градуса но перед ним кракозябры.

arduino328
Offline
Зарегистрирован: 01.09.2016

Gogi пишет:

arduino328 пишет:

Gogi пишет:

На Alt+127 закончило правильно показывать символы.

На матрице нужно символы перебирать (как в посте #1 данной темы - там кстати все символы из glcdfont.c отображены), а не Alt с цифрами нажимать.

Так Alt c цифрами я в скетч вводил и заливал в ардуино-на матрице отображалось. Я бы как видел что каждый код обозначает. Alt+196 знак градуса но перед ним кракозябры.

Перебирать символы нужно программным путём, так как символы, отображаемые на экране монитора, и символы, выводимые матрицей, могут не совпадать.

Gogi
Offline
Зарегистрирован: 17.09.2017

arduino328 пишет:

Gogi пишет:

arduino328 пишет:

Gogi пишет:

На Alt+127 закончило правильно показывать символы.

На матрице нужно символы перебирать (как в посте #1 данной темы - там кстати все символы из glcdfont.c отображены), а не Alt с цифрами нажимать.

Так Alt c цифрами я в скетч вводил и заливал в ардуино-на матрице отображалось. Я бы как видел что каждый код обозначает. Alt+196 знак градуса но перед ним кракозябры.

Перебирать символы нужно программным путём, так как символы, отображаемые на экране монитора, и символы, выводимые матрицей, могут не совпадать.

Так я же ввожу их в скетч а потом заливаю в плату а плата выводит на матрицу. Скетч же и есть программа или я не понимаю чего-то.

arduino328
Offline
Зарегистрирован: 01.09.2016

Gogi пишет:

Так я же ввожу их в скетч а потом заливаю в плату а плата выводит на матрицу. Скетч же и есть программа или я не понимаю чего-то.

В скетчах Arduino IDE для строковых символов применяется кодировка UTF-8, в которой русские символы и символ градуса занимают по 2 байта - отсюда и все проблемы.

Gogi
Offline
Зарегистрирован: 17.09.2017

arduino328 пишет:

Gogi пишет:

Так я же ввожу их в скетч а потом заливаю в плату а плата выводит на матрицу. Скетч же и есть программа или я не понимаю чего-то.

В скетчах Arduino IDE для строковых символов применяется кодировка UTF-8, в которой русские символы и символ градуса занимают по 2 байта - отсюда и все проблемы.

Это можно как-то исправить? На видео ютубе видел знак градуса на такой матрице-но клиент не отзывается-забил на канал наверно.( Дошёл я до 295 по моему потом начали повторяться символы)

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

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

Завтра если время будет попробую вывести (раньше с наскока тоже не вышло - вывожу тока букву "С")

Gogi
Offline
Зарегистрирован: 17.09.2017

pilnikov пишет:

Завтра если время будет попробую вывести (раньше с наскока тоже не вышло - вывожу тока букву "С")

Спасибо заранее

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>


int pinCS = 16; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 1;
int numberOfVerticalDisplays = 4;

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);


int wait = 20; // In milliseconds

int spacer = 1;
int width = 5 + spacer; // The font width is 5 pixels

void setup() {

  matrix.begin();
  matrix.setRotation(matrix.getRotation() + 3); //1 - 90  2 - 180   3 - 270
  matrix.cp437(true);
  matrix.setTextSize(1);
  matrix.setTextWrap(false); // Allow text to run off right edge
  matrix.fillScreen(LOW);
  matrix.setCursor(1, 0);

  // Adjust to your own needs
  //  matrix.setPosition(0, 0, 0); // The first display is at <0, 0>
  //  matrix.setPosition(1, 1, 0); // The second display is at <1, 0>
  //  matrix.setPosition(2, 2, 0); // The third display is at <2, 0>
  //  matrix.setPosition(3, 3, 0); // And the last display is at <3, 0>
  //  ...
  //  matrix.setRotation(0, 2);    // The first display is position upside down
  //  matrix.setRotation(3, 2);    // The same hold for the last display
}

void loop()
{
  matrix.drawChar(7, 0, '5', HIGH, LOW, 1);
  matrix.drawChar(12, 0, 0xB0, HIGH, LOW, 1);
  matrix.drawChar(17, 0, 'C', HIGH, LOW, 1);
  matrix.write(); // Send bitmap to display
}

тока при чем тут русификатор?

Gogi
Offline
Зарегистрирован: 17.09.2017

Уважаемый, pilnikov. К сожалению я не программист, но если я правильно понял это скетч для вывода знака градус на MAX7219?

При компиляции этого скетча Arduino IDE выдаёт такую ошибку: GRADUS:20: error: 'class Max72xxPanel' has no member named 'begin'  

exit status 1 'class Max72xxPanel' has no member named 'begin'

(У меня плата Arduino UNO)

Я сделал так: 1)закомменторовал строку matrix.begin(); 2)поменял на  int pinCS = 10; // DIN 11, CLK 13  т.к. у меня матрица так подключена. 3) залил скетч в плату и получил вот что: статическое изображение.

Но дело в том что у меня строка бегущая и на русском языке вот в чём дело. Я не программист и не знаю как отобразить знак градуса именно в бегущей строке (скетч брал тут на форуме  http://bit.ly/2gUk99l

Вот этот бы "градус" да в этот скетч было бы классно. Спасибо огромное что откликнулись!!!

Может сможете мне помоч в этом вопросе?

 

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

 Пример вывода строки "Сегодня на улице 5оС"

uint8_t tmp_today = 5; //текущая температура

String str = "Сегодня на улице " + String(tmp_today) + "\x0B" + "C";

Gogi
Offline
Зарегистрирован: 17.09.2017

Сейчас попробую-это надо вставить в скетч бегущей строки?

tape = utf8rus((String)+"Время "+hour+":"+String(min1)+String(min2)+" Дата "+dayOfMonth+" "+month_str+" 20"+year+" "+dow_str+". Темп-ра "+temp_new+""\x0B"+C Влажность "+sensor.hum+"% Давление "+press_new+"Hg.");

написал так. выдаёт ошибку

KoJIxo3Huk
Offline
Зарегистрирован: 07.02.2017

  

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

". Темп-ра "+temp_new+"\x0B"+ "C Влажность "

Gogi
Offline
Зарегистрирован: 17.09.2017

Спасибо-получилось. Но рисует другой значок (ищу в таблице символов но найти не могу чтобы показать)

Похож на знак градуса но со стрелкой вправо и пишется внизу.

 

Темп-ра "+temp_new+"\xB80"+"C получилось пока с этим кодом ("в нулевой степени") нолик узкий и вверху.

 

 

Gogi
Offline
Зарегистрирован: 17.09.2017

Надо было написать ". Темп-ра "+temp_new+"\xB0"+ "C Влажность " тогда выходит знак градуса.

Добавил matrix.cp437(true); и в функции utf8rus() поставил эти два адреса 0x30; 0x70;

Всё получилось. Спасибо всем помогавшим!!!

Виктор66
Offline
Зарегистрирован: 29.10.2017

Здравствуйте. Принимайте новичка.

Спасибо вам за такой подарочек. Всё получилось с русификацией на 5110, кроме заглавной русской -Р-.

Эту букву просто игнорирует. Например в скетче -display.println(utf8rus("Юрик ШуРик"));  а на дисплее Юрик Шуик. Ну или вместо ПРИВЕТ пишет ПИВЕТ. надеюсь внятно объяснил.

Понятно,что -Р- можно написАть на анг.раскладке но всё же. А так всё отлично.

Вместо display.cp437(true); в каждом скетче, поправил  в самой библиотеке (Adafruit_GFX.cpp) строку 83|    _cp437    = true; (было 'false'). Так можно?

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

Виктор66 пишет:

Вместо display.cp437(true); в каждом скетче, поправил  в самой библиотеке (Adafruit_GFX.cpp) строку 83|    _cp437    = true; (было 'false'). Так можно?

Так тоже можно. Русская буква Р у меня отображается без проблем (скетч прилагается):

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

Adafruit_PCD8544 display = Adafruit_PCD8544(7,6,5,4,3);  // CLK,DIN,DC,CE,RST

void setup()
{
  display.begin();
  display.cp437(true);
  display.setContrast(50);

  display.clearDisplay();
  display.setTextColor(BLACK);
  display.setCursor(0,0);
  display.setTextSize(2);
  display.println(utf8rus("ПРИВЕТ"));
  display.println(utf8rus("ШуРик"));
  display.display();
}

void loop() {}

/* 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 >= 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; target = target + String(m);
  }
  return target;
}

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

Виктор66
Offline
Зарегистрирован: 29.10.2017

Возможно у меня какие-то траблы. Хотя библиотеку вроде брал с github и остальное всё работает.

Возможно потом разберусь, а пока не сильно то и перетружусь набрать анг. Р

Ваш скетч выдает то, что я и ожидал. Не заморачивайтесь )

И да, как вы заметили даже пропуска или кракозябры вместо Р нет.

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

Виктор66 пишет:

Возможно потом разберусь, а пока не сильно то и перетружусь набрать анг. Р

Если русская буква Р (в составе строки) попадает в функцию utf8rus(), то там можно сделать дополнительную проверку и сразу заменять её на английскую P.

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

arduinec пишет:

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

Была.

Если мне не изменяет память, буква "р" в альтернативной кодировке ГОСТ попадала на символ, который с точки зрения Майкрософт должен быть служебным. Радикальным образом решили эту проблему виндовой кодировкой - просто переместили всю кириллицу в другую часть таблицы. Как следствие получили несовпадение кодировок в GUI и консольных приложениях.

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

arduinec пишет:

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

display.println(utf8rus("Тест"));

Не получается использовать такую конструкцию при использовании класса для отрисовки кнопок

  String buttonText = utf8rus( "Вода" );
  
  buttons[0].initButton( 
    &tft, 
    85,                 // x
    85,                 // y
    129,                // w 
    129,                // h 
    COLOR1,             // outline
    WHITE,              // fill
    COLOR1,             // text color
    buttonText,         // text
    3                   // text size
  );
   
  buttons[0].drawButton();
C:\Program Files (x86)\Arduino\libraries\Adafruit_GFX/Adafruit_GFX.h:100:8: note:   no known conversion for argument 9 from 'String' to 'char*'
 
По всей видимости, нужно перевести String в char.
 
 
arduinec
Offline
Зарегистрирован: 01.09.2015

cyber-jet пишет:

По всей видимости, нужно перевести String в char.

Вариант utf8rus() с массивом char* приведен в посте #40 данной темы.

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

arduinec пишет:

Вариант utf8rus() с массивом char* приведен в посте #40 данной темы.

Спасибо! Это сэкономило мне время :)

bv7
Offline
Зарегистрирован: 09.07.2017

Выполнил все инструкции из поста 251 не могу победить кирилицу. Все равно иероглифы показывает. IDE 1.8.1

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

bv7 пишет:

Выполнил все инструкции из поста 251 не могу победить кирилицу. Все равно иероглифы показывает. IDE 1.8.1

Принято к сведению.

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

добавил в виндовый редактор шрифтов поддержку Adafruit classic. размер символов поддерживается любой, но для использования со стандартной библиотекой помните, что размер символов должен быть шириной 5 и высотой 7 точек. так же имя шрифта для стандартной библиотеки должно быть только font, количество символов 256 начиная с символа с кодом 0.

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

Мож у кого есть желание пошевелить мозгами? Помогите пожалуйста нубу адаптировать библиотеку GitHub - nickgammon/MAX7219_Dot_Matrix: Arduino library for MAX7219 display chip used with 8x8 dot-matrix display под поддержку Adafruit GFX (Правильно выполнить наследование класса Adafruit GFX).

Спасибо.

 
 

 

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

Насколько я понял эта библиотека работает с матрицей, а не с TFT экраном. А библиотека Adafruit GFX работает ЕНИМП исключительно с экранами. Так что не получится ужа с ежом скрестить.

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

Неправильно вы поняли

This is the core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.). It needs to be paired with a hardware-specific library for each display device we carry (to handle the lower-level functions).

Это основная графическая библиотека для всех наших дисплеев, обеспечивающая общий набор графических примитивов (точек, линий, кругов и т. Д.). Он должен быть сопряжен с аппаратной библиотекой для каждого устройства отображения, которое мы переносим (для обработки функций нижнего уровня).
blackbird5
Offline
Зарегистрирован: 16.12.2016

Но только в том случае если библиотека конкретного устройства изначально написана как наследование этому классу. В Вашем же случае библиотека изначально отдельная....

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

Кто мешает переписать? Или "библиотека" - это нечто фундаментальное и модернизации не подлежит?

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

blackbird5 пишет:

У вас как с ООП? Если никак, то продолжать на эту тему я думаю не стОит.

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

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

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

А вы неправильно написали свой пост изначальный. ))

Надо было вместо "помогите нубу адаптировать", написать "кто напишет библиотеку на мое железо с нуля под Адафруит".

Тогда бы и вопросов не возникло )))

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

pilnikov пишет:

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

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