Кодировка русских букв компилятором

Argus19
Offline
Зарегистрирован: 08.05.2022

 Я понимаю, что IDE Arduino работает с UTF-8, но в какую кодировку компилятор транслирует русские буквы?

Например, если в скетче написано:

 Lcd.Display("АБВГДЕЖЗИ");

то, что будет записано в Atmega?

 

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

Компилятор ничего никуда не транслирует. Если файл в ASCI, то в памяти будут коды ASCI. Если файла в UTF-8, то в памяти будут коды UTF-8. Никакой самодеятельностью компилятор не занимается.

Argus19
Offline
Зарегистрирован: 08.05.2022

ЕвгенийП пишет:

 Если файла в UTF-8, то в памяти будут коды UTF-8.

Т.е. в памяти будут двухбайтные коды русских букв, как описано тут:

сылка

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

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

Argus19
Offline
Зарегистрирован: 08.05.2022

 Мне подсказали, что если сменить кодировку на ср1251, то символы станут однобайтовыми.Т.е., если у меня появилась фантазия использовать русские символы, то при перекодировке в cp1251, я буду экономить один байт на каждый символ?

 

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

Argus19 пишет:

 буду экономить один байт на каждый символ?

Будете. Другой вопрос, что Вы собираетесь делать с этими символами? Например (чисто пример), если Вы собираетесь выводить их на экран, Вы должны понимать какой кодировки ожидает от Вас библиотека экрана. Если она ожидает cp1251, то так и надо делать. Но, если она ожидает UTF-8, то сильно удивится, увидев Вашу cp1251.

Argus19
Offline
Зарегистрирован: 08.05.2022

ЕвгенийП пишет:

 Вы должны понимать какой кодировки ожидает от Вас библиотека экрана. Если она ожидает cp1251, то так и надо делать. Но, если она ожидает UTF-8, то сильно удивится, увидев Вашу cp1251.

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

 Посмотрю исходную. Может пойму как допилить.

 

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

Argus19 пишет:
Библиотека, судя по всему, ждёт только однобайтовые символы. Чисел принципиально не понимает.
А последней фразы я не понимаю. Уверен, что и Вы тоже.

Argus19
Offline
Зарегистрирован: 08.05.2022

ЕвгенийП пишет:

А последней фразы я не понимаю. Уверен, что и Вы тоже.

 При передаче в библиотеку числа выводится, либо соответствующий ему символ, либо ничего.

Вот так объявлен метод класса:

    void Display(char *str);              //4 lines of 18 characters each.

 

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

Argus19 пишет:

 При передаче в библиотеку числа выводится, либо соответствующий ему символ, либо ничего.

Ну, да. А Вы чего ожидали?

Argus19
Offline
Зарегистрирован: 08.05.2022

ЕвгенийП пишет:

Ну, да. А Вы чего ожидали?

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

Почему-то была уверенность, что магазин Estardyn Official Store является ещё и производителем.

 

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

А чем она " недоделанная"? Уж не тем ли, что чисел не понимает?
Открою вам секрет - любая графическая библиотека при записи в нее чисел выводит на экран символы. По другому просто не бывает.

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

Ну а вот недоделанная библиотека выводит недоделанные числа... 

Argus19
Offline
Зарегистрирован: 08.05.2022

b707 пишет:
А чем она " недоделанная"? Уж не тем ли, что чисел не понимает? Открою вам секрет - любая графическая библиотека при записи в нее чисел выводит на экран символы. По другому просто не бывает.

 Вы читали мой пост #8 ?

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

Argus19 пишет:

b707 пишет:
А чем она " недоделанная"? Уж не тем ли, что чисел не понимает? Открою вам секрет - любая графическая библиотека при записи в нее чисел выводит на экран символы. По другому просто не бывает.

 Вы читали мой пост #8 ?

Да. читал.

И то. что выше - мой ответ на это сообщение.

А чего вы вообще ждали от библиотеки? Сдается мне, что вам стоит разобраться. чем отличается число 1 от символа '1' и что из них выводится на экран. Подскажу - символ.

и чтобы нарисовать на экране единичку - надо передать библиотеке не число 1, а символ '1'

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Argus19 пишет:

b707 пишет:
А чем она " недоделанная"? Уж не тем ли, что чисел не понимает? Открою вам секрет - любая графическая библиотека при записи в нее чисел выводит на экран символы. По другому просто не бывает.

 Вы читали мой пост #8 ?

Я прочел. Что ты хотел сказать? На дисплей передается строка символов (вот этот char *).

Попробую угадать: кириллицу не печатает? ;)))) А должна? Реально исчезающе мало библиотек для экранов, которые содержат кириллические шрифты. Часто  бывает можно добавить свой шрифт - их есть на просторах Инета.

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

Мир программирования и электроники - он весь англоязычный и весь на латинице... ну еще бывают ДШ на китайском ;)))) но не на кириллице!

--------------------

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

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

wdrakula пишет:

Я прочел. Что ты хотел сказать?

Попробую угадать: кириллицу не печатает? ;))))

нет Влад, все хуже! он кидает туда число 65 - а эта "недоделанная либа" вместо "65" печатает "А" !!! Он посылает ей 240 - а она вообще не печатает ничего!

безобразие... никому нельзя верить... он рассчитывал. что хотя в магазине производителя дисплеев порядок...

Argus19
Offline
Зарегистрирован: 08.05.2022

wdrakula пишет:

Я прочел. Что ты хотел сказать? На дисплей передается строка символов (вот этот char *).

 

[/quote]

 Если в прототипе указана строка, то и печатается строка. Если туда передать число, то оно интерпретируется как строка.

wdrakula пишет:
Попробую угадать: кириллицу не печатает? ;)))) А должна?

 Зачем угадывать? Это очевидно из общения. Латиница входит в любую кодировку. И не должна, т.к. анализируются символы от '1' до 'z', плюс кое-какие псеводграфические вот таким образом:

for(int num=0; num<len; num++){ 
    switch(str[num]){
      case '0': WriteFont(0); break;
      case '1': WriteFont(1); break;
      case '2': WriteFont(2); break;
      case '3': WriteFont(3); break;
      case '4': WriteFont(4); break;
      case '5': WriteFont(5); break;
      case '6': WriteFont(6); break;
      case '7': WriteFont(7); break;
      case '8': WriteFont(8); break;
      case '9': WriteFont(9); break;

и т.д. Скетч в кодировке UTF-8, т.е. двухбайтовой.

1). Как такой код понимает, что первый байт ноль?

 

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

Argus19 пишет:

[Если в прототипе указана строка, то и печатается строка. Если туда передать число, то оно интерпретируется как строка.

вопрос - если вы видите, что в прототипе СТРОКА - нафига вы туда число передаете?

 

 

Argus19 пишет:

1). Как такой код понимает, что первый байт ноль?

никак не понимает. Вы должны явно передать коду ноль. Причем не байт ноль, а символ ноль, то есть байт 48.

У меня такое впечатление, что вы так и не поняли разницу.

Argus19
Offline
Зарегистрирован: 08.05.2022

b707 пишет:

никак не понимает. Вы должны явно передать коду ноль. Причем не байт ноль, а символ ноль, то есть байт 48.

У меня такое впечатление, что вы так и не поняли разницу.

 Нашёл нормальную таблицу UTF-8. Латиница и цифры занимают один байт, а после 127 символы становятся двухбайтовыми и до 4 байт. Не могли бы вы на примере какой-либо библиотеки разъяснить как метод .print понимает, что получил, строку и в какой кодировке, целое или вещественное число? В С++, если я правильно понимаю, что описано в прототипе, с тем функция и работает. Судя по всему, Arduino построена иначе.

 Библиотека, которую я пытаюсь понять взята отсюда:

https://github.com/luetee/ST7567S_128X64_I2C

 Как по вашему мнению, она допилена или нет?

 

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

Argus19 пишет:

 Нашёл нормальную таблицу UTF-8. Латиница и цифры занимают один байт, а после 127 символы становятся двухбайтовыми и до 4 байт. Не могли бы вы на примере какой-либо библиотеки разъяснить как метод .print понимает, что получил, строку и в какой кодировке, целое или вещественное число? В С++, если я правильно понимаю, что описано в прототипе, с тем функция и работает. Судя по всему, Arduino построена иначе.

Просили пример библиотеки - получите: https://arduino.ru/forum/proekty/asoled-kompaktnaya-biblioteka-dlya-oled-displeya-128kh64-s-kirillitsei-utf-8

Только никому больше не говорите про отличие Ардуино от С++.

lilik
Offline
Зарегистрирован: 19.10.2017

Я всё не пойму в чём проблема? Если на запрос '1' рисует 1, то что мешает дописать код чтоб на 1 рисовала 1?, а потом на 10 рисовала 1и рядом 0?

lilik
Offline
Зарегистрирован: 19.10.2017

Экран то какой? На все ходовые уже давно всё поделали, и на русском и не на русском.

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

Argus19 пишет:
В С++, если я правильно понимаю, что описано в прототипе, с тем функция и работает. Судя по всему, Arduino построена иначе.
Да, нет, это мозги у Вас иначе устроены :-)

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

andriano пишет:

Только никому больше не говорите про отличие Ардуино от С++.

Поздно, я уже заметил :-)

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

Argus19 пишет:

Не могли бы вы разъяснить как метод .print понимает, что получил, строку и в какой кодировке, целое или вещественное число? В С++, если я правильно понимаю, что описано в прототипе, с тем функция и работает. Судя по всему, Arduino построена иначе.

давайте по порядку.

До того мы говорили про метод Display() , прототип которого вы приводили в сообщении #8. Теперь вдруг речь зашла про какой-то метод print, непонятно откуда взявшийся.

Так какой метод надо рассмотреть - метод print или метод  прототип которого вы приводили выше?

lilik
Offline
Зарегистрирован: 19.10.2017

Argus19 пишет:

 

 Библиотека, которую я пытаюсь понять взята отсюда:

https://github.com/luetee/ST7567S_128X64_I2C

 Как по вашему мнению, она допилена или нет?

 

Вот в этом коне-библиотеке ищите свой экранчик. Она явно допилена-перепилена. 

 <U8g2lib.h>

У меня похожий экранчик, уже не помню как, но на русском шпрехает. Вот мой рабочий пример.

/////////////////   часы с мелодией версия 3
#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
 U8G2_ST7565_ERC12864_2_4W_SW_SPI u8g2(U8G2_R1, /* scl=*/ 13, /* si=*/ 11, /* cs=*/ 10, /* rs=*/ 9, /* rse=*/ 8);
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS3231);
extern const unsigned char schkala_A[];
///////////////////////////
// НОВОГОДНЯЯ МЕЛОДИЯ фрагмент
int tonePin = 7; 
const struct sound{ 
  int freq, duration, dly; 
  } sounds[] PROGMEM = {
    {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, {293, 450, 750}, 
    {293, 225, 250}, {293, 225, 250}, {493, 225, 250}, {440, 225, 250}, {391, 225, 250}, 
    {329, 450, 750}, {329, 225, 250}, {329, 225, 250}, {523, 225, 250}, {493, 225, 250}, 
    {440, 225, 250}, {587, 450, 750}, {587, 225, 250}, {659, 225, 250}, {587, 225, 250}, 
    {523, 225, 250}, {440, 225, 250}, {493, 675, 750}
};
const uint8_t melodieLength = sizeof(sounds) / sizeof(sound);
sound SoundSRAM;
///////////////////////////////
int t=222;// пауза между считываниями данных
float minuti = 0.00; //пременные хранения углов
float tcshasi = 0.00; //
float sekundi = 0.00; //
int dlina_1 = 30;//задаём геометрию-форму стрелок часов
int dlina_2 = 30;
bool fl=true;//"флаг по условию" переключает режимы основная тема-вторичная

void setup()
{
 u8g2.begin(); 
 u8g2.setContrast (20); 
 time.begin();
 //u8g2.sendF("c", 0xA7);//инвертировать цвета на экране
 u8g2.enableUTF8Print();
 u8g2.setFont(u8g2_font_cu12_t_cyrillic);
   
 }

void loop()
{
if((time.minutes==0&&time.seconds<10)||(time.minutes==30&&time.seconds<10)){midi();}// играем мелодию в начале каждого получаса 
 vremia_A();
 delay(t); 
 }
////////////////////////////////////////
void vremia_A (){
 time.gettime();//
 ///////////////
//выставляем на экран календарь с 45 по 52 секунды каждой минуты
if(time.seconds==52){fl=true;}
if(time.seconds==45){fl=false;}
///////////////  
//  u8g2.clearBuffer();//очистка экрана
u8g2.firstPage();
  do {  
  if(fl==true){//ставим на экран основную тему
   ///////////////
  u8g2.setFont(u8g2_font_logisoso22_tr);//меняем шрифт 
  u8g2.setCursor(17,32);u8g2.print(time.day);// число месяца пишем
  u8g2.setFont(u8g2_font_cu12_t_cyrillic);//возвращаем шрифт
  u8g2.setCursor(10,55);
  if( time.month==1){u8g2.print("ЯНВ.");}// название месяца пишем
  if( time.month==2){u8g2.print("ФЕВР.");}
  if( time.month==3){u8g2.print("МАР.");}
  if( time.month==4){u8g2.print("АПР.");}
  if( time.month==5){u8g2.print("МАЯ");}
  if( time.month==6){u8g2.print("ИЮН.");}
  if( time.month==7){u8g2.print("ИЮЛ.");}
  if( time.month==8){u8g2.print("АВГ.");}
  if( time.month==9){u8g2.print("СЕНТ.");}
  if( time.month==10){u8g2.print("ОКТ.");}
  if( time.month==11){u8g2.print("НОЯБ.");}
  if( time.month==12){u8g2.print("ДЕК.");}
  u8g2.setCursor(20,68);
  u8g2.print("20");//год пишем
  u8g2.setCursor(35,68);
  u8g2.print(time.year);
  u8g2.setCursor(10,80);
  if(time.weekday==1){u8g2.print("понед.");}//день недели пишем
  if(time.weekday==2){u8g2.print("вторн.");}//
  if(time.weekday==3){u8g2.print("сред.");}//
  if(time.weekday==4){u8g2.print("четв.");}//
  if(time.weekday==5){u8g2.print("пятн.");}//
  if(time.weekday==6){u8g2.print("субб.");}//
  if(time.weekday==0){u8g2.print("воскр.");}//
  u8g2.setCursor(10,102);
  if(time.Hours<10){u8g2.print("0");u8g2.setCursor(18,102);u8g2.print(time.Hours);}else{u8g2.print(time.Hours);}//время текущее пишем (часы и минуты)
  u8g2.setCursor(25,102);
  u8g2.print("//");//
  u8g2.setCursor(43,102);
  if(time.minutes<10){u8g2.print("0");u8g2.setCursor(51,102);u8g2.print(time.minutes);}else{u8g2.print(time.minutes);}//
  u8g2.drawBox(2,110,60-time.seconds,6);//рисуем прогресс убыли секунд в каждой минуте
  u8g2.drawFrame(2,108,60,10);
   //////////////
  }
  else{//ставим на экран вторичную тему
  u8g2.setCursor(5,15);
  u8g2.print(" В");//
   u8g2.setCursor(5,30);
  u8g2.print("каждой");//
   u8g2.setCursor(5,45);
  u8g2.print(" минуте");//
  u8g2.setCursor(5,60);
  u8g2.print("есть...");//
  u8g2.drawXBMP(0, 63, 64, 64,schkala_A);// рисование
    }
 
  } while ( u8g2.nextPage() );
 // u8g2.sendBuffer();  
  }
  ///////////////////////////////////////
  void midi() {
  for (uint8_t i = 0; i < melodieLength; i++) {
    memcpy_P( &SoundSRAM, &sounds[i], sizeof(sound));
    tone(tonePin, SoundSRAM.freq, SoundSRAM.duration);
    vremia_A();//не забываем двигать стрелки часов во время исполнения мелодии
   delay(SoundSRAM.dly-150);
  }
}
/////////////////////////////////////////

 

Argus19
Offline
Зарегистрирован: 08.05.2022

b707 пишет:

Так какой метод надо рассмотреть - метод print или метод  прототип которого вы приводили выше?

 Извините. Моя ошибка. Интересует метод print и всё, что с ним связано. Т.е. каким образом библиотека понимает, что передаётся. Например:

#define Mpin (0)
float Value1;
.......
Value1 = analogRead(Mpin);
    lcd.print("Level: ");
  lcd.print(Value1);

 Сначала печатаем строку, затем число, полученное с аналогового входа. Как метод print понимает, что именно ему передали?

 

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

Argus19 пишет:
Сначала печатаем строку, затем число, полученное с аналогового входа. Как метод print понимает, что именно ему передали?

все, тушите свет.

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

Argus19 пишет:

Как метод print понимает, что именно ему передали?

 

прочитайте что-нибудь про перегрузку функций в Си. Именно в Си, а не в ардуино.

Вы же утверждали, что понимаете, как работают функции в Си...

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

Argus19 пишет:

 Сначала печатаем строку, затем число, полученное с аналогового входа. Как метод print понимает, что именно ему передали?

Метод print ничего не понимает - он тупой.

Должен понимать компилятор - он умнее.

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

Похоже что ТС опять пропал. То ли осознал дремучесть своих вопросов, то ли готовит новую порцию :)

Argus19
Offline
Зарегистрирован: 08.05.2022

b707 пишет:

прочитайте что-нибудь про перегрузку функций в Си. Именно в Си, а не в ардуино.

Вы же утверждали, что понимаете, как работают функции в Си...

 Перегруженный функции это набор функций, принимающих разные типы параметров. Посмотрел вышеуказанную библиотеку. Есть объявление класса, в который входит набор методов. Если компилятор выбирает из набора функций, имеющих одно название, ту, которая сможет работать с передаваемым типом, то не понятно, как компилятор выбирает метод, из набора с разными именами? Подозреваю, что где-то тут "собака порылась".

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

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

P.S. Метод = функция класса

lilik
Offline
Зарегистрирован: 19.10.2017

Перегружаемые функции имеют одинаковое имя, но разное количество или типы аргументов. Это разновидность статического полиморфизма, при которой вопрос о том, какую из функций вызвать, решается по списку её аргументов.

ТС, я думал вы экран хотите запустить, а не в понимашки играть. Вот первый же ответ для людей далёких от программирования и языков этих птичьих, но понятный. Что не ясно?, по "внешнему" виду аргументов!!!, не по имени.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Argus19 пишет:
Как метод print понимает, что именно ему передали?

В библиотеке стандартных функций Ардуино (называется wiring) НЕ ОДИН print, а МНОГО:

    size_t print(const __FlashStringHelper *);
    size_t print(const String &);
    size_t print(const char[]);
    size_t print(char);
    size_t print(unsigned char, int = DEC);
    size_t print(int, int = DEC);
    size_t print(unsigned int, int = DEC);
    size_t print(long, int = DEC);
    size_t print(unsigned long, int = DEC);
    size_t print(double, int = 2);
    size_t print(const Printable&);

Во время компиляции gcc видит с каким параметром написан вызов и использует максимально похожий метод, если подберет. Для понимания нужно зарубить на носу, ЧТО ВСЁ ЭТО - РАЗНЫЕ ФУНКЦИИ!!! Тип параметра - как-бы часть имени метода, понял?