utf8rus не конвертирует больше 59 символов

gqboy
Offline
Зарегистрирован: 29.04.2022

здравствуйте, у меня стоит задача - вывести 234 символа на экран. я думаю все знают про способ русификации adafruit gfx через glcdfont.c и utf8rus от arduinec. сама тема перекодировки то работает, я думал что сама проблема в способе получения строки из прогмема, но, даже при использовании lcd.print(utf8rus("59 русских символов")) все работает корректно, но при выводе 60 и больше символов не выводит ничего. в чем может быть проблема?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Наверное, в размере буфера? Если бы Вы дали ссылку на библиотеку, можно было бы посмотреть.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Как вариант - выводить строку кусками по 59 символов ...

gqboy
Offline
Зарегистрирован: 29.04.2022

в плане буфер дисплея?
библиотека https://github.com/cbm80amiga/Arduino_ST7735_Fast
я её немного переписал на размер экрана 80х160 и добавил оффестов для изображения (тк выводило криво), но думаю сути дела это особо не поменяет

gqboy
Offline
Зарегистрирован: 29.04.2022

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gqboy пишет:
в плане буфер дисплея?

В плане буфер функции utf2rus если он у неё есть. Дайте же посмотреть-то.

Кстати, в приведённой Вам библиотеке её нет. Значит, её Вы где-то отдельно брали.

gqboy пишет:
думаю сути дела это особо не поменяет

Напрасно думаете. Нужен ВАШ код С КОТОРЫМ У ВАС ПРОБЛЕМЫ. Не надо мне кодов "из интета". Нужно то, что работает / не работает У ВАС.

Выкладывайте, наконец, код, чтобы я мог на него посмотреть. Только выкладывайте с номерами строк, иначе получите совет "поправить что-нибудь в строке № ХЗ"

Без кода любые разговоры - в пользу бедных.

gqboy
Offline
Зарегистрирован: 29.04.2022

окей, до дома доберусь, скину код отредаченной либы и кода

gqboy
Offline
Зарегистрирован: 29.04.2022

Для начала приведу файлы измененной библиотеки ST7735:

ST7735.cpp:

#include "Arduino_ST7735_Fast.h"
#include <limits.h>
#include "pins_arduino.h"
#include "wiring_private.h"
#include <SPI.h>

// Initialization commands for ST7735 128x160 1.8" IPS
// taken from Adafruit
static const uint8_t PROGMEM
Rcmd1[] = {                       // 7735R init, part 1 (red or green tab)
  15,                             // 15 commands in list:
  ST7735_SWRESET,   ST_CMD_DELAY, //  1: Software reset, 0 args, w/delay
  150,                          //     150 ms delay
  ST7735_SLPOUT,    ST_CMD_DELAY, //  2: Out of sleep mode, 0 args, w/delay
  255,                          //     500 ms delay
  ST7735_FRMCTR1, 3,              //  3: Framerate ctrl - normal mode, 3 arg:
  0x01, 0x2C, 0x2D,             //     Rate = fosc/(1x2+40) * (LINE+2C+2D)
  ST7735_FRMCTR2, 3,              //  4: Framerate ctrl - idle mode, 3 args:
  0x01, 0x2C, 0x2D,             //     Rate = fosc/(1x2+40) * (LINE+2C+2D)
  ST7735_FRMCTR3, 6,              //  5: Framerate - partial mode, 6 args:
  0x01, 0x2C, 0x2D,             //     Dot inversion mode
  0x01, 0x2C, 0x2D,             //     Line inversion mode
  ST7735_INVCTR,  1,              //  6: Display inversion ctrl, 1 arg:
  0x07,                         //     No inversion
  ST7735_PWCTR1,  3,              //  7: Power control, 3 args, no delay:
  0xA2,
  0x02,                         //     -4.6V
  0x84,                         //     AUTO mode
  ST7735_PWCTR2,  1,              //  8: Power control, 1 arg, no delay:
  0xC5,                         //     VGH25=2.4C VGSEL=-10 VGH=3 * AVDD
  ST7735_PWCTR3,  2,              //  9: Power control, 2 args, no delay:
  0x0A,                         //     Opamp current small
  0x00,                         //     Boost frequency
  ST7735_PWCTR4,  2,              // 10: Power control, 2 args, no delay:
  0x8A,                         //     BCLK/2,
  0x2A,                         //     opamp current small & medium low
  ST7735_PWCTR5,  2,              // 11: Power control, 2 args, no delay:
  0x8A, 0xEE,
  ST7735_VMCTR1,  1,              // 12: Power control, 1 arg, no delay:
  0x0E,
  ST7735_INVOFF,  0,              // 13: Don't invert display, no args
  ST7735_MADCTL,  1,              // 14: Mem access ctl (directions), 1 arg:
  0xC8,                         //     row/col addr, bottom-top refresh
  ST7735_COLMOD,  1,              // 15: set color mode, 1 arg, no delay:
  0x05 },
      
Rcmd2red[] = {                    // 7735R init, part 2 (red tab only)
  2,                              //  2 commands in list:
  ST7735_CASET,   4,              //  1: Column addr set, 4 args, no delay:
  0x00, 0x00,                   //     XSTART = 0
  0x00, 0x7F,                   //     XEND = 127
  ST7735_RASET,   4,              //  2: Row addr set, 4 args, no delay:
  0x00, 0x00,                   //     XSTART = 0
  0x00, 0x9F },
      
Rcmd3[] = {                       // 7735R init, part 3 (red or green tab)
  4,                              //  4 commands in list:
  ST7735_GMCTRP1, 16      ,       //  1: Gamma Adjustments (pos. polarity), 16 args + delay:
  0x02, 0x1c, 0x07, 0x12,       //     (Not entirely necessary, but provides
  0x37, 0x32, 0x29, 0x2d,       //      accurate colors)
  0x29, 0x25, 0x2B, 0x39,
  0x00, 0x01, 0x03, 0x10,
  ST7735_GMCTRN1, 16      ,       //  2: Gamma Adjustments (neg. polarity), 16 args + delay:
  0x03, 0x1d, 0x07, 0x06,       //     (Not entirely necessary, but provides
  0x2E, 0x2C, 0x29, 0x2D,       //      accurate colors)
  0x2E, 0x2E, 0x37, 0x3F,
  0x00, 0x00, 0x02, 0x10,
  ST7735_NORON,     ST_CMD_DELAY, //  3: Normal display on, no args, w/delay
  10,                           //     10 ms delay
  ST7735_DISPON,    ST_CMD_DELAY, //  4: Main screen turn on, no args w/delay
  100 };         

#ifdef COMPATIBILITY_MODE
static SPISettings spiSettings;
#define SPI_START  SPI.beginTransaction(spiSettings)
#define SPI_END    SPI.endTransaction()
#else
#define SPI_START
#define SPI_END
#endif

// macros for fast DC and CS state changes
#ifdef COMPATIBILITY_MODE
#define DC_DATA     digitalWrite(dcPin, HIGH)
#define DC_COMMAND  digitalWrite(dcPin, LOW)
#define CS_IDLE     digitalWrite(csPin, HIGH)
#define CS_ACTIVE   digitalWrite(csPin, LOW)
#else
#define DC_DATA    *dcPort |= dcMask
#define DC_COMMAND *dcPort &= ~dcMask
#define CS_IDLE    *csPort |= csMask
#define CS_ACTIVE  *csPort &= ~csMask
#endif

// if CS always connected to the ground then don't do anything for better performance
#ifdef CS_ALWAYS_LOW
#define CS_IDLE
#define CS_ACTIVE
#endif

// ----------------------------------------------------------
// speed test results:
// in AVR best performance mode -> about 6.9 Mbps
// in compatibility mode (SPI.transfer(c)) -> about 4 Mbps
inline void Arduino_ST7735::writeSPI(uint8_t c) 
{
#ifdef COMPATIBILITY_MODE
    SPI.transfer(c);
#else
    SPDR = c;
    asm volatile("nop"); // 8 NOPs seem to be enough for 16MHz AVR @ DIV2 to avoid using while loop
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    //while(!(SPSR & _BV(SPIF))) ;
#endif
}

// ----------------------------------------------------------
Arduino_ST7735::Arduino_ST7735(int8_t dc, int8_t rst, int8_t cs) : Adafruit_GFX(ST7735_TFTWIDTH, ST7735_TFTHEIGHT) 
{
  csPin = cs;
  dcPin = dc;
  rstPin = rst;
}

// ----------------------------------------------------------
void Arduino_ST7735::init() 
{
  pinMode(dcPin, OUTPUT);
#ifndef CS_ALWAYS_LOW
	pinMode(csPin, OUTPUT);
#endif

#ifndef COMPATIBILITY_MODE
  dcPort = portOutputRegister(digitalPinToPort(dcPin));
  dcMask = digitalPinToBitMask(dcPin);
#ifndef CS_ALWAYS_LOW
	csPort = portOutputRegister(digitalPinToPort(csPin));
	csMask = digitalPinToBitMask(csPin);
#endif
#endif

  SPI.begin();
#ifdef COMPATIBILITY_MODE
  spiSettings = SPISettings(16000000, MSBFIRST, SPI_MODE3);  // 8000000 gives max speed on AVR 16MHz
#else
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE3);
#endif

  CS_ACTIVE;
  if(rstPin != -1) {
    pinMode(rstPin, OUTPUT);
    digitalWrite(rstPin, HIGH);
    delay(50);
    digitalWrite(rstPin, LOW);
    delay(50);
    digitalWrite(rstPin, HIGH);
    delay(50);
  }

  _colstart = 26; //оффсет картинки
  _rowstart = 1;
  _width  = ST7735_TFTWIDTH;
  _height = ST7735_TFTHEIGHT;
  displayInit(Rcmd1);
  displayInit(Rcmd2red);
  displayInit(Rcmd3);
  setRotation();
}

// ----------------------------------------------------------
void Arduino_ST7735::writeCmd(uint8_t c) 
{
  DC_COMMAND;
  CS_ACTIVE;
  SPI_START;

  writeSPI(c);

  CS_IDLE;
  SPI_END;
}

// ----------------------------------------------------------
void Arduino_ST7735::writeData(uint8_t c) 
{
  DC_DATA;
  CS_ACTIVE;
  SPI_START;
    
  writeSPI(c);

  CS_IDLE;
  SPI_END;
}

// ----------------------------------------------------------
void Arduino_ST7735::displayInit(const uint8_t *addr) 
{
  uint8_t  numCommands, numArgs;
  uint16_t ms;
  numCommands = pgm_read_byte(addr++);   // Number of commands to follow
  while(numCommands--) {                 // For each command...
    writeCmd(pgm_read_byte(addr++));     //   Read, issue command
    numArgs  = pgm_read_byte(addr++);    //   Number of args to follow
    ms       = numArgs & ST_CMD_DELAY;   //   If hibit set, delay follows args
    numArgs &= ~ST_CMD_DELAY;            //   Mask out delay bit
    while(numArgs--) writeData(pgm_read_byte(addr++));

    if(ms) {
      ms = pgm_read_byte(addr++); // Read post-command delay time (ms)
      if(ms == 255) ms = 500;     // If 255, delay for 500 ms
      delay(ms);
    }
  }
}


// ----------------------------------------------------------
void Arduino_ST7735::setRotation() //Только 1 вид развертки дисплея
{
  writeCmd(ST7735_MADCTL);
  writeData(ST7735_MADCTL_MV | ST7735_MADCTL_RGB);
  _ystart = _colstart;
  _xstart = _rowstart;
  _width  = ST7735_TFTHEIGHT;
  _height = ST7735_TFTWIDTH;
}

// ----------------------------------------------------------
void Arduino_ST7735::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) 
{
  uint16_t xs = x0 + _xstart, xe = x1 + _xstart;
  uint16_t ys = y0 + _ystart, ye = y1 + _ystart;
  // optimized version
  CS_ACTIVE;
  SPI_START;
  
  DC_COMMAND; writeSPI(ST7735_CASET);
  DC_DATA;
  writeSPI(xs >> 8); writeSPI(xs & 0xFF);
  writeSPI(xe >> 8); writeSPI(xe & 0xFF);

  DC_COMMAND; writeSPI(ST7735_RASET);
  DC_DATA;
  writeSPI(ys >> 8); writeSPI(ys & 0xFF);
  writeSPI(ye >> 8); writeSPI(ye & 0xFF);

  DC_COMMAND; writeSPI(ST7735_RAMWR);
  
  CS_IDLE;
  SPI_END;
}

void Arduino_ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) 
{
  if(x<0 ||x>=_width || y<0 || y>=_height) return;
  setAddrWindow(x,y,x+1,y+1);

  SPI_START;
  DC_DATA;
  CS_ACTIVE;

  writeSPI(color >> 8); writeSPI(color);

  CS_IDLE;
  SPI_END;
}


void Arduino_ST7735::fillScreen(uint16_t color) 
{
  fillRect(0, 0,  _width, _height, color);
}

void Arduino_ST7735::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 
{
  if(x>=_width || y>=_height || w<=0 || h<=0) return;
  if(x+w-1>=_width)  w=_width -x;
  if(y+h-1>=_height) h=_height-y;
  setAddrWindow(x, y, x+w-1, y+h-1);

  uint8_t hi = color >> 8, lo = color;
    
  SPI_START;
  DC_DATA;
  CS_ACTIVE;

  uint32_t num = (uint32_t)w*h;
  uint16_t num16 = num>>4;
  while(num16--) {
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
    writeSPI(hi); writeSPI(lo);
  }
  uint8_t num8 = num & 0xf;
  while(num8--) { writeSPI(hi); writeSPI(lo); }

  CS_IDLE;
  SPI_END;
}


void Arduino_ST7735::invertDisplay(boolean mode) 
{
  writeCmd(mode ? ST7735_INVON : ST7735_INVOFF);
}

ST7735.h:

#ifndef _ST7735_FAST_H_
#define _ST7735_FAST_H_

// ------------------------------
// remove "define COMPATIBILITY_MODE" for best performance on 16MHz AVR Arduinos
// if defined - the library should work on all Arduino compatible boards
//#define COMPATIBILITY_MODE

// define for LCD boards where CS pin is internally connected to the ground
//#define CS_ALWAYS_LOW
// ------------------------------

#include "Arduino.h"
#include "Print.h"
#include <Adafruit_GFX.h>
#include <avr/pgmspace.h>

#define ST7735_TFTWIDTH 	80
#define ST7735_TFTHEIGHT 	160

// Some register settings
#define ST7735_MADCTL_BGR 0x08
#define ST7735_MADCTL_MH  0x04

#define ST7735_FRMCTR1    0xB1
#define ST7735_FRMCTR2    0xB2
#define ST7735_FRMCTR3    0xB3
#define ST7735_INVCTR     0xB4
#define ST7735_DISSET5    0xB6

#define ST7735_PWCTR1     0xC0
#define ST7735_PWCTR2     0xC1
#define ST7735_PWCTR3     0xC2
#define ST7735_PWCTR4     0xC3
#define ST7735_PWCTR5     0xC4
#define ST7735_VMCTR1     0xC5

#define ST7735_PWCTR6     0xFC

#define ST7735_GMCTRP1    0xE0
#define ST7735_GMCTRN1    0xE1



#define ST_CMD_DELAY   0x80

#define ST7735_NOP     0x00
#define ST7735_SWRESET 0x01

#define ST7735_SLPIN   0x10  // sleep on
#define ST7735_SLPOUT  0x11  // sleep off
#define ST7735_PTLON   0x12  // partial on
#define ST7735_NORON   0x13  // partial off
#define ST7735_INVOFF  0x20  // invert off
#define ST7735_INVON   0x21  // invert on
#define ST7735_DISPOFF 0x28  // display off
#define ST7735_DISPON  0x29  // display on
#define ST7735_IDMOFF  0x38  // idle off
#define ST7735_IDMON   0x39  // idle on

#define ST7735_CASET   0x2A
#define ST7735_RASET   0x2B
#define ST7735_RAMWR   0x2C
#define ST7735_RAMRD   0x2E

#define ST7735_COLMOD  0x3A
#define ST7735_MADCTL  0x36

#define ST7735_PTLAR    0x30   // partial start/end
#define ST7735_VSCRDEF  0x33   // SETSCROLLAREA
#define ST7735_VSCRSADD 0x37

#define ST7735_WRDISBV  0x51
#define ST7735_WRCTRLD  0x53
#define ST7735_WRCACE   0x55
#define ST7735_WRCABCMB 0x5e

#define ST7735_POWSAVE    0xbc
#define ST7735_DLPOFFSAVE 0xbd

// bits in MADCTL
#define ST7735_MADCTL_MY  0x80
#define ST7735_MADCTL_MX  0x40
#define ST7735_MADCTL_MV  0x20
#define ST7735_MADCTL_ML  0x10
#define ST7735_MADCTL_RGB 0x00


// Color definitions
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define RGBto565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3)) 

class Arduino_ST7735 : public Adafruit_GFX {

 public:
  Arduino_ST7735(int8_t DC, int8_t RST, int8_t CS = -1);

  void init();
  void begin() { init(); }
  void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
  void fillScreen(uint16_t color=BLACK);
  void clearScreen() { fillScreen(BLACK); }
  void drawPixel(int16_t x, int16_t y, uint16_t color);
  void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
  void setRotation();
  void invertDisplay(boolean mode);
  void resetDisplay();
 protected:
  uint8_t  _colstart, _rowstart, _xstart, _ystart;

  void displayInit(const uint8_t *addr);
  void writeSPI(uint8_t);
  void writeCmd(uint8_t c);
  void writeData(uint8_t d);

 private:
  int8_t  csPin, dcPin, rstPin;
  uint8_t  csMask, dcMask;
  volatile uint8_t  *csPort, *dcPort;

};

#endif

А теперь и сам код + фотки того, что выводится на дисплей

const char scr0[] PROGMEM = "АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШ"; //59 сим
const char scr1[] PROGMEM = "АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; //99 сим
const char scr2[] PROGMEM = "АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
const char scr3[] PROGMEM = "АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
const char* const scr_nm[] PROGMEM = {
  scr0, scr1, scr2, scr3,
};

#include <Adafruit_GFX.h>
#include <Arduino_ST7735_Fast.h>

#define TFT_CS 3
#define TFT_DC  A3
#define TFT_RST A2

Arduino_ST7735 lcd = Arduino_ST7735(TFT_DC, TFT_RST, TFT_CS);

String utf8rus(String source) //функция от arduinec для перекодировки utf8 в cp какой то там
{
  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 printPGM(int idx) { //Принт из прогмема (не больше ? (59-ошибка, выводит чуть больше,но все равно недостаточно) сим.)
  PGM_P p = pgm_read_word(scr_nm + idx);
  char buf[strlen_P(p)];
  strcpy_P(buf, p);
  lcd.setCursor(0,0);
  lcd.print(utf8rus(buf));
}

void setup() {
  lcd.init();
  lcd.cp437(true);
  lcd.invertDisplay(true);
  lcd.fillScreen(BLACK);
  lcd.setTextSize(1);
  lcd.setTextColor(WHITE);
  pinMode(2,OUTPUT);
  digitalWrite(2,HIGH);// подсветка дисплея
  //printPGM(0); //Вывод первого массива - 59 сим; выводит нормально
  //printPGM(1); //Вывод второго массива - 99 сим; только часть
  //lcd.print(utf8rus("АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШ")); //Вывод без прогмема (59 сим); выводит нормально
  lcd.print(utf8rus("АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ")); //Вывод без прогмема (99 сим); так же, выводит только часть
}

void loop() {}

59 символов (прогмем/принт выводит одинаково)

59 символов, все норм (так выводит и из прогмема и простым print(utf8rus(&quot;текст&quot;));

99 символов (прогмем/принт выводит одинаково)

А вот так выводит 99 символов

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

вот только на той неделе человек спрашивал тоже самое - только у него более 10 символов не показывало - тут http://arduino.ru/forum/programmirovanie/russkie-shrifty-dlya-biblioteki-fabgl#comment-652425

избавьтесь от String - все заработает.

И откуда вы берете этот кривой вариант utf2rus. это не код arduinec

gqboy
Offline
Зарегистрирован: 29.04.2022

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

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

мой вариант для char строки из UTF в Win1251

http://arduino.ru/forum/otvlechennye-temy/programmirovanie-32-kh-razryad...

void tftConvertStringToWIN1251(unsigned char * utfText) {
	unsigned char locPosOriginalStr = 0; // позиция обрабатываемого байта в исходной строке
	unsigned char locPosOutStr = 0; // позиция куда класть исходящий байт
	while (utfText[locPosOriginalStr]) { // цикл по всей входящей строке
		if (utfText[locPosOriginalStr] == 0xD0) { // UTF символ
			if (utfText[locPosOriginalStr+1] == 0x81) { // буква Ё
				utfText[locPosOutStr] = 0xA8; // кладем символ
				++locPosOutStr; // прибавляем выходной счетчик
				++locPosOriginalStr; // пропускаем один байт исходной строки
			} else if ((utfText[locPosOriginalStr+1] >= 0x90) && (utfText[locPosOriginalStr+1] <= 0xBF)) { // первая часть русской UTF
				utfText[locPosOutStr] = 0xC0 + (utfText[locPosOriginalStr+1] - 0x90); // кладем символ
				++locPosOutStr; // прибавляем выходной счетчик
				++locPosOriginalStr; // пропускаем один байт исходной строки
			} else { // или конец строки или байт не относиться к русской UTF
				utfText[locPosOutStr] = utfText[locPosOriginalStr]; // кладем байт как есть
				++locPosOutStr; // прибавляем выходной счетчик
			}
		} else if (utfText[locPosOriginalStr] == 0xD1) { // UTF символ
			if (utfText[locPosOriginalStr+1] == 0x91) { // буква ё
				utfText[locPosOutStr] = 0xB8; // кладем символ
				++locPosOutStr; // прибавляем выходной счетчик
				++locPosOriginalStr; // пропускаем один байт исходной строки
			} else if ((utfText[locPosOriginalStr+1] >= 0x80) && (utfText[locPosOriginalStr+1] <= 0x8F)) { // вторая часть русской UTF
				utfText[locPosOutStr] = 0xF0 + (utfText[locPosOriginalStr+1] - 0x80); // кладем символ
				++locPosOutStr; // прибавляем выходной счетчик
				++locPosOriginalStr; // пропускаем один байт исходной строки
			} else { // или конец строки или байт не относиться к русской UTF
				utfText[locPosOutStr] = utfText[locPosOriginalStr]; // кладем байт как есть
				++locPosOutStr; // прибавляем выходной счетчик
			}
		} else {
			utfText[locPosOutStr] = utfText[locPosOriginalStr]; // кладем байт как есть
			++locPosOutStr; // прибавляем выходной счетчик
		}
		++locPosOriginalStr; // переходим на след символ оригинальной строки
	}
	utfText[locPosOutStr] = 0; // заканчиваем строку нулем
}

 

gqboy
Offline
Зарегистрирован: 29.04.2022

собственно вот где я взял вариант этой функции
http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafru...

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

gqboy пишет:
собственно вот где я взял вариант этой функции http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafruit-gfx-i-vyvod-russkikh-bukv-na-displei-v-kodi

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

 

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

andycat пишет:

мой вариант для char строки из UTF в Win1251

ой мама... че ж там стока наворочено? :)

а вот мой

int utf8_rus(char* dest, const unsigned char* src) {
  uint16_t i, j;
  for ( i =0, j =0; src[i]; i++) {
   if ((src[i] == 0xD0 )&& src[i+1])  { dest[j++] = src[++i] - 0x10;}
    else if ((src[i] == 0xD1 )&& src[i+1]) {dest[j++] = src[++i] + 0x30;  }
    else dest[j++] = src[i];
  }
  dest[j] ='\0';
  return j;
}

правда упрощенный :) Ё нет

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

b707 пишет:

ой мама... че ж там стока наворочено? :)

как смог :)

Улыбнуло | Аппаратная платформа Arduino

"

Самое начало: лишь бы работало

"
 

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

Отлично :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В этом коде я не вижу никаких ограничений на 59 или любую другую длину.

Но, я вижу операции с типом String без проверки того, что хватили памяти (в 99,89% ардуиновского кода таких проверок нет). Скорее всего где-то не хватает памяти. Поставьте проверки.