Для русификации библиотеки Adafruit-GFX требуется:
- скачать любой из приведённых ниже архивов;
- заменить файл glcdfont.c в Adafruit-GFX;
- добавить функцию utf8rus() в скетч;
- вставить в начале скетча команду: display.cp437(true);
Применять функцию utf8rus() можно внутри команд печати строк: display.println(utf8rus("Тест"));
В архивах примеры и библиотеки, различающиеся по виду дисплея:
Более подробная информация в предыдущих постах.
Например:
В посте 27 демонстрируется скетч, с помощью которого можно редактировать шрифты (в том числе и в glcdfont.c).
В посте 40 приводится вариант utf8rus() с экономным использованием оперативной памяти.
В посте 46 показан 2.8" TFT Touch Shield для Uno и Mega, и прилагается полный набор библиотек и примеров для него.
В посте 80 описаны изменения в шрифте для проекта Transistor Tester (http://arduino.ru/forum/proekty/transistor-tester-arduino).
В посте 379 дополнительно приведён скетч для демонстрации динамических эффектов из символов, содержащихся в шрифте.
В посте 399 приводится скетч с функцией utf8rus2hex(), которая перекодирует русские буквы и преобразует их в строчные HEX-символы.
В разделе "Программирование" половина первой страницы в приклееных темах. Лучше бы отдельный раздел создали и туда наиболее популярные темы переместили.
Используя собственный код из поста #40 научил функцию utf8rus() работать со строками, размещёнными в PROGMEM.
Для сохранения перекодированной строки нужно создать в глобальных переменных массив char. Длина массива определяется исходя из максимального размера строки, выводимой на дисплей.
В исходном варианте дисплей OLED 0.96 имеет ширину 128 пикселей. Ширина каждой буквы составляет 5 пикселей плюс интервал между буквами (6-й пиксель). В итоге, поделив 128 на 6, получаем, что максимальная длина выводимой строки составляет 21 символ плюс ещё один знак для нулевого символа конца строки.
Чтобы не выскочить за пределы массива в функцию встроена проверка на превышение максимального размера строки (более длинная строка просто отсекается).
По аналогии с PROGMEM-функциями к utf8rus тоже была добавлена буква _P.
#define maxString 21
char target[maxString + 1] = "";
char *utf8rus_P(const char *source)
{
char m[2] = { '0', '\0' };
int j = 0;
unsigned char n = 1;
strcpy(target, "");
while (1) {
n = pgm_read_byte(source); source++;
if (n >= 0xC0) {
switch (n) {
case 0xD0: {
n = pgm_read_byte(source); source++;
if (n == 0x81) { n = 0xA8; break; }
if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
break;
}
case 0xD1: {
n = pgm_read_byte(source); source++;
if (n == 0x91) { n = 0xB8; break; }
if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
break;
}
}
}
if (n == 0) break;
m[0] = n; strcat(target, m);
j++; if (j >= maxString) break;
}
return target;
}
Для русификации библиотеки Adafruit-GFX требуется:
- скачать приложенный архив;
- заменить файл glcdfont.c в Adafruit-GFX;
- добавить функцию utf8rus_P() в скетч;
- вставить в начале скетча команду: display.cp437(true);
Применять функцию utf8rus_P() можно внутри команд печати строк: display.println(utf8rus_P(Stroka));
использую код из 401 поста. И возникли проблемы. Если вызывать utf8rus из loop все прекрасно работает. Если же я вызывают utf8rus из другой функции, а затем эту фукнцию из loop. То вместо русских букв ничего нет. Причем не кракозябры, а именно ничего нет.
#include <Adafruit_CCS811.h>
#include "HDC1080JS.h"
#include "Wire.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <Fonts/rus5x7.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Adafruit_CCS811 ccs;
HDC1080JS tempsensor;
void setup() {
display.cp437(true);
Serial.begin(9600);
Wire.begin();
Wire.setClock(400000); //set clock speed for I2C bus to maximum allowed for HDC1080
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
Serial.println("CCS811 test");
pinMode(2, INPUT);
tempsensor = HDC1080JS();
tempsensor.config();
if (!ccs.begin()) {
Serial.println("Failed to start sensor! Please check your wiring.");
while (1);
}
//calibrate temperature sensor
while (!ccs.available());
float temp = ccs.calculateTemperature();
ccs.setTempOffset(temp - 25.0);
}
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;
}
void loop() {
if (digitalRead(2) == HIGH)
edin();
if (digitalRead(2) == LOW)
chered();
}
void chered()
{
display.clearDisplay();
tempsensor.readTempHumid();
float temp = tempsensor.getTemp();
float humid = tempsensor.getRelativeHumidity();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(20, 0);
display.print(utf8rus("ТЕМПЕРАТУРА"));
display.setCursor(0, 16);
display.print(temp);
display.print("\xB0");
display.print("C");
display.display();
delay(5000);
display.clearDisplay();
display.setCursor(20, 0);
display.setTextSize(2);
display.println(utf8rus("ВЛАЖНОСТЬ"));
display.setCursor(0, 16);
display.setTextSize(3);
display.print(humid);
display.print("%");
display.display();
delay(5000);
if (ccs.available()) {
if (!ccs.readData()) {
display.clearDisplay();
display.setCursor(20, 0);
display.setTextSize(2);
display.println(utf8rus("СОДЕРЖАНИЕ CO2"));
display.setTextSize(3);
display.print(ccs.geteCO2());
display.print("ppm");
display.display();
delay(5000);
display.clearDisplay();
display.setCursor(20, 0);
display.setTextSize(1);
display.println(utf8rus("СОДЕРЖАНИЕ ЛОВ"));
display.setCursor(0, 16);
display.setTextSize(3);
display.print(ccs.getTVOC());
display.print("ppb");
display.display();
delay(5000);
}
else {
display.setTextSize(2);
display.setCursor(0, 0);
display.print(utf8rus("css error"));
while (1);
}
}
}
void edin()
{
display.clearDisplay();
tempsensor.readTempHumid();
float temp = tempsensor.getTemp();
float humid = tempsensor.getRelativeHumidity();
display.setTextColor(WHITE);
display.drawFastHLine(0, 31, 128, 1);
display.drawFastVLine(63, 0, 64, 1);
display.setTextSize(1);
display.setCursor(0, 0);
display.print(utf8rus("Темп., "));
display.print("\xB0");
display.print("C");
display.setCursor(0, 10);
display.setTextSize(2);
display.print(temp);
display.setCursor(73, 0);
display.setTextSize(1);
display.print(utf8rus("Влажн., %"));
display.setTextSize(2);
display.setCursor(68, 10);
display.print(humid);
if (ccs.available()) {
// float temp = ccs.calculateTemperature();
if (!ccs.readData()) {
display.setCursor(0, 56);
display.setTextSize(1);
display.print(utf8rus("CO2, ppm"));
display.setTextSize(2);
display.setCursor(10, 39);
display.print(ccs.geteCO2());
display.setCursor(73, 56);
display.setTextSize(1);
display.print(utf8rus("TVOC, ppb"));
display.setTextSize(2);
display.setCursor(75, 39);
display.print(ccs.getTVOC());
display.display();
}
else {
//Serial.println("ERROR!");
display.setTextSize(2);
display.setCursor(0, 0);
display.print(utf8rus("css error"));
while (1);
}
}
delay(5000);
}
использую код из 401 поста. И возникли проблемы. Если вызывать utf8rus из loop все прекрасно работает. Если же я вызывают utf8rus из другой функции, а затем эту фукнцию из loop. То вместо русских букв ничего нет. Причем не кракозябры, а именно ничего нет.
Вероятнее всего String что-то портит в памяти. Лучше использовать utf8rus() из поста #40.
Немного преобразовал код и всё стало отображаться.
Автору огромное спасибо!!! Русифицировал дисплей 2,4" на 9341 с библиотекой SPFD5408-master. Там в библиотеке SPFD5408_Adafruit_GFX.h используется такой же файл, как у автора- glcdfont.c. Я его заменил и все заработало!!! ) Еще раз, arduinec, огромное спасибо за труды и ответы на вопросы!
С какой версии библиотеки Adafruit-GFX, не работает первый способ русификации?
Перепробовал кучу вариантов. Пробовал ставить самую последнюю версию библиотеки и применять utf8rus2.
и функцию display.cp437(true); скетч с ней не компилируется. без неё компиляция завершается но результата нет. Перепробовал несколько библиотек из архива 15го и 17 года( все перепробовать нереально) с первой версией файла utf8rus. Тоже безрезультатно. И я мог бы сослаться на свою некомпетентность, если бы у меня не получалось русифицировать эту библиотеку ранее. Сейчас же хоть убей не могу. Все исходные те же, кроме новой версии IDE и новых библиотек. К стате ранее, результата добился без функции display.cp437. Отсюда делаю вывод, что раньше работал со старой 255 символьной библиотекой. К стате, пока не обновил IDE и библиотеки с ним, заметил, что русский шрифт выводился, но совсем не то что вводилось с клавиатуры.
Так отображается русский набор, когда функция utf8rus. вложена в папку со скетчем но не прописана внутри команды String, или когда вообще без неё и в папке тоже.
Так ровно те же буквы с добавленной функцией . внутри команды и вложенной в папку со скетчем
Открыв файл шрифта, который скопирован в библиотеку с архива, в редакторе, видно что русские символы там присутствуют
Но так же выяснилось следующее что цифры которые присутствуют в этом шрифте, не выводятся. а выводятся другие. видно на примере цифры 2
Из чего напрашивается вопрос. Если файл glcdfont в библиотеке заменён на одноимённый из архива, то каким образом подключается какой то другой шрифт? Скорее всего базовый из библиотеки. Что я и проверил открыв базовый шрифт библиотеки в редакторе.
Вывод: даже заменив файл glcdfont в библиотеке, подключается всё равно базовый. Вопрос почему? где ещё могут хранится следы этого шрифта?
Кое что нарыл. Оказывается Файл со шрифтом нужно менять не только в папке libraries, Adafruit-GFX-Library. Но и в папке portable,sketchbook,libraries,Adafruit_GFX_Library. Которая присутствует в каталоге ideV3. Но проблемма полностью не решилась. Теперь русские символы выводятся, но не те которые вводишь с клавиатуры. Например вместо "вск" выводится "гтл".
Если я правильно понимаю, то если не применять функцию display.cp437(true); , то не будет отображаться только символ градуса?
Символы, расположенные после символа градуса (русские буквы в частности), будут отображаться со смещением на 1 символ - что и прозошло в вышеприведенном примере.
Оказывается Файл со шрифтом нужно менять не только в папке libraries, Adafruit-GFX-Library. Но и в папке portable,sketchbook,libraries,Adafruit_GFX_Library. Которая присутствует в каталоге ideV3.
Файл со шрифтом нужно менять в той библиотеке Adafruit-GFX, которую использует компилятор Arduino IDE (можно посмотреть по логам).
та же проблема что и у nalbagar вначале. Вроде всё переделал, все способы с первой страницы этого форума...Всё равно крягазябра, причём символы кряказябры те же что и у nalbagar на месте тех же букв-проверял. Что это ещё может быть?
Тут форум по программированию. Если проблемы с кодом, его нужно показать в читабельно-понятном виде что бы искать причину проблемы а не где начало где пипец.
Вставил код в скобки, просто их сразу не заметил.
Легче стало?
Кто-нибудь с проблемой поможет или Вам ещё вензеля деревянные надо вырезать, али ещё какие-то украшательства?
Spa5 - не компилируется
Мужик, до тебя похоже плохо доходит.
Пишу как для идиотов - чтобы кто-то помог тебе найти ошибки в программе, ее текст надо показать целиком.
Можешь выкинуть все лишнее, но программа должна быть полной, чтобы любой мог скачать ее, скомпилировать и запустить.
А пока ты постишь обрывки - помощи не будет, можешь не тратить время
Очередным мученикам на заметку! При проверке адресов используемых библиотек обратите внимание на папку TEMP на диске С в юзерах. Только после чистки этой папки кракозябры пропали.
А ещё лучше каждую секунду менять значение от минимально возможного до максимального, не забывая о том что количество символов будет меняться и лишнее надо затирать, но это уже другая тема.
Да. Пистрелка. Как оказалось, Адафрукт не умеет центрировать
tft.drawCentreString("Text", 120, 14, 2);
Буду искать другие библиотеки
Да. помню что-то подобное. Но чем менять библиотеку - проще написать свою функцию центрирования. Для этого нужно только определить ширину текста в пикселях. Насколько я помню, в Адафруте есть под это функция.
А если нет отдельной функции для строки - то ширина каждого символа точно есть, просто суммируешь все символы и потом сдвигаешь строчку влево на половину ширины - вот и все "центрирование"
Для того чтоб напечатать текст по центру на самом деле и функции писать не надо.
Достаточно правильно сформировать вывод символов в зависимости от содержимого. Да и иногда эстетичней (с моей точки зрения) расстояние от точки до символом лучше уменьшить.
Вот три примера на одном скрине когда это расстояние убрать не только можно но и нужно:
А на следующем скрине пример типа центрованного текста с этой же библиотекой:
Решил русифицировать свой TFT на ST7789(240х240) способом ТС arduinec. Использовал корректировку utf8rus из поста nalbagar #416, где дополнительно заменил 0xB8 на 0xB7 - для корректного отображения "ё", и замечание arduinec в посте #418. Для вывода на дисплей использованы - библиотека Adafruit_GFX_AS.h и SPI.h в составе сборника Arduino_STM32-master(https://github.com/ynkady/Arduino_STM32-master) с дополнением Arduino-ST7789.h (https://github.com/ananevilya/Arduino-ST7789-Library). Контроллер - Blue Pill STM32F103C8T6 board + Arduino IDE. Спасибо, все заработало.
По размышлении понял, что вносить исправления в код процедуры utf8rus - неправильно, т.к. она будет генерировать нестандартные коды русских букв, а это не есть хорошо. Чтобы сохранить правильный вывод на дисплей, в файле glcdfont.c переставил строки с байтами бито-пикселей. Если, условно, нумеровать их от 0 до 255, то строку 255(FF) перенес и вставил на место 224(E0), а 185(E9) - на место 184(E8). Буквы(латинские и русские) выводятся на дисплей и через Serial правильно. Остальные символы - не проверял, руки не дошли.
Решил русифицировать свой TFT на ST7789(240х240) способом ТС arduinec. Использовал корректировку utf8rus из поста nalbagar #416, где дополнительно заменил 0xB8 на 0xB7 - для корректного отображения "ё"
добрый день! использую библиотеку #include <TFT_eSPI.h> для дисплея ST7789 и ESP32 не получается вывести русский шрифт.
Помогите, пожалуйста!!!
Надо найти тему с обсуждением этой библиотеки. Если таковой нет, создать. Ну и раз уже тут засветили, то можно поместить ссылку на тему. И там уже показать что получается при попытке вывести текст в кириллице.
Краткие итоги предыдущих 400 постов
Для русификации библиотеки 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).
В посте 379 дополнительно приведён скетч для демонстрации динамических эффектов из символов, содержащихся в шрифте.
В посте 399 приводится скетч с функцией utf8rus2hex(), которая перекодирует русские буквы и преобразует их в строчные HEX-символы.
arduinec Спасибо большое работает на ура)
Топик, по моему, заслужил что-бы его приклеели!
Топик, по моему, заслужил что-бы его приклеели!
В разделе "Программирование" половина первой страницы в приклееных темах. Лучше бы отдельный раздел создали и туда наиболее популярные темы переместили.
Используя собственный код из поста #40 научил функцию utf8rus() работать со строками, размещёнными в PROGMEM.
Для сохранения перекодированной строки нужно создать в глобальных переменных массив char. Длина массива определяется исходя из максимального размера строки, выводимой на дисплей.
В исходном варианте дисплей OLED 0.96 имеет ширину 128 пикселей. Ширина каждой буквы составляет 5 пикселей плюс интервал между буквами (6-й пиксель). В итоге, поделив 128 на 6, получаем, что максимальная длина выводимой строки составляет 21 символ плюс ещё один знак для нулевого символа конца строки.
Чтобы не выскочить за пределы массива в функцию встроена проверка на превышение максимального размера строки (более длинная строка просто отсекается).
По аналогии с PROGMEM-функциями к utf8rus тоже была добавлена буква _P.
#define maxString 21 char target[maxString + 1] = ""; char *utf8rus_P(const char *source) { char m[2] = { '0', '\0' }; int j = 0; unsigned char n = 1; strcpy(target, ""); while (1) { n = pgm_read_byte(source); source++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = pgm_read_byte(source); source++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = pgm_read_byte(source); source++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } if (n == 0) break; m[0] = n; strcat(target, m); j++; if (j >= maxString) break; } return target; }Демонстрационный код для дисплея OLED 0.96:
#include <avr/pgmspace.h> #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // software SPI: #define OLED_CLK 13 // D0 #define OLED_MOSI 12 // D1 #define OLED_RESET 11 // RES #define OLED_DC 10 // DC #define OLED_CS 9 // CS #define maxString 21 char target[maxString + 1] = ""; const char Stroka31[] PROGMEM = "АБВГДЕЖЗИЙКЛМНОП"; const char Stroka32[] PROGMEM = "РСТУФХЦЧШЩЪЫЬЭЮЯ"; const char Stroka33[] PROGMEM = "абвгдежзийклмноп"; const char Stroka34[] PROGMEM = "рстуфхцчшщъыьэюя"; const char Stroka35[] PROGMEM = "Ёё123ABCabc!@#\xBC\xBD"; const char Stroka36[] PROGMEM = "10\x83 10\x8A\x82 10\x81\x80 2\x85"; const char Stroka41[] PROGMEM = "Размер шрифта 1"; const char Stroka42[] PROGMEM = "Размер 2"; const char Stroka43[] PROGMEM = "Разм 3"; const char Stroka51[] PROGMEM = "Строка более 21 символа длиной"; const char Stroka52[] PROGMEM = "Stroka bolee 21 simvola dlinoj"; unsigned char i1,i2,c3; Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); void setup(){ display.begin(SSD1306_SWITCHCAPVCC); 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_P(Stroka31)); display.println(utf8rus_P(Stroka32)); display.println(utf8rus_P(Stroka33)); display.println(utf8rus_P(Stroka34)); display.println(utf8rus_P(Stroka35)); display.println(utf8rus_P(Stroka36)); display.display(); } void TEST_display_4() { display.clearDisplay(); display.setTextColor(WHITE); display.setCursor(0,0); display.setTextSize(1); display.println(utf8rus_P(Stroka41)); display.setTextSize(2); display.println(utf8rus_P(Stroka42)); display.setTextSize(3); display.println(utf8rus_P(Stroka43)); display.display(); } void TEST_display_5() { display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(0,0); display.println(utf8rus_P(Stroka51)); display.println(utf8rus_P(Stroka52)); display.display(); } /* Recode russian fonts from UTF-8 to Windows-1251 */ char *utf8rus_P(const char *source) { char m[2] = { '0', '\0' }; int j = 0; unsigned char n = 1; strcpy(target, ""); while (1) { n = pgm_read_byte(source); source++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = pgm_read_byte(source); source++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = pgm_read_byte(source); source++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } if (n == 0) break; m[0] = n; strcat(target, m); j++; if (j >= maxString) break; } return target; }Архив с кодом и библиотеками:
https://yadi.sk/d/Tay6fBw-Qoo45w
Для русификации библиотеки Adafruit-GFX требуется:
- скачать приложенный архив;
- заменить файл glcdfont.c в Adafruit-GFX;
- добавить функцию utf8rus_P() в скетч;
- вставить в начале скетча команду: display.cp437(true);
Применять функцию utf8rus_P() можно внутри команд печати строк:
display.println(utf8rus_P(Stroka));
Добрый день,
использую код из 401 поста. И возникли проблемы. Если вызывать utf8rus из loop все прекрасно работает. Если же я вызывают utf8rus из другой функции, а затем эту фукнцию из loop. То вместо русских букв ничего нет. Причем не кракозябры, а именно ничего нет.
#include <Adafruit_CCS811.h> #include "HDC1080JS.h" #include "Wire.h" #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> //#include <Fonts/rus5x7.h> #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); Adafruit_CCS811 ccs; HDC1080JS tempsensor; void setup() { display.cp437(true); Serial.begin(9600); Wire.begin(); Wire.setClock(400000); //set clock speed for I2C bus to maximum allowed for HDC1080 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); Serial.println("CCS811 test"); pinMode(2, INPUT); tempsensor = HDC1080JS(); tempsensor.config(); if (!ccs.begin()) { Serial.println("Failed to start sensor! Please check your wiring."); while (1); } //calibrate temperature sensor while (!ccs.available()); float temp = ccs.calculateTemperature(); ccs.setTempOffset(temp - 25.0); } 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; } void loop() { if (digitalRead(2) == HIGH) edin(); if (digitalRead(2) == LOW) chered(); } void chered() { display.clearDisplay(); tempsensor.readTempHumid(); float temp = tempsensor.getTemp(); float humid = tempsensor.getRelativeHumidity(); display.setTextColor(WHITE); display.setTextSize(2); display.setCursor(20, 0); display.print(utf8rus("ТЕМПЕРАТУРА")); display.setCursor(0, 16); display.print(temp); display.print("\xB0"); display.print("C"); display.display(); delay(5000); display.clearDisplay(); display.setCursor(20, 0); display.setTextSize(2); display.println(utf8rus("ВЛАЖНОСТЬ")); display.setCursor(0, 16); display.setTextSize(3); display.print(humid); display.print("%"); display.display(); delay(5000); if (ccs.available()) { if (!ccs.readData()) { display.clearDisplay(); display.setCursor(20, 0); display.setTextSize(2); display.println(utf8rus("СОДЕРЖАНИЕ CO2")); display.setTextSize(3); display.print(ccs.geteCO2()); display.print("ppm"); display.display(); delay(5000); display.clearDisplay(); display.setCursor(20, 0); display.setTextSize(1); display.println(utf8rus("СОДЕРЖАНИЕ ЛОВ")); display.setCursor(0, 16); display.setTextSize(3); display.print(ccs.getTVOC()); display.print("ppb"); display.display(); delay(5000); } else { display.setTextSize(2); display.setCursor(0, 0); display.print(utf8rus("css error")); while (1); } } } void edin() { display.clearDisplay(); tempsensor.readTempHumid(); float temp = tempsensor.getTemp(); float humid = tempsensor.getRelativeHumidity(); display.setTextColor(WHITE); display.drawFastHLine(0, 31, 128, 1); display.drawFastVLine(63, 0, 64, 1); display.setTextSize(1); display.setCursor(0, 0); display.print(utf8rus("Темп., ")); display.print("\xB0"); display.print("C"); display.setCursor(0, 10); display.setTextSize(2); display.print(temp); display.setCursor(73, 0); display.setTextSize(1); display.print(utf8rus("Влажн., %")); display.setTextSize(2); display.setCursor(68, 10); display.print(humid); if (ccs.available()) { // float temp = ccs.calculateTemperature(); if (!ccs.readData()) { display.setCursor(0, 56); display.setTextSize(1); display.print(utf8rus("CO2, ppm")); display.setTextSize(2); display.setCursor(10, 39); display.print(ccs.geteCO2()); display.setCursor(73, 56); display.setTextSize(1); display.print(utf8rus("TVOC, ppb")); display.setTextSize(2); display.setCursor(75, 39); display.print(ccs.getTVOC()); display.display(); } else { //Serial.println("ERROR!"); display.setTextSize(2); display.setCursor(0, 0); display.print(utf8rus("css error")); while (1); } } delay(5000); }Выяснил в чем глюк. Перекодировщик так реагивет на пробел между русскими буквами. То есть после :
display.print(utf8rus("Влажн., %"));Все нормально.
А вот после:
display.println(utf8rus("СОДЕРЖАНИЕ ЛОВ"));Пропадают русские буквы везде.
использую код из 401 поста. И возникли проблемы. Если вызывать utf8rus из loop все прекрасно работает. Если же я вызывают utf8rus из другой функции, а затем эту фукнцию из loop. То вместо русских букв ничего нет. Причем не кракозябры, а именно ничего нет.
Вероятнее всего String что-то портит в памяти. Лучше использовать utf8rus() из поста #40.
Немного преобразовал код и всё стало отображаться.
//#include <Adafruit_CCS811.h> //#include "HDC1080JS.h" #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); //Adafruit_CCS811 ccs; //HDC1080JS tempsensor; #define maxString 21 char target[maxString + 1] = ""; void setup() { display.cp437(true); Serial.begin(9600); Wire.begin(); // Wire.setClock(400000); //set clock speed for I2C bus to maximum allowed for HDC1080 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); Serial.println("CCS811 test"); pinMode(2, INPUT); // tempsensor = HDC1080JS(); // tempsensor.config(); // if (!ccs.begin()) { // Serial.println("Failed to start sensor! Please check your wiring."); // while (1); // } //calibrate temperature sensor // while (!ccs.available()); // float temp = ccs.calculateTemperature(); // ccs.setTempOffset(temp - 25.0); } 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; } void loop() { // if (digitalRead(2) == HIGH) edin(); delay(5000); // test // if (digitalRead(2) == LOW) chered(); delay(5000); // test } void chered() { display.clearDisplay(); // tempsensor.readTempHumid(); // float temp = tempsensor.getTemp(); // float humid = tempsensor.getRelativeHumidity(); float temp = 12; float humid = 34; display.setTextColor(WHITE); display.setTextSize(2); display.setCursor(20, 0); display.print(utf8rus("ТЕМПЕРАТУРА")); display.setCursor(0, 16); display.print(temp); display.print("\xB0"); display.print("C"); display.display(); delay(5000); display.clearDisplay(); display.setCursor(20, 0); display.setTextSize(2); display.println(utf8rus("ВЛАЖНОСТЬ")); display.setCursor(0, 16); display.setTextSize(3); display.print(humid); display.print("%"); display.display(); delay(5000); // if (ccs.available()) { // if (!ccs.readData()) { display.clearDisplay(); display.setCursor(20, 0); display.setTextSize(2); display.println(utf8rus("СОДЕРЖАНИЕ CO2")); display.setTextSize(3); // display.print(ccs.geteCO2()); display.print(56); display.print("ppm"); display.display(); delay(5000); display.clearDisplay(); display.setCursor(20, 0); display.setTextSize(1); display.println(utf8rus("СОДЕРЖАНИЕ ЛОВ")); display.setCursor(0, 16); display.setTextSize(3); // display.print(ccs.getTVOC()); display.print(78); display.print("ppb"); display.display(); delay(5000); // } // else { // display.setTextSize(2); // display.setCursor(0, 0); // display.print(utf8rus("css error")); // while (1); // } // } } void edin() { display.clearDisplay(); // tempsensor.readTempHumid(); // float temp = tempsensor.getTemp(); // float humid = tempsensor.getRelativeHumidity(); float temp = 12; float humid = 34; display.setTextColor(WHITE); display.drawFastHLine(0, 31, 128, 1); display.drawFastVLine(63, 0, 64, 1); display.setTextSize(1); display.setCursor(0, 0); display.print(utf8rus("Темп., ")); display.print("\xB0"); display.print("C"); display.setCursor(0, 10); display.setTextSize(2); display.print(temp); display.setCursor(73, 0); display.setTextSize(1); display.print(utf8rus("Влажн., %")); display.setTextSize(2); display.setCursor(68, 10); display.print(humid); // if (ccs.available()) { // float temp = ccs.calculateTemperature(); // if (!ccs.readData()) { display.setCursor(0, 56); display.setTextSize(1); display.print(utf8rus("CO2, ppm")); display.setTextSize(2); display.setCursor(10, 39); // display.print(ccs.geteCO2()); display.print(56); display.setCursor(73, 56); display.setTextSize(1); display.print(utf8rus("TVOC, ppb")); display.setTextSize(2); display.setCursor(75, 39); // display.print(ccs.getTVOC()); display.print(78); display.display(); // } // else { //Serial.println("ERROR!"); // display.setTextSize(2); // display.setCursor(0, 0); // display.print(utf8rus("css error")); // while (1); // } // } delay(5000); }Автору огромное спасибо!!! Русифицировал дисплей 2,4" на 9341 с библиотекой SPFD5408-master. Там в библиотеке SPFD5408_Adafruit_GFX.h используется такой же файл, как у автора- glcdfont.c. Я его заменил и все заработало!!! ) Еще раз, arduinec, огромное спасибо за труды и ответы на вопросы!
Здравствуйте.
С какой версии библиотеки Adafruit-GFX, не работает первый способ русификации?
Перепробовал кучу вариантов. Пробовал ставить самую последнюю версию библиотеки и применять utf8rus2.
и функцию display.cp437(true); скетч с ней не компилируется. без неё компиляция завершается но результата нет. Перепробовал несколько библиотек из архива 15го и 17 года( все перепробовать нереально) с первой версией файла utf8rus. Тоже безрезультатно. И я мог бы сослаться на свою некомпетентность, если бы у меня не получалось русифицировать эту библиотеку ранее. Сейчас же хоть убей не могу. Все исходные те же, кроме новой версии IDE и новых библиотек. К стате ранее, результата добился без функции display.cp437. Отсюда делаю вывод, что раньше работал со старой 255 символьной библиотекой. К стате, пока не обновил IDE и библиотеки с ним, заметил, что русский шрифт выводился, но совсем не то что вводилось с клавиатуры.

Результат со старой библиотекой
и тщетные попытки с новой.
Если я правильно понимаю, то если не применять функцию display.cp437(true); , то не будет отображаться только символ градуса?
Так отображается русский набор, когда функция utf8rus. вложена в папку со скетчем но не прописана внутри команды String, или когда вообще без неё и в папке тоже.
Так ровно те же буквы с добавленной функцией . внутри команды и вложенной в папку со скетчем
Открыв файл шрифта, который скопирован в библиотеку с архива, в редакторе, видно что русские символы там присутствуют
Но так же выяснилось следующее что цифры которые присутствуют в этом шрифте, не выводятся. а выводятся другие. видно на примере цифры 2
Из чего напрашивается вопрос. Если файл glcdfont в библиотеке заменён на одноимённый из архива, то каким образом подключается какой то другой шрифт? Скорее всего базовый из библиотеки.
Что я и проверил открыв базовый шрифт библиотеки в редакторе.
Вывод: даже заменив файл glcdfont в библиотеке, подключается всё равно базовый. Вопрос почему? где ещё могут хранится следы этого шрифта?
Кое что нарыл. Оказывается Файл со шрифтом нужно менять не только в папке libraries, Adafruit-GFX-Library. Но и в папке portable,sketchbook,libraries,Adafruit_GFX_Library. Которая присутствует в каталоге ideV3. Но проблемма полностью не решилась. Теперь русские символы выводятся, но не те которые вводишь с клавиатуры. Например вместо "вск" выводится "гтл".
Ищем дальше.
И так. пришлось поменять в теле функции некоторые значения. Вычитал на форуме АМПЕРКИ.
Кирилица в Adafruit_GFX.h
Итог:
Всё выводится чётко. Спасибо всем! Особенно arduinec и
Securbond
Если я правильно понимаю, то если не применять функцию display.cp437(true); , то не будет отображаться только символ градуса?
Символы, расположенные после символа градуса (русские буквы в частности), будут отображаться со смещением на 1 символ - что и прозошло в вышеприведенном примере.
Оказывается Файл со шрифтом нужно менять не только в папке libraries, Adafruit-GFX-Library. Но и в папке portable,sketchbook,libraries,Adafruit_GFX_Library. Которая присутствует в каталоге ideV3.
Файл со шрифтом нужно менять в той библиотеке Adafruit-GFX, которую использует компилятор Arduino IDE (можно посмотреть по логам).
та же проблема что и у nalbagar вначале. Вроде всё переделал, все способы с первой страницы этого форума...Всё равно крягазябра, причём символы кряказябры те же что и у nalbagar на месте тех же букв-проверял. Что это ещё может быть?
Заработало, ошибка на деле была глупой-обращалось не к той библиотеке Adafruit-GFX
Индикатор
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println(utf8rus("АБВГДЕЖЗИЙКЛМНОП"));
…
m[0] = n; target = target + String(m);
}
Serial.print("target=");
Serial.println(target);
return target;
…
На мониторе СОМ порта
target=⸮⸮⸮⸮
На индикаторе 4-е буквы: НОПР
Как это вылечить?
Неумение правильно вставлять код код лечится здесь: http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...
Полезную информацию по другим вопросам можно получить здесь: http://arduino.ru/forum/obshchii/pesochnitsa-dlya-vsekh-novichkov
Благодарю за помощь, надо было просто нахрен послать!
Так так, что я слышу!? Знакомые нотки :).
Хотя уважаемый spa5, arduinec прав.
Тут форум по программированию. Если проблемы с кодом, его нужно показать в читабельно-понятном виде что бы искать причину проблемы а не где начало где пипец.
Благодарю за помощь, надо было просто нахрен послать!
собственно, это и произошло, вы просто не поняли...
#include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println(utf8rus("АБВГДЕЖЗИЙКЛМНОП")); … m[0] = n; target = target + String(m); } Serial.print("target="); Serial.println(target); return target; …Вставил код в скобки, просто их сразу не заметил.
Легче стало?
Кто-нибудь с проблемой поможет или Вам ещё вензеля деревянные надо вырезать, али ещё какие-то украшательства?
Spa5 - не компилируется
Мужик, до тебя похоже плохо доходит.
Пишу как для идиотов - чтобы кто-то помог тебе найти ошибки в программе, ее текст надо показать целиком.
Можешь выкинуть все лишнее, но программа должна быть полной, чтобы любой мог скачать ее, скомпилировать и запустить.
А пока ты постишь обрывки - помощи не будет, можешь не тратить время
Очередным мученикам на заметку! При проверке адресов используемых библиотек обратите внимание на папку TEMP на диске С в юзерах. Только после чистки этой папки кракозябры пропали.
400 постов прочесть не осилю. Имею такой вывод:
tft.setCursor(5, 5); tft.fillScreen(ST77XX_BLACK); tft.invertDisplay(true); tft.setTextColor(ST77XX_YELLOW); tft.setTextSize(0); tft.println(utf8rus("Привет!")); tft.setTextSize(3); tft.println(" 27.8°C");А на дисплее вот так:
Непонятно откуда берётся символ "B" и как его избежать?
Напечатай в строке только символ градуса и ничего больше, даже пробелы убери, покажи что получилось т будем смотреть что делать.
Печалька :(
Форумчане так старались, набивая эти посты :)
А если так?
tft.println(" 27.8\xB0C");
\xB0 выводит символ градуса (в прилагаемом шрифте)
//tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.println("°");============================
tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.println(utf8rus("°"))==================================
tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.println(" 27.8\xB0C");Если использовать вывод:
tft.println(utf8rus("27.8\xB0C"));То выводит точно также как на последнем скрине.
//tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.println("27.8\xB0C");====================================
//tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.println("27.8\xB0");================================
tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.println(utf8rus("27.8\xB0C"));=================================
tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.println(utf8rus("27.8\xB0"));В последнем примере, получается, "С" мешает.
На сколько я вижу, это "пристрелка" вывода значения температуры. Если ошибаюсь - дальше не читаем.
Даже без реальных показаний лучше печатать не строку целиком а сначала некую переменную int или float, а потом и символы.
Всё равно таким простым исходник не останется.
int16_t temp = 278; tft.cp437(true); tft.setCursor(10, 10); tft.fillScreen(ST77XX_BLACK); tft.setTextSize(3); tft.print(temp/10); tft.print("."); tft.print(temp%10); tft.print(utf8rus("\xB0")); tft.println("C");А ещё лучше каждую секунду менять значение от минимально возможного до максимального, не забывая о том что количество символов будет меняться и лишнее надо затирать, но это уже другая тема.
Да. Пистрелка. Как оказалось, Адафрукт не умеет центрировать
tft.drawCentreString("Text", 120, 14, 2);
Буду искать другие библиотеки
Да. Пистрелка. Как оказалось, Адафрукт не умеет центрировать
tft.drawCentreString("Text", 120, 14, 2);
Буду искать другие библиотеки
Да. помню что-то подобное. Но чем менять библиотеку - проще написать свою функцию центрирования. Для этого нужно только определить ширину текста в пикселях. Насколько я помню, в Адафруте есть под это функция.
А если нет отдельной функции для строки - то ширина каждого символа точно есть, просто суммируешь все символы и потом сдвигаешь строчку влево на половину ширины - вот и все "центрирование"
Для того чтоб напечатать текст по центру на самом деле и функции писать не надо.
Достаточно правильно сформировать вывод символов в зависимости от содержимого. Да и иногда эстетичней (с моей точки зрения) расстояние от точки до символом лучше уменьшить.
Вот три примера на одном скрине когда это расстояние убрать не только можно но и нужно:
А на следующем скрине пример типа центрованного текста с этой же библиотекой:
Ни одна библиотека не напишет сама проект.
Решил русифицировать свой TFT на ST7789(240х240) способом ТС arduinec. Использовал корректировку utf8rus из поста nalbagar #416, где дополнительно заменил 0xB8 на 0xB7 - для корректного отображения "ё", и замечание arduinec в посте #418. Для вывода на дисплей использованы - библиотека Adafruit_GFX_AS.h и SPI.h в составе сборника Arduino_STM32-master(https://github.com/ynkady/Arduino_STM32-master) с дополнением Arduino-ST7789.h (https://github.com/ananevilya/Arduino-ST7789-Library). Контроллер - Blue Pill STM32F103C8T6 board + Arduino IDE. Спасибо, все заработало.
По размышлении понял, что вносить исправления в код процедуры utf8rus - неправильно, т.к. она будет генерировать нестандартные коды русских букв, а это не есть хорошо. Чтобы сохранить правильный вывод на дисплей, в файле glcdfont.c переставил строки с байтами бито-пикселей. Если, условно, нумеровать их от 0 до 255, то строку 255(FF) перенес и вставил на место 224(E0), а 185(E9) - на место 184(E8). Буквы(латинские и русские) выводятся на дисплей и через Serial правильно. Остальные символы - не проверял, руки не дошли.
Ошибся в числах. В файле glcdfont.c переставил строки так: 255(FF) > 192(C0), 185(B9) > 184(B8).
Решил русифицировать свой TFT на ST7789(240х240) способом ТС arduinec. Использовал корректировку utf8rus из поста nalbagar #416, где дополнительно заменил 0xB8 на 0xB7 - для корректного отображения "ё"
Может проще в начале скетча вставить команду: display.cp437(true);
Для чего она нужна описано в посте #15 (http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafru...).
Если я правильно понимаю, то если не применять функцию display.cp437(true); , то не будет отображаться только символ градуса?
И все символы после него (в том числе русские буквы) будут смещены на 1 символ.
добрый день! использую библиотеку #include <TFT_eSPI.h> для дисплея ST7789 и ESP32 не получается вывести русский шрифт.
Помогите, пожалуйста!!!
В данной теме описывается как русифицировать библиотеку Adafruit-GFX.
добрый день! использую библиотеку #include <TFT_eSPI.h> для дисплея ST7789 и ESP32 не получается вывести русский шрифт.
Помогите, пожалуйста!!!
Надо найти тему с обсуждением этой библиотеки. Если таковой нет, создать. Ну и раз уже тут засветили, то можно поместить ссылку на тему. И там уже показать что получается при попытке вывести текст в кириллице.
Коли уж заглянул сюда, вот видос запилил на этой библиотеке. https://youtu.be/UvRmT0aR75o
При пояснении немгого заговаривался и некоторые детали передал не совсем корректно, но всё понял, осознал, каюсь, а видос из ютюба не выкинешь...
Здравствуйте ! спасибо за труды автору!
Удобная библиотека применение ей нашёл в бегущей строке.
Подскажите как можно увеличить количество применяемых символов в функцию utf8rus.
Там есть ограничение из-за типа переменной - char.
Подскажите как можно увеличить количество применяемых символов в функцию utf8rus.
Там есть ограничение из-за типа переменной - char.
поясните, как тип переменной char вам ограничивает число вимволов?
Я предположил - подскажите как лучше сделать?
максимум это 106 размер - #define maxString 106
С такой константой стабильная работа