Кодировка русских букв компилятором
- Войдите на сайт для отправки комментариев
Сб, 13/08/2022 - 19:52
Я понимаю, что IDE Arduino работает с UTF-8, но в какую кодировку компилятор транслирует русские буквы?
Например, если в скетче написано:
Lcd.Display("АБВГДЕЖЗИ");
то, что будет записано в Atmega?
Компилятор ничего никуда не транслирует. Если файл в ASCI, то в памяти будут коды ASCI. Если файла в UTF-8, то в памяти будут коды UTF-8. Никакой самодеятельностью компилятор не занимается.
Если файла в UTF-8, то в памяти будут коды UTF-8.
Т.е. в памяти будут двухбайтные коды русских букв, как описано тут:
сылка
Ну, да. Можете их вывести в сериал (в цикле байт за байтом) и полюбоваться - ничего сложного.
Мне подсказали, что если сменить кодировку на ср1251, то символы станут однобайтовыми.Т.е., если у меня появилась фантазия использовать русские символы, то при перекодировке в cp1251, я буду экономить один байт на каждый символ?
буду экономить один байт на каждый символ?
Будете. Другой вопрос, что Вы собираетесь делать с этими символами? Например (чисто пример), если Вы собираетесь выводить их на экран, Вы должны понимать какой кодировки ожидает от Вас библиотека экрана. Если она ожидает cp1251, то так и надо делать. Но, если она ожидает UTF-8, то сильно удивится, увидев Вашу cp1251.
Вы должны понимать какой кодировки ожидает от Вас библиотека экрана. Если она ожидает cp1251, то так и надо делать. Но, если она ожидает UTF-8, то сильно удивится, увидев Вашу cp1251.
Библиотека, которую порекомендовал производитель дисплея, допил библиотеки от другого дисплея и не доведена до ума. Библиотека, судя по всему, ждёт только однобайтовые символы. Чисел принципиально не понимает.
Посмотрю исходную. Может пойму как допилить.
А последней фразы я не понимаю. Уверен, что и Вы тоже.
При передаче в библиотеку числа выводится, либо соответствующий ему символ, либо ничего.
Вот так объявлен метод класса:
void Display(char *str); //4 lines of 18 characters each.При передаче в библиотеку числа выводится, либо соответствующий ему символ, либо ничего.
Ну, да. А Вы чего ожидали?
Ну, да. А Вы чего ожидали?
Я ожидал, что магазин, в котором я купил дисплей, пришлёт библиотеку от производителя, а получил сначала не работающую библиотеку, а затем ссылку на недоделанную библиотеку. И это странно.
Почему-то была уверенность, что магазин Estardyn Official Store является ещё и производителем.
А чем она " недоделанная"? Уж не тем ли, что чисел не понимает?
Открою вам секрет - любая графическая библиотека при записи в нее чисел выводит на экран символы. По другому просто не бывает.
Ну а вот недоделанная библиотека выводит недоделанные числа...
Вы читали мой пост #8 ?
Вы читали мой пост #8 ?
Да. читал.
И то. что выше - мой ответ на это сообщение.
А чего вы вообще ждали от библиотеки? Сдается мне, что вам стоит разобраться. чем отличается число 1 от символа '1' и что из них выводится на экран. Подскажу - символ.
и чтобы нарисовать на экране единичку - надо передать библиотеке не число 1, а символ '1'
Вы читали мой пост #8 ?
Я прочел. Что ты хотел сказать? На дисплей передается строка символов (вот этот char *).
Попробую угадать: кириллицу не печатает? ;)))) А должна? Реально исчезающе мало библиотек для экранов, которые содержат кириллические шрифты. Часто бывает можно добавить свой шрифт - их есть на просторах Инета.
Ты бы дал ссылку на эту библиотеку - когда не лень посмотрит кто и подскажет, откуда взять шрифт с кириллицей хоть в какой-нибудь кодировке.
Мир программирования и электроники - он весь англоязычный и весь на латинице... ну еще бывают ДШ на китайском ;)))) но не на кириллице!
--------------------
Ты уж прости старика, просто такие посты о дисплеях, которые "не понимают по русски" - каждую неделю какой-нибудь новичок пишет. В твоей теме хоть глума мало... Попал под хорошее настроение!
Я прочел. Что ты хотел сказать?
Попробую угадать: кириллицу не печатает? ;))))
нет Влад, все хуже! он кидает туда число 65 - а эта "недоделанная либа" вместо "65" печатает "А" !!! Он посылает ей 240 - а она вообще не печатает ничего!
безобразие... никому нельзя верить... он рассчитывал. что хотя в магазине производителя дисплеев порядок...
Я прочел. Что ты хотел сказать? На дисплей передается строка символов (вот этот char *).
[/quote]
Если в прототипе указана строка, то и печатается строка. Если туда передать число, то оно интерпретируется как строка.
Зачем угадывать? Это очевидно из общения. Латиница входит в любую кодировку. И не должна, т.к. анализируются символы от '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). Как такой код понимает, что первый байт ноль?
[Если в прототипе указана строка, то и печатается строка. Если туда передать число, то оно интерпретируется как строка.
вопрос - если вы видите, что в прототипе СТРОКА - нафига вы туда число передаете?
1). Как такой код понимает, что первый байт ноль?
никак не понимает. Вы должны явно передать коду ноль. Причем не байт ноль, а символ ноль, то есть байт 48.
У меня такое впечатление, что вы так и не поняли разницу.
никак не понимает. Вы должны явно передать коду ноль. Причем не байт ноль, а символ ноль, то есть байт 48.
У меня такое впечатление, что вы так и не поняли разницу.
Нашёл нормальную таблицу UTF-8. Латиница и цифры занимают один байт, а после 127 символы становятся двухбайтовыми и до 4 байт. Не могли бы вы на примере какой-либо библиотеки разъяснить как метод .print понимает, что получил, строку и в какой кодировке, целое или вещественное число? В С++, если я правильно понимаю, что описано в прототипе, с тем функция и работает. Судя по всему, Arduino построена иначе.
Библиотека, которую я пытаюсь понять взята отсюда:
https://github.com/luetee/ST7567S_128X64_I2C
Как по вашему мнению, она допилена или нет?
Нашёл нормальную таблицу UTF-8. Латиница и цифры занимают один байт, а после 127 символы становятся двухбайтовыми и до 4 байт. Не могли бы вы на примере какой-либо библиотеки разъяснить как метод .print понимает, что получил, строку и в какой кодировке, целое или вещественное число? В С++, если я правильно понимаю, что описано в прототипе, с тем функция и работает. Судя по всему, Arduino построена иначе.
Просили пример библиотеки - получите: https://arduino.ru/forum/proekty/asoled-kompaktnaya-biblioteka-dlya-oled-displeya-128kh64-s-kirillitsei-utf-8
Только никому больше не говорите про отличие Ардуино от С++.
Я всё не пойму в чём проблема? Если на запрос '1' рисует 1, то что мешает дописать код чтоб на 1 рисовала 1?, а потом на 10 рисовала 1и рядом 0?
Экран то какой? На все ходовые уже давно всё поделали, и на русском и не на русском.
Только никому больше не говорите про отличие Ардуино от С++.
Поздно, я уже заметил :-)
Не могли бы вы разъяснить как метод .print понимает, что получил, строку и в какой кодировке, целое или вещественное число? В С++, если я правильно понимаю, что описано в прототипе, с тем функция и работает. Судя по всему, Arduino построена иначе.
давайте по порядку.
До того мы говорили про метод Display() , прототип которого вы приводили в сообщении #8. Теперь вдруг речь зашла про какой-то метод print, непонятно откуда взявшийся.
Так какой метод надо рассмотреть - метод print или метод прототип которого вы приводили выше?
Библиотека, которую я пытаюсь понять взята отсюда:
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); } } /////////////////////////////////////////Так какой метод надо рассмотреть - метод print или метод прототип которого вы приводили выше?
Извините. Моя ошибка. Интересует метод print и всё, что с ним связано. Т.е. каким образом библиотека понимает, что передаётся. Например:
#define Mpin (0) float Value1; ....... Value1 = analogRead(Mpin); lcd.print("Level: "); lcd.print(Value1);Сначала печатаем строку, затем число, полученное с аналогового входа. Как метод print понимает, что именно ему передали?
все, тушите свет.
Как метод print понимает, что именно ему передали?
прочитайте что-нибудь про перегрузку функций в Си. Именно в Си, а не в ардуино.
Вы же утверждали, что понимаете, как работают функции в Си...
Сначала печатаем строку, затем число, полученное с аналогового входа. Как метод print понимает, что именно ему передали?
Должен понимать компилятор - он умнее.
Похоже что ТС опять пропал. То ли осознал дремучесть своих вопросов, то ли готовит новую порцию :)
прочитайте что-нибудь про перегрузку функций в Си. Именно в Си, а не в ардуино.
Вы же утверждали, что понимаете, как работают функции в Си...
Перегруженный функции это набор функций, принимающих разные типы параметров. Посмотрел вышеуказанную библиотеку. Есть объявление класса, в который входит набор методов. Если компилятор выбирает из набора функций, имеющих одно название, ту, которая сможет работать с передаваемым типом, то не понятно, как компилятор выбирает метод, из набора с разными именами? Подозреваю, что где-то тут "собака порылась".
компилятор не выбирает метод, метод выбираешь ты. Компилятор подставляет тот, который более всего подходит по параметрам.
P.S. Метод = функция класса
Перегружаемые функции имеют одинаковое имя, но разное количество или типы аргументов. Это разновидность статического полиморфизма, при которой вопрос о том, какую из функций вызвать, решается по списку её аргументов.
ТС, я думал вы экран хотите запустить, а не в понимашки играть. Вот первый же ответ для людей далёких от программирования и языков этих птичьих, но понятный. Что не ясно?, по "внешнему" виду аргументов!!!, не по имени.
В библиотеке стандартных функций Ардуино (называется 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 видит с каким параметром написан вызов и использует максимально похожий метод, если подберет. Для понимания нужно зарубить на носу, ЧТО ВСЁ ЭТО - РАЗНЫЕ ФУНКЦИИ!!! Тип параметра - как-бы часть имени метода, понял?