Преобразование кириллического алфавита в азбуку Морзе

Kirsten

✩✩✩✩✩✩✩
2 Ноя 2021
2
0
Доброй ночи! Пытаюсь сделать код для Wemos d1 mini, который делает вот что. wemos создаёт точку доступа и локальный сайт. На котором будет поле для ввода текста и кнопка отправить. Когда я ввожу текст (на русском языке) и нажимаю на кнопку, он должен преобразовываться в азбуку морзе (для русского алфавита). Затем этот текст на азбуке морзе выводился миганием светодиода. Но не всё так гладко, английский алфавит он кушает, а кириллический нет. Может кто-нибудь подправить, просто мои полномочия на этом всё:D

C++:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char *ssid = "YourSSID";         // SSID точки доступа
const char *password = "YourPassword"; // Пароль для точки доступа

ESP8266WebServer server(80);
const int ledPin = D4; // Пин, к которому подключен светодиод

const char *morseAlphabet[] = {
  ".-",    // А
  "-...",  // Б
  ".--",   // В
  "--.",   // Г
  "-..",   // Д
  ".",     // Е
  "..-.",  // Ж
  "--..",  // З
  "..",    // И
  ".---",  // Й
  "-.-",   // К
  ".-..",  // Л
  "--",    // М
  "-.",    // Н
  "---",   // О
  ".--.",  // П
  "--.-",  // Р
  "...",   // С
  "-",     // Т
  "..-",   // У
  "...-",  // Ф
  "....",  // Х
  "-.-.",  // Ц
  "---.",  // Ч
  "----",  // Ш
  "--.-",  // Щ
  "-..-",  // Ъ
  "-.--",  // Ы
  "-.--.", // Ь
  "..-..", // Э
  ".-.-",  // Ю
  "--.--"  // Я
};

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  Serial.begin(115200);

  // Подключение к Wi-Fi
  WiFi.softAP(ssid, password);
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);

  server.on("/", HTTP_GET, handleRoot);
  server.on("/", HTTP_POST, handlePost);

  server.begin();
}

void loop() {
  server.handleClient();
}

void handleRoot() {
  String html = "<html><body>";
  html += "<h1>Преобразование текста в азбуку Морзе</h1>";
  html += "<form method='post' action='/'>";
  html += "Текст на русском языке: <input type='text' name='inputText'>";
  html += "<input type='submit' value='Отправить'>";
  html += "</form>";
  html += "</body></html>";
  server.send(200, "text/html", html);
}

void handlePost() {
  String inputText = server.arg("inputText");
  String morseText = textToMorse(inputText);
  server.send(200, "text/html", "Текст на азбуке Морзе: " + morseText);
  flashMorseCode(morseText);
}

String textToMorse(String text) {
  String morseCode = "";
  text.toLowerCase();

  for (int i = 0; i < text.length(); i++) {
    char currentChar = text[i];

    if (currentChar == ' ') {
      morseCode += " ";
    } else if (isAlpha(currentChar)) {
      int index = currentChar - 'a';
      morseCode += morseAlphabet[index];
      morseCode += " ";
    }
  }

  return morseCode;
}

void flashMorseCode(String morse) {
  for (int i = 0; i < morse.length(); i++) {
    char symbol = morse[i];
    if (symbol == '.') {
      digitalWrite(ledPin, HIGH);
      delay(100); // Длительность точки
      digitalWrite(ledPin, LOW);
      delay(100); // Пауза между символами
    } else if (symbol == '-') {
      digitalWrite(ledPin, HIGH);
      delay(300); // Длительность тире
      digitalWrite(ledPin, LOW);
      delay(100); // Пауза между символами
    } else if (symbol == ' ') {
      delay(300); // Пауза между словами
    }
  }
}
 

bort707

★★★★★★✩
21 Сен 2020
2,911
865
Но не всё так гладко, английский алфавит он кушает, а кириллический нет
C
Скорее всего проблема с кодировками. Ардуино использует UTF, в котором коды русских букв двухбайтовые. А код ваш написан для однобайтовой кириллицы, потому и не работает
 

Сотнег

★★★★★★★
15 Янв 2020
4,139
1,445
@Kirsten,
если вы код готовый где-то взяли, то самостоятельно вам его не исправить.
А так - проверяйте, если символ в строке имеет код 208 или 209, тогда отбрасываете его и обрабатываете уже следующий, как кириллический.

И штуки типа int index = currentChar - 'a'; или text.toLowerCase(); работать с кириллицей не будут.
 
  • Лойс +1
Реакции: bort707

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,296
948
58
Марий-Эл
@Kirsten, Перейдите под PlatformIO там есть возможность включить другую кодировку файла - Window1251.
Тогда прошивка будет понимать русский язык. Или пишите сами конвертор UTF8 -> Windows1251
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
472
79
Глупости. МК ничего не знает про текст, он работает с байтами. Любой текст это набор байт, не важно - английский это, русский или вообще арабский
Разве есть скетчи, вернее коды написанные русскими буквами? Я только учусь по книге УрокиС++ Ravesli мне её рекомендовали СтаринаПохабыч.
 

bort707

★★★★★★✩
21 Сен 2020
2,911
865
Разве есть скетчи, вернее коды написанные русскими буквами?
не очень понятно, что вы имеете в виду как "код русскими буквами". Конечно, операторы С++ писать кириллицей нельзя, а вот текстовые строки кириллицей Ардуино ИДЕ вполне допускает.
C++:
char aa[] = "привет";
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
472
79
Тогда мы с вами не поняли друг друга, я имел ввиду: Конечно, операторы С++ писать кириллицей нельзя .
 

bort707

★★★★★★✩
21 Сен 2020
2,911
865
Так ТС вроде и не нужно код на русском писать, только текстовые строчки
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,296
948
58
Марий-Эл
@Сотнег, "ё" и "Ё"
При перекодировке в ASCII все буквы кроме этих получают отбрасыванием первого кода и сложением второго кода с константой. Эти буквы декодируются отдельно.
Вот переписанный класс Print
C++:
size_t Print::print(const char *p)
{
  size_t n = 0;
  uint8_t c;
  while (1)
  {
    c = *p++;
    if(c >= 0xC0)
    {
      if(c == 0xC2) c = *p++; // ToDo добавил для некоторых служебных символов
      else if(c == 0xD0)
      {
        c = *p++;
        if(c == 0x81)         // Ё
        {
          c = 0xA8;
        }
        else if(c >= 0x90 && c <= 0xBF) c = c + 0x30;
      }
      else if(c == 0xD1)
      {
        c = *p++;
        if(c == 0x91)         // ё
        {
          c = 0xB8;
        }
        else if(c >= 0x80 && c <= 0x8F) c = c + 0x70;
      }
    }
    if(c == 0) break;
    if(write(c)) n++;
    else break;
  }
  return n;
}
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,296
948
58
Марий-Эл
@Сотнег, Кого забить? Как раз настроение есть.
Не понял, как в этих шести словах не учтены ё и Ё.
Посмотрите мой код и таблицу, что по ссылке данной вами. И там и там эти две буквы выделены.
У них одинаковый код с буквами "с" и "Б", но байт стоящий перед ними другой. Поэтому они обрабатываются отдельно. А не по общему принципу.
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,296
948
58
Марий-Эл
@Сотнег, Я не про азбуку. Я про перекодировку.
@bort707, Я переписал не конкретно под STM. Я просто переписал. А так как я программирую только STM. Поэтому я я про него и сказал. А что пришлось переписать?
Сами смотрите. Это стандартный "Print"

C++:
size_t Print::print(const __FlashStringHelper *ifsh)
{
  PGM_P p = reinterpret_cast<PGM_P>(ifsh);
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    if (write(c)) n++;
    else break;
  }
  return n;
}
Сравнивайте.

А переписывал я так для того, что бы не городить таблицу знакогенератора под UTF-8. Она слишком большая будет.
Я перекодирую код UTF-8 из IDE, на котором пишется программа, в ASCII. Тогда знакогенератор получается компактнее.