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

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

Краткие итоги предыдущих 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-символы.

killspika
Offline
Зарегистрирован: 04.02.2019

arduinec Спасибо большое работает на ура)

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Топик, по моему, заслужил что-бы его приклеели!

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

xDriver пишет:

Топик, по моему, заслужил что-бы его приклеели!

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

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

Используя собственный код из поста #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));

kc_duke
Offline
Зарегистрирован: 23.04.2019

Добрый день,

использую код из 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);
}

 

kc_duke
Offline
Зарегистрирован: 23.04.2019

Выяснил в чем глюк. Перекодировщик так реагивет на пробел между русскими буквами. То есть после :


display.print(utf8rus("Влажн., %"));

Все нормально.

А вот после:

display.println(utf8rus("СОДЕРЖАНИЕ ЛОВ"));

Пропадают русские буквы везде.

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

kc_duke пишет:

использую код из 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);
}

 

Skiminok81
Offline
Зарегистрирован: 26.01.2018
Добрый день.
 
в Arduino IDE все хорошо работает.
Попытался сделать в PlatformIO не получается.
Выдает казябры. как будто-бы файл шрифтов не подключается.
Подскажите как подключить в PlatformIO?
 
Заранее благодарен за ответ.
lev2606
Offline
Зарегистрирован: 19.06.2019

Автору огромное спасибо!!! Русифицировал дисплей 2,4" на 9341 с библиотекой SPFD5408-master. Там в библиотеке SPFD5408_Adafruit_GFX.h используется такой же файл, как у автора- glcdfont.c. Я его заменил и все заработало!!! ) Еще раз, arduinec, огромное спасибо за труды и ответы на вопросы!

nalbagar
Offline
Зарегистрирован: 28.12.2017

Здравствуйте. 

С какой версии библиотеки Adafruit-GFX, не работает первый способ русификации? 

Перепробовал кучу вариантов. Пробовал ставить самую последнюю версию библиотеки и применять  utf8rus2.

и функцию display.cp437(true); скетч с ней не компилируется. без неё компиляция завершается но результата нет. Перепробовал несколько библиотек из архива 15го и 17 года( все перепробовать нереально) с первой версией файла utf8rus. Тоже безрезультатно. И я мог бы сослаться на свою некомпетентность, если бы у меня не получалось русифицировать эту библиотеку ранее. Сейчас же хоть убей не могу. Все исходные те же, кроме новой версии IDE и новых библиотек. К стате ранее, результата добился без функции display.cp437. Отсюда делаю вывод, что раньше работал со старой 255 символьной библиотекой. К стате, пока не обновил IDE и библиотеки с ним, заметил, что русский шрифт выводился, но совсем не то что вводилось с клавиатуры. 

   Результат со старой библиотекой

и тщетные попытки с новой.

nalbagar
Offline
Зарегистрирован: 28.12.2017

Если я правильно понимаю, то если не применять функцию display.cp437(true); , то не будет отображаться только символ градуса?

 

nalbagar
Offline
Зарегистрирован: 28.12.2017

   Так отображается русский набор, когда функция utf8rus. вложена в папку со скетчем но не прописана внутри команды String, или когда вообще без неё и в папке тоже. 

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

 

  

nalbagar
Offline
Зарегистрирован: 28.12.2017

 Открыв файл шрифта, который скопирован в библиотеку с архива, в редакторе, видно что русские символы там присутствуют

    Но так же выяснилось следующее что цифры которые присутствуют в этом шрифте, не выводятся. а выводятся другие. видно на примере цифры 2

  

 Из чего напрашивается вопрос. Если файл glcdfont в библиотеке заменён на одноимённый из архива, то каким образом подключается какой то другой шрифт? Скорее всего базовый из библиотеки.   Что я и проверил открыв базовый шрифт библиотеки в редакторе.

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

nalbagar
Offline
Зарегистрирован: 28.12.2017

  Кое что нарыл. Оказывается Файл со шрифтом нужно менять не только в папке   libraries, Adafruit-GFX-Library. Но и в папке portable,sketchbook,libraries,Adafruit_GFX_Library. Которая присутствует в каталоге ideV3. Но проблемма полностью не решилась. Теперь русские символы выводятся, но не те которые вводишь с клавиатуры. Например вместо "вск" выводится "гтл".

 Ищем дальше.

nalbagar
Offline
Зарегистрирован: 28.12.2017

   И так. пришлось поменять в теле функции некоторые значения. Вычитал на форуме АМПЕРКИ. 

Кирилица в Adafruit_GFX.h

 

  Итог: 

 

 Всё выводится чётко. Спасибо всем! Особенно arduinec и

Securbond

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

nalbagar пишет:

Если я правильно понимаю, то если не применять функцию display.cp437(true); , то не будет отображаться только символ градуса?

Символы, расположенные после символа градуса (русские буквы в частности), будут отображаться со смещением на 1 символ - что и прозошло в вышеприведенном примере.

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

nalbagar пишет:

Оказывается Файл со шрифтом нужно менять не только в папке   libraries, Adafruit-GFX-Library. Но и в папке portable,sketchbook,libraries,Adafruit_GFX_Library. Которая присутствует в каталоге ideV3.

Файл со шрифтом нужно менять в той библиотеке Adafruit-GFX, которую использует компилятор Arduino IDE (можно посмотреть по логам).

Paladian
Offline
Зарегистрирован: 23.10.2019

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

Paladian
Offline
Зарегистрирован: 23.10.2019

Заработало, ошибка на деле была глупой-обращалось не к той библиотеке Adafruit-GFX

spa5
Offline
Зарегистрирован: 20.02.2020

Индикатор

#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-е буквы: НОПР

Как это вылечить?
 

 

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

spa5 пишет:
Как это вылечить?

Неумение правильно вставлять код код лечится здесь: http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...

Полезную информацию по другим вопросам можно получить здесь: http://arduino.ru/forum/obshchii/pesochnitsa-dlya-vsekh-novichkov

spa5
Offline
Зарегистрирован: 20.02.2020

Благодарю за помощь, надо было просто нахрен послать!

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

Так так, что я слышу!? Знакомые нотки :).

Хотя уважаемый spa5arduinec прав.

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

 

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

spa5 пишет:

Благодарю за помощь, надо было просто нахрен послать!

собственно, это и произошло, вы просто не поняли...

spa5
Offline
Зарегистрирован: 20.02.2020
#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;

…

Вставил код в скобки, просто их сразу не заметил.
Легче стало?
Кто-нибудь с проблемой поможет или Вам ещё вензеля деревянные надо вырезать, али ещё какие-то украшательства?

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

Spa5 - не компилируется
Мужик, до тебя похоже плохо доходит.
Пишу как для идиотов - чтобы кто-то помог тебе найти ошибки в программе, ее текст надо показать целиком.
Можешь выкинуть все лишнее, но программа должна быть полной, чтобы любой мог скачать ее, скомпилировать и запустить.
А пока ты постишь обрывки - помощи не будет, можешь не тратить время

IvanDu
Offline
Зарегистрирован: 04.04.2015

   Очередным мученикам на заметку! При проверке адресов используемых библиотек обратите внимание на папку TEMP на диске С в юзерах. Только после чистки этой папки кракозябры пропали.

Sirocco
Offline
Зарегистрирован: 28.09.2013

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" и как его избежать?

nik182
Offline
Зарегистрирован: 04.05.2015

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

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

Sirocco пишет:
400 постов прочесть не осилю.

Печалька :(
Форумчане так старались, набивая эти посты :)

Sirocco пишет:
Непонятно откуда берётся символ "B" и как его избежать?

А если так?
tft.println(" 27.8\xB0C");
\xB0 выводит символ градуса (в прилагаемом шрифте)

Sirocco
Offline
Зарегистрирован: 28.09.2013
//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"));

То выводит точно также как на последнем скрине.

Sirocco
Offline
Зарегистрирован: 28.09.2013
  //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"));

В последнем примере, получается, "С" мешает.

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

На сколько я вижу, это "пристрелка" вывода значения температуры. Если ошибаюсь - дальше не читаем.

Даже без реальных показаний лучше печатать не строку целиком а сначала некую переменную 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");

А ещё лучше каждую секунду менять значение от минимально возможного до максимального, не забывая о том что количество символов будет меняться и лишнее надо затирать, но это уже другая тема.

Sirocco
Offline
Зарегистрирован: 28.09.2013

Да. Пистрелка. Как оказалось, Адафрукт не умеет центрировать

tft.drawCentreString("Text", 120, 14, 2);

Буду искать другие библиотеки

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

Sirocco пишет:

Да. Пистрелка. Как оказалось, Адафрукт не умеет центрировать

tft.drawCentreString("Text", 120, 14, 2);

Буду искать другие библиотеки

Да. помню что-то подобное. Но чем менять библиотеку - проще написать свою функцию центрирования. Для этого нужно только определить ширину текста в пикселях. Насколько я помню, в Адафруте есть под это функция.

А если нет отдельной функции для строки - то ширина каждого символа точно есть, просто суммируешь все символы и потом сдвигаешь строчку влево на половину ширины - вот и все "центрирование"

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

Для того чтоб напечатать текст по центру на самом деле и функции писать не надо.

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

Вот три примера на одном скрине когда это расстояние убрать не только можно но и нужно:

А на следующем скрине пример типа центрованного текста с этой же библиотекой:

Ни одна библиотека не напишет сама проект. 

A_lexK
Offline
Зарегистрирован: 02.11.2019

Решил русифицировать свой 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. Спасибо, все заработало.

A_lexK
Offline
Зарегистрирован: 02.11.2019

По размышлении понял, что вносить исправления в код процедуры utf8rus - неправильно, т.к. она будет генерировать нестандартные коды русских букв, а это не есть хорошо. Чтобы сохранить правильный вывод на дисплей, в файле glcdfont.c переставил строки с байтами бито-пикселей. Если, условно, нумеровать их от 0 до 255, то строку 255(FF) перенес и вставил на место 224(E0), а 185(E9) - на место 184(E8). Буквы(латинские и русские) выводятся на дисплей и через Serial правильно. Остальные символы - не проверял, руки не дошли.

A_lexK
Offline
Зарегистрирован: 02.11.2019

Ошибся в числах. В файле glcdfont.c переставил строки так: 255(FF) > 192(C0), 185(B9) > 184(B8).

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

A_lexK пишет:

Решил русифицировать свой TFT на ST7789(240х240) способом ТС arduinec. Использовал корректировку utf8rus из поста nalbagar #416, где дополнительно заменил 0xB8 на 0xB7 - для корректного отображения "ё"

Может проще в начале скетча вставить команду: display.cp437(true);
Для чего она нужна описано в посте #15 (http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafru...).

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

nalbagar пишет:

Если я правильно понимаю, то если не применять функцию display.cp437(true); , то не будет отображаться только символ градуса?

И все символы после него (в том числе русские буквы) будут смещены на 1 символ.

aleksandr23uam
Offline
Зарегистрирован: 22.01.2017

добрый день! использую библиотеку #include <TFT_eSPI.h>  для дисплея ST7789 и ESP32 не получается  вывести русский шрифт.

Помогите, пожалуйста!!!

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

В данной теме описывается как русифицировать библиотеку Adafruit-GFX.

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

aleksandr23uam пишет:

добрый день! использую библиотеку #include <TFT_eSPI.h>  для дисплея ST7789 и ESP32 не получается  вывести русский шрифт.

Помогите, пожалуйста!!!

Надо найти тему с обсуждением этой библиотеки. Если таковой нет, создать. Ну и раз уже тут засветили, то можно поместить ссылку на тему. И там уже показать что получается при попытке вывести текст в кириллице. 

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

Коли уж заглянул сюда, вот видос запилил на этой библиотеке. https://youtu.be/UvRmT0aR75o

При пояснении немгого заговаривался и некоторые детали передал не совсем корректно, но всё понял, осознал, каюсь, а видос из ютюба не выкинешь...  

1945
Offline
Зарегистрирован: 05.07.2020

Здравствуйте ! спасибо за труды автору!

Удобная библиотека применение ей нашёл в бегущей строке. 

Подскажите как можно увеличить количество применяемых символов в функцию utf8rus. 

Там есть ограничение из-за типа переменной - char. 

 

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

1945 пишет:

Подскажите как можно увеличить количество применяемых символов в функцию utf8rus. 

Там есть ограничение из-за типа переменной - char. 

 

поясните, как тип переменной char вам ограничивает число вимволов?

1945
Offline
Зарегистрирован: 05.07.2020

Я предположил - подскажите как лучше сделать?

 

1945
Offline
Зарегистрирован: 05.07.2020

максимум это 106 размер - #define maxString 106

С такой константой стабильная работа