Кракозябры по UART

Тема в разделе "Arduino & Shields", создана пользователем Daniil, 4 дек 2014.

  1. Daniil

    Daniil Гуру

    Предисловие. Макетной платой от DFrobots, сегодня перепаивал контакты, хотел реализовать передачу по RS485 от ПК к ардуине, для этого нужно дёргать ногой на переходнике MAX485 RE DE. Мог ли я что то замкнуть на отладочной плате так, чтобы при соединении с Ардуиной что то замыкается и что то случается(описано далее) с UARTом? Всё описанное далее больше не контактирует с отладочной платой. Все делает только Arduino.

    Имею модифицированный код программы Blink:
    Код (Text):
    #include <SoftwareSerial.h>
    void setup() {
      pinMode(13, OUTPUT);
      Serial.begin(115200);
    }

    void loop() {
      digitalWrite(13, HIGH);  // turn the LED on (HIGH is the voltage level)
      delay(1000);              // wait for a second
      digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);              // wait for a second
      Serial.println("Hi");
      Serial.println(5);
      Serial.println("хорошо");
      int t=10;
      Serial.println(t,DEC);
      Serial.println(t,HEX);
    }
    Вот, что приходит на терминал:
    Termite.PNG
    Русские символы стали кракозябрами, до сегодня такого не было.
    Есть более сложный код, где происходит такая процедура:
    Код (Text):
    void posled_main_main_loop()
    {// принимаются данные с 5 каналов АЦП по 3 байта на 1 канал.
    unsigned long int bt1;
    unsigned long int bt2;
    unsigned long int bt3;
    unsigned long int time=millis();
    unsigned char mask=B10000000; // имеется chan_select, который указывает с каких каналов и их комбинаций нужно оцифровывать сигнал
    for (int i=0; i<=7; i++)      // chan_select=B11110010
        {
        if ((mask & chan_select)!=0)
            {
                my_transfer(0b01011000 | code_chan[i]);  // выбор соответствующего канала и посылка команды чтения АЦП
                bt1=my_transfer(0xFF); bt1=bt1<<16;      // приём 3ёх байт
                bt2=my_transfer(0xFF); bt2=bt2<<8;
                bt3=my_transfer(0xFF);
                ch[i]=(ch[i]*(k_average-1)+(bt1 | bt2 | bt3)); // усреднение
             
                        ch[i]=ch[i]/k_average;      // усреднение
                        switch (i)
                            {
                                case 0: Serial.print(":A00"); break; // посылка заготовок, "управляющая команда", говорят о том с какого канала считано
                                case 1: Serial.print(":B00"); break;
                                case 2: Serial.print(":C00"); break;
                                case 3: Serial.print(":D00"); break;
                                case 6: Serial.print(":E00"); break;
                            }
                        for (int j=5; j>=0; j--)  //посылка по одной четверке, чтобы все цифры были переданы, даже нули в начале числа
                            {
                                Serial.print((ch[i]>>j*4) & 0x0000000F,HEX);
                            }
                        Serial.print(char(13));  //конец посылки, "управляющий символ"
                        digitalWrite(REDE_pin, LOW); //задержка, ждём когда ПК ответит, RS485 переводим на приём
                        while (Serial.available()==0); // ждём когда ПК ответит
                        command_in=Serial.read(); // "очищаем" приёмный буфер
                        digitalWrite(REDE_pin, HIGH);  // RS485 переводим на передачу
            }
        mask=mask>>1; // переход к анализу следующего канала
        }        
    }
    Тут кракозябрами приходит всё - и цифры, и латинский текст.

    Есть предположения что случилось?
     
  2. r0c

    r0c Гик

    Хотите сказать, до сегодняшнего дня такая команды выполнялась без кракозябров?:)
    при этой библиотеке
     
  3. Daniil

    Daniil Гуру

    Код (Text):
    void menu() {
    Serial.println(" = Меню настроек = ");
    Serial.println(" 1. Выводов");
    Serial.println(" 2. COM-порта");
    Serial.println(" 3. SPI");
    Serial.println(" 4. Калибровки");
    Serial.println(" 5. Конфигурирование АЦП");
    Serial.println(" 6. Чтение регистров");
    Serial.println(" 7. Выбор канала(ов)");
    Serial.println(" 8. Передачи данных");
    Serial.println(" Введите номер команды: ");
    while (Serial.available()==0);
    command_in=Serial.read(); Serial.println(command_in-48); delay(100);
    switch (command_in)
      {
      case '1': setup_pin();          break;
      case '2': setup_serial();        break;
      case '3': setup_spi();          break;
      case '4': setup_calibration();    break;
      case '5': setup_calibration();    break;
      case '6': setup_calibration();    break;
      case '7': setup_calibration();    break;
      case '8': setup_data_transfer();  break;
      }
    }
    Это точно работало. При библиотеке, которую Вы написали.

    Дополнение=)
    Наблюдал приём символов в терминале. ("А", "5" и т.п.) потом он прислал то, что должен был прислать за 1 цикл loop, кроме последней строки (''-----------") и остановился.
    Код (Text):
    void loop() {
      digitalWrite(13, HIGH);  // turn the LED on (HIGH is the voltage level)
      delay(1000);              // wait for a second
      digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);              // wait for a second
      Serial.println("Hi");
      Serial.println("В"); // рус
      Serial.println("B"); // eng
      Serial.println(5);
      Serial.println("хорошо");
      //Serial.println(UCSR1B,BIN);
      while (Serial.available()==0);
      if (Serial.read()=='!')
      {
        Serial.println("?");
      }
      Serial.println("-----------------------------------------");
    }
    Он ожидает "!", далее работает так, что заходит в бесконечный цикл и ожидает восклицательный знак.
    Но до этого он несколько раз отрабатывает без "!".
    Termite.PNG

    Ещё одно наблюдение. Окно терминала активно - текст не приходит.
    Любое другое окно делаем активным или обратно делаем активным окно терминала, то передача происходит=)))
     
    Последнее редактирование: 4 дек 2014
  4. Alex19

    Alex19 Гуру

    Не знаком с данным модулем.

    Проблема с кодировкой, поэтому идут "Кракозябры ". Где-то, читал что сама IDE работает в UTF-8, а монитор порта ардуины в win-1251 (если ошибся, поправьте). Обычно это не проблема, так как Вы все равно используете монитор порта только для отладки.

    А для конечного решения или пишите программу для коммуникации по Com порту или пользуетесь готовой.
    Вот к примеру мой код в Ардуине
    Код (Text):

    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
      Serial.println("Привет");
      delay(1000);
    }
     
    Код приложения для в взаимодействии с ардуиной на C#
    Код (Text):

    serialPort.PortName = port_combobox.Text;
    serialPort.BaudRate = Convert.ToInt32(baudrate_combobox.Text);

    serialPort.RtsEnable = false;
    serialPort.DtrEnable = true;
    serialPort.Parity = Parity.None;
    serialPort.DataBits = 8;
    serialPort.StopBits = StopBits.One;
    serialPort.Encoding = Encoding.UTF8;
     
    Без строки serialPort.Encoding = Encoding.UTF8; идут "Кракозябры ", но с ней, получаю нормальный ответ.

    [​IMG]

    Вроде существует, еще один метод, писать в порт в нужной кодировке, на которой работает монитор порта. Но как это сделать не знаю.

    Очень странно, они всегда идут такими, если пытаться писать в порт русские символы и смотреть монитором порта. Говорю о HardwareSerial.

    С #include <SoftwareSerial.h> не работал. Но у Вас в 1 блоке кода, она не используется, используется именно HardwareSerial. Вы подключили библиотеку но не воспользовались ей.
    http://arduino.cc/en/Reference/softwareSerial

    Не очень понял, Вы не можете пользоваться и монитором порта ардуины и сторонними программами для чтения из порта. Работа с Com монопольная вещь.

    Если, что-то упустил или был не точен, надеюсь более опытные товарищи меня поправят.

    UPD. Как вариант попробуйте http://putty.org.ru/.
    Она может работать как монитор порта COM. И отлично выводит русские символы с ардуины.
     
    Последнее редактирование: 4 дек 2014
    Daniil нравится это.
  5. Daniil

    Daniil Гуру

    Ну что же, начнём... скандалы, интриги, расследования!))
    Для начала спасибо за наводку Alex19.
    Именно так и получается, но не все IDE. Распишу ниже.
    Не сразу обратил внимание, думал аппаратному UART нужно библиотеку подключать, вот я и подключил. Спасибо, что пояснили.
    Не пробовал повторять и не хочу, аномалия какая то... Да, я понимаю, что с COM портом работает только одна программа, но под словом "окна" я имел в виду и окна браузера, папок или других программ, которые к COM порту отношения не имеют.
    Ниже. Расписываю тут то, что обещал выше=)
    Мне не полюбилась Arduino IDE из-за блеклых цветов выделения и из-за очень светлой цветовой гаммы. Поэтому я случайно набрёл на IDE MariaMole. Мне она понравилась и решил использовать в своём проекте.
    Возьмём код:
    Код (Text):
    void setup()
    {
    Serial.begin(115200);
    }

    void loop()
    {
      Serial.println("ку");
      Serial.println("hi");
      delay(1000);  
    }
    Прошью в Arduino IDE. Посмотрю в 4 разных терминала (по очереди, конечно)(ММ = MariaMole):
    pic1.png
    Прошью в ММ Stable:
    pic2.png
    Прошиваем в MM Beta:
    Обратите внимание, что MM Beta даже в редакторе кода не поддерживает кириллицу.
    pic3.png
    Сегодня на слабеньком ноуте и офисном ПК и на домашнем монстре MM Stable решил зависнуть.
    Приём данных осуществляет программа на Visual Basic 6, тестировалось в termite - и кириллица, и цифры из переменных присылались адекватно.
    Пришлось вернуться к Arduino IDE (я днём не знал про MM Beta). Куча кода ей не помеха, но появились кракозябры, ужасно то, что кракозябры в цифрах(!).
    Пробовал в MM beta кракозябр в цифрах нет, придётся пока отказаться от кириллицы в коде.

    Ещё наблюдение:
    У меня в коде есть реализация "меню", я её делал для быстрой отладки(оперативно менять напряжения на выводах, режимы менять и т.п.). Реализовано текстом, поэтому занимает 13 кБ.
    До сегодняшней перепайки, а значит и до добавления пары строк всё работало прекрасно.
    (В MM Stable пробовал, т.к. её хотел вернуть) Решил убирать лишнее из кода и...я не знаю как описать...но чем меньше занимал код, тем "правильней" он работал. Правильность работы оценивалась по данным, которые я наблюдал в мониторе COM-порта.
     
    Последнее редактирование: 5 дек 2014
    sdfg нравится это.
  6. Alex19

    Alex19 Гуру

    Не за что все подсказываем и учимся друг у друга.

    Таких тестов не делал, говорил о стандартной Arduino IDE.

    Это библиотека, на случай если не хватает Serial-ов. К примеру ардуина соединена с другими ардуинами, микросхемами, сенсорами работающими по Serial. У Uno только 1 Serial, у Mega 2560 сразу 4.

    Точно аномалия.

    Попробуйте http://putty.org.ru/. Он без проблем, показывает русские символы.
    Вы может просто отправлять код сообщения на клиентское приложение, а там просто в switch-е выбирать необходимый текст. К примеру отправлять сообщение типа ?10;0! 10 - команда, 0 - параметр.

    Если команд много, можно использовать enum.
    Код (Text):

    /// <summary>
    /// Перечисление - Тип операции
    /// </summary>
    enum OperationTypeEnum  
    {
        /// <summary>
        /// Не выбрана
        /// </summary>
        OT_None = 0,
        /// <summary>
        /// Проверка какая ардуина подключена, запрос на запуск ответа
        /// </summary>
        OT_CheckWhatKindArduinConnectedStart = 1,
        /// <summary>
        /// Проверка какая ардуина подключена, ответ от ардуины
        /// </summary>
        OT_CheckWhatKindArduinConnected = 2,
        /// <summary>
        /// Проверка какая ардуина подключена, запрос на остановку ответа
        /// </summary>
        OT_CheckWhatKindArduinConnectedStop = 3,
        /// <summary>
        /// Старт протокола передачи данных
        /// </summary>
        OT_ProtocolDataTransferStart = 4,
        /// <summary>
        /// Остановка протокола передачи данных
        /// </summary>
        OT_ProtocolDataTransferStop = 5,
        /// <summary>
        /// Проверка протокола передачи данных
        /// </summary>
        OT_CheckProtocolDataTransfer = 6,
        /// <summary>
        /// Старт инициализации Arduino
        /// </summary>
        OT_InitArduinoStart = 8,
        /// <summary>
        /// Инициализация Arduino
        /// </summary>
        OT_InitArduinoWork = 9,
        /// <summary>
        /// Остановка инициализации Arduino
        /// </summary>
        OT_InitArduinoStop = 10,
        /// <summary>
        /// TPA готов к работе
        /// </summary>
        OT_TPAReadyToWork = 11,
        /// <summary>
        /// Старт ТПА
        /// </summary>
        OT_StartTPA = 12,
        /// <summary>
        /// Стоп ТПА
        /// </summary>
        OT_StopTPA = 13,
        /// <summary>
        /// Отладочное сообщение с Arduino
        /// </summary>
        OT_DebugMessageFromArduino = 14,
        /// <summary>
        /// Отладочное сообщение с PC
        /// </summary>
        OT_DebugMessageFromPC = 15,
        /// <summary>
        /// Ошибка на стороне Arduino
        /// </summary>
        OT_ErrorMessageFromArduino = 16,
        /// <summary>
        /// Ошибка на стороне PC
        /// </summary>
        OT_ErrorMessageFromPC = 17
    };

    /// <summary>
    /// Переменная хранящая тип операции
    /// </summary>
    OperationTypeEnum operationType = OT_None;
     
    Пользуюсь таким вариантом, но дело вкуса и рациональности.

    Правильное решение, лучше поэтапно писать код, отлаживая и проверяя все нюансы. Так проще, а когда код большой, порой сложно понять, что именно не работает.
     
    Daniil нравится это.
  7. kocmockocmoc

    kocmockocmoc Нуб

    У меня подобная проблема была. Причем кракозябры даже на цифры были. Скетч мигания светодиодом - работал идеально. Скетч клиента - не работал уже. Оказалось я просто обновил до последней версии платы для esp8285 (практически полный аналог 8266). И там в ядре был какой-то косяк. Откатился на более раннюю версию платы и все заработало.
     
  8. YeS

    YeS Гик

    На самом деле нет. Где-то полгода назад после очередного обновления IDE кириллица пошла через сериал без искажений. Был немало удивлён тоже.
     
  9. DIYMan

    DIYMan Guest

    Ну если посмотреть Release Note, то там видно, что с определённой версии просто прикрутили поддержку UTF-8 к монитору порта, вот и "пошла кириллица". Ничего необычного и экстраординарного - рядовое развитие софта.
     
    Tomasina нравится это.
  10. YeS

    YeS Гик

    Удивило не то, что это возможно, а то что это таки было сделано, через более чем 10 лет после выпуска софтины. Это и стало неожиданностью.
     
    DIYMan нравится это.
  11. DIYMan

    DIYMan Guest

    А я что, о другом писал, что ли? Странный вы.
     
  12. DIYMan

    DIYMan Guest

    Занудный вы, и невнимательный, однако. Почитайте ВНИМАТЕЛЬНО мою цитату. Вы видите разницу между "последовательным портом" и "монитором порта", не? Я писал именно про монитор порта, ни о какой передаче куда бы то ни было - речи не шло.

    Писец, не прочитают внимательно, не вникнут, зато всегда надо вставить свои 5 копеек не в тему. Слова "прикрутили поддержку UTF-8 к монитору порта" в КОНТЕКСТЕ ОБСУЖДАЕМОЙ проблемы с неправильным ПОКАЗОМ UTF-8 в мониторе порта означают ровно то, что UTF-8 в МОНИТОРЕ ПОРТА стал ОТОБРАЖАТЬСЯ корректно.

    Короче, вы два раза не в тему.

    З.Ы. Жду очередной порции цитирования от вас всем известных вещей, типа того, что передача по последовательному порту идёт побайтово и там вообще никто ничего не знает ни про какие кодировки, ибо оно там и не надо - сколько байт запросили передать, столько и передали. И да, добрый вам совет - учитесь отделять данные от способа их представления, помогает.
     
    Последнее редактирование модератором: 18 мар 2018
  13. Arduino_man

    Arduino_man Гик

    Если бы я был админом, то отредактировал или удалил бы пост, т.к. это нецензурная лексика и оскорбление.
    Если вдруг не читали, то внизу есть ссылочка "Условия и правила", и вот из нее выдержка:
    Отредактируйте, пожалуйста, пост.
     
  14. b707

    b707 Гуру

    Да ладно вам - товарищ Олех известный.... какое слово подобрать - БОЛТУН. Любит ляпнуть не подумав или вообще не разбираясь в вопросе. На ардуино.ру его уже раскусили - теперь он сюда перекинулся.
     
  15. Arduino_man

    Arduino_man Гик

    Отлично. Пишу жалобу команде форума.
    ===UPD===
    Написал. Ждите "письмо счастья" за злостное нарушение правил форума (с отказом им подчиняться).
     
    Последнее редактирование: 19 мар 2018
  16. Arduino_man

    Arduino_man Гик

    Не привожу опровержение из-за боязни за Вас - а то упадете еще в обморок :)
    Именно поэтому я и советую Вам побольше думать при выборе слов.
     
    Последнее редактирование: 19 мар 2018
  17. Arduino_man

    Arduino_man Гик

    И кстати:
    От Вас, многоуважаемый грубиян @Olej, я и не хотел бы ничего узнавать. Мне куда приятнее общаться с знающими побольше Вас, но, однако, вежливыми людьми, не нарушающими правил форума и не позволяющими себе оскорблять кого ни попадя на каждом шагу.
     
  18. DIYMan

    DIYMan Guest

    Ясно, товарищи: ещё один невменяшка объявился на форуме, так и запишем - сразу в игнор, дабы не видеть подобных высеров далее. Всем советую поступить так же ;)
     
    Arduino_man нравится это.
  19. Arduino_man

    Arduino_man Гик

    Это также можно расценивать как намеренное оскорбление.
    Понятно?
    Вы про @Olej?
     
    Последнее редактирование: 20 мар 2018
  20. Arduino_man

    Arduino_man Гик

    Спасибо за разрешение! Обязательно воспользуюсь!