Linux com port gui

Заметки о Linux, электронике, радиолюбительстве

Личный блог Вадима Кузнецова, RA3XDH

воскресенье, 27 июля 2014 г.

Работа с последовательным портом из консоли Linux

В предыдущем посте было показано как запустить UART на отладочной плате Launchpad для MSP430. Теперь рассмотрим как общаться с платой при помощи средств командной строки Linux. Используется плата с прошивкой из предыдущего поста. Для подробностей — см. под кат

Как известно, все устройства последовательных портов представлены файлами устройств в каталоге /dev.Через эти файлы и происходит общение ОС Linux с внешним устройством на последовательном порту. Чтобы передать что-то на внешнее устройство нужно записать данные в файл устройства, а чтобы считать информацию из устройства — прочитать данные из файла устройства. Это можно делать при помощи команд cat и echo так же как для обычных файлов на диске. Или внутри программы на С при помощи вызовов ioctl(), read() и write() или библиотеки termios.

Физическим последовательным портам RS232, к которым подключались диалапные модемы на старых компьютерах, соответствуют файлы устройств /dev/ttyS*, начиная с /dev/ttyS0. Виртуальным последовательным портам, которые создаются различными конвертерами USB UART соответствуют файлы устройств /dev/ttyUSB* и /dev/ttyACM*. Ядро Linux автоматически разпознаёт подключенное устройство, загружает для него драйвер и создаёт файл устройства. Вручную устанавливать драйвер, как в ОС Windows не требуется. Например, если подключить к USB преобразователь USB UART FT232, то создаётся файл устройства /dev/ttyUSB0, с которым можно работать также как и с обычным последовательным портом. На плате Launcpad находится микросхема TUSB3410, которая тоже представляет собой конвертер USB UART. Если подключить её к USB, то создаётся файл устройства /dev/ttyACM0. Чтобы общаться с платой нужно что-либо писать/читать с этого файла.

Чтобы пользователь мог читать или писать в файл устройства последовательного порта, его нужно добавить в группу dialout. Иначе работать с последовательным портом сможет только администратор root.

Простейшим приложением с графическим интерфейсом, которое работает с последовательным портом, является CuteCOM. Он обычно уже есть в вашем дистрибутиве Linux. Его можно установить из репозиториев. При помощи CuteCOM мы работали с платой в предыдущем посте. Выглядит CuteCOM вот так:

Работать с ним крайне просто. Указываем нужное устройство, если его нет в списке, то его можно впечатать вручную. Затем указываем скорость и параметры и нажимаем OpenDevice. В окне видим данные, которые пришли от устройства. В поле ввода в нижней части можем печать строку символов, которые предаются на устройство. Чтобы передать данный нажимаем Enter и смотрим ответ устройства в окне.

Теперь рассмотрим как работать с COM-портом из командной строки. Для этого служат три команды: stty, cat и echo.

Читайте также:  Как зарезервируйте копию windows 10 для себя

Команда stty устанавливает параметры и скорость COM-порта. Её формат:

stty -F

Чтобы установить параметры для платы Launchpad для соединения на скорости 9600 нужно выполнить:

$ stty 9600 -F /dev/ttyACM0 raw -echo

Параметр raw устанавливает, что данные в компьютер передаются байт за байтом так же как приходят в порт без преобразований. Аппаратное управление потоком отключено. Подробнее о том, что включает и выключает raw — см. man stty. Если не включить raw, то скорее всего ничего работать не будет.

Теперь в той же консоли нужно набрать

$ cat /dev/ttyACM0

И можно смотреть данные, которые приходят от платы. Выход — нажать Ctrl+C.

Теперь нажимаем на плате RESET и видим, что в консоди напечатался текст.

Чтобы передать в плату данные, в другой консоли нужно использовать команду echo и перенаправление вывода в файл устройства. Наберём в другой консоли:

$ echo "1">/dev/ttyACM0

Видим, что на плате загорелся красный светодиод и в первой консоли было выдано сообщение об этом. Чтобы убрать конец строки в передаваемых данных, то нужно использовать запуск echo -n, а чтобы интерпретировать 16-ричные коды — нужно echo -e. Ключи можно комбинировать.

В итоге должно получиться так:

Чтобы увидеть 16-ричные коды данных, приходящих от устройства, нужно использовать команду hexdump:

$ cat /dev/ttyACM0|hexdump -C

Получится вот так:

Чтобы иметь вывод данных от устройство на экран и в текстовый файл нужно использовать tee:

Источник

Собираем плату

Значит сделал я такую схемку (да простят меня ардуинщики и физики и вообще…). Короче не будем вдаваться в подробности ее корректности. По крайне мере она работает.

Короче на ней есть два светодиода подключенный к цифровым портам и фоторезистор подключенный к аналоговому порту. Будем писать интерфейс который позволит переключать светодиоды и считывать значения фоторезистора.

Для управления ардуино я буду использовать следующую схему

    Если я отправил символ ‘r’ – значит я хочу чтобы зажегся красный светодиод (англ. r

red)
Если я отправил символ ‘b’ – значит я хочу чтобы зажегся синий светодиод (англ. b

blue)

  • Если я отправил символ ‘p’ – значит я хочу чтобы устройство сообщило мне текущее значение фоторезистора
  • Вот такая у меня получилась программа для ардуино

    Создаем приложение

    И так открываем Qt Creator и создаем новый проект

    выбираем тип приложения

    ну и все собственно

    увидим что-то такое

    чтобы ошибки ушли. Надо один раз запустить приложение. Для этого кликаем на зеленый треугольник (либо жмем Ctrl+R)

    запустится наше интерфейс, который пока выглядит вот так:

    Собираем форму

    закрываем его и начинаем править. Для этого переключимся на форму двойным щелчком на mainwindow.ui

    собственно, увидим нашу форму:

    Теперь начнем перетаскивать на нее элементы формы. Сначала я хочу, чтобы у меня было поле в котором можно ввести порт к которому я буду коннектиться для общения с ардуино.

    Читайте также:  Linux mount nfs from windows

    Делается это так:

    • Label – это просто метка, не редактируемый текст.
    • LineEdit – поле для редактирования однострочного текста

    Не смотрите что пока все криво, мы в конце добавим немного магии чтобы все выровнять.

    Теперь сделаем две кнопки для включения красного и синего светодиодов

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

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

    А теперь чуток магии чтобы все это выровнялось

    если немного разъяснить, то тут я объединяю компоненты в горизонтальные группы (чтобы выбрать несколько элементов я удерживаю Ctrl)

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

    Можно запустить (Ctrl+R) и проверить как все работает

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

    меняем его на txtPort

    у остальных полей поменяем потом.

    Добавляем обработчик нажатия на кнопку

    Теперь давайте добавим реакцию на клик кнопки “Включить синий” для этого кликаем на нее правой кнопкой мыши и выбираем “Перейти к слоту”

    в Qt используется так называемый механизм сигналов (signal) и слотов (slot) это расширений C++, которое позволяет связывать событие с реакцией на событие более-менее естественный образом.

    В общем открывается такое окно где виден список сигналов, которые может послать кнопка. Например, когда вы просто нажали на кнопку, но еще не отпустили кнопку мышь, генерируется сигнал pressed, а если же вы отпустил мышь, то сгенерируется сигнал clicked.

    Короче суть в том, что мы к этому сигнал сейчас привяжем функцию (или если мыслить в рамках Qt – слот)

    выбираем clicked и жмем OK:

    нас кидает в редактор кода

    не будем мудрствовать и для начала давайте просто выведем какое-нибудь сообщение, правим функцию

    скорее всего вы увидите, что QMessageBox подчеркнуто и выдается ошибка:

    это потому что мы не подключим заголовочный файл с этим классом, ставим курсор на QMessageBox и жмем Alt+Enter

    и видим, как вверху добавился необходимый include

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

    Жмем Ctrl+R и кликаем на кнопку

    Выводим значение из txtPort

    Давайте теперь попробуем сделать так чтобы по нажатию на кнопку выводилось содержимое поля для ввода порта. Подправим функцию:

    Посылаем сообщение arduino

    Для работы с COM портом у QT есть класс QSerialPort, давайте подправим функцию чтобы она отправил символ “b” в порт и тем самым зажгла светодиод:

    он опять будет ругаться на QSerialPort (ставьте курсор на него, жмите Alt+Enter, выбирайте #include , ну либо руками сами добавляйте)

    Пробуем запустить. Жмем Ctrl+R

    И видим кучу ошибок:

    дело в том, что QSerialPort специализированная библиотечка, и чтобы ее начать использовать надо попросить QT использовать ее dll файл.

    Как это сделать. Для этого есть документация!) В ней указано что надо прописать класс заработал.

    Читайте также:  Windows запрашивает код активации

    У QtCreator встроенная документация по Qt, так что ставим курсор на QSerialPort и жмем F1

    собственно, тут видно какой заголовочный файл (Header) достаточно указать, и еще что-то про qmake

    qmake – это такой себе компилятор QT, который делает из QT C++ кода обычный C++ код, его поведение настраивается в *.pro файле

    Кликаем в левом меню Редактор

    далее выбираем GuiController.pro – собственно pro файл, ну или проще говоря project файл

    в самом верху в нем строчка:

    добавим к ней снизу

    пробуем запустить снова (Ctrl+R)

    уже по крайней мере запустилось!) Попробуем нажать на кнопку

    Ну да мы ведь порт не указали, так что логично

    Пробуем зажечь светодиод

    Собираем и подключаем нашу ардуинку. Заливаем на нее программу, за одно проверяем какой порт использовать

    запускаем нашу программу, вводим порт COM3 и смотрим:

    Давайте теперь добавим то что вернет arduino в ответ на зажжение светодиода, как мы помним там у нас есть:

    а в нашем обработчике мы в холостую читаем данные:

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

    Только сначала дадим ему осознанное имя. Переключаемся на mainwindow.ui

    теперь идем обратно в mainwindow.cpp и правим on_pushButton_clicked:

    у нас в программе никаких “Blue is on” так что можно с чистой совестью заявить, что это отправило нам ардуино.

    Правим красную кнопку

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

    запускаем и проверяем:

    в общем показывать, что диоды у меня действительно переключаются мне чего-то лень, но вот сообщения по крайне мере точно приходят с ардуино =)

    Читаем значения датчика освещённости

    Дадим осознанное имя поля для значения фоторезистора

    И добавим обработчик кнопке обновить:

    и пишем код (по сути копипастим с правкой в двух местах):

    Обновляем значения датчика освещённости в режиме реального времени

    Тыкать все время на кнопку обновить не очень интересно. Лучше, чтобы это делалось на автомате. При чем не именно кликанье на кнопку, а просто команда запроса значения и вывода его на форму. Допустим раз в секунду или чаще.

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

    Делается это так. В конструкторе добавляем таймер

    Теперь как только мы укажем правильный порт, начнут приходить значения:

    Вот собственно и все!

    БОНУС

    Писать порт все время лениво. Есть возможность получить список всех доступных портов. Делается это так.

    Сначала идем на mainwindow.ui и удаляем txtPort, на место него ставим Combo Box

    правим ему свойства

    • objectName меняем на cmbPort
    • кликаем дважды на sizePolicy и в свойстве Горизонтальная политика ставим Expanding, чтобы этот комбо бокс как и lineEdit занимал все свободное место

    возвращаемся к коду mainwindow.cpp и в конструкторе добавляем:

    Прикольно, что прям сразу подключается! Такие дела =)

    Источник

    Оцените статью