Как отправить команду на com порт
Перейти к содержимому

Как отправить команду на com порт

  • автор:

Как отправить команду на com порт

Мне часто нужно посылать короткие строки символов в последовательный порт на операционной системе Windows (перевод статьи [1]). Это можно использовать для отправки команд роботу или в другие устройства, основанным на микроконтроллерах. Для соединения с устройством можно использовать аппаратный преобразователь USB-to-serial, которые в обилии можно найти на сайтах AliExpress, Ebay и dx.com. Для отправки символов есть удобная утилита SerialSend [2], но также можно использовать встроенные команды Windows: echo, set и mode.

К примеру, нужно послать строку «hello» в COM1 (имя первого последовательного порта Windows). Для этого можно просто ввести в консоли cmd.exe следующую команду:

echo hello > COM1

Команда echo обычно используется для отображения строк в консоли командной строки, когда нужно вывести какое-нибудь информационное сообщение из скрипта команд *.BAT или *.CMD. Однако в этом примере с помощью символа > применено перенаправление вывода в специальный файл COM1, который в действительности не файл на диске, а последовательный порт. По этой причине строка «hello» отправляется в последовательный порт вместо экрана консоли.

Но для такого вывода текста в последовательный порт есть несколько препятствий:

• Нужно заранее знать номер COM-порта, который хотите использовать. Если Вы используете преобразователь USB-to-serial, то этот номер может неожиданно поменяться, особенно если Вы подключили его в другой разъем USB (программа SerialSend [2] предоставляет простой альтернативный метод отправки строк в любой доступный COM-порт с самым высоким порядковым номером, что может быть очень полезным).
• Строка, которая отправляется в нашем примере, в действительности имеет длину 8 байт, потому что она включает 1 байт завершающего пробела (код ASCII 0x20) плюс символ возврата каретки (CR, код 0x0D) и перевода строки (LF, код 0x0A).
• Отправлять можно только обычные символы текста. К примеру, произвольные байты с кодами 0x00 .. 0x19 отправлять не получится, на это способна только утилита SerialSend [2].
• Последовательный порт, который Вы хотите использовать, может быть настроен не на ту скорость, которая Вам нужна. В таком случае дополнительно нужно использовать команду mode, чтобы сконфигурировать скорость baudrate (и/или другие параметры фрейма последовательного протокола).
• COM-порты с большими номерами могут быть не распознаны для такого примера, но для их использования есть обходной маневр, описанный ниже.

Следующий пример — более надежный аналог команды из примера выше:

set /p x="hello" < nul >\\.\COM22 

Эта команда может выглядеть поначалу довольно непонятной, давайте разберем её по частям.

Команда set обычно используется для установки значения для так называемой переменной окружения (environment variable). Например, следующая команда должна использоваться для установки переменной окружения с именем x в значение строки «sunshine»:

set x="sunshine"

Когда в команде set используется ключ /p, то команда set выводит приглашение для пользователя, чтобы он ввел значение для устанавливаемой переменной окружения. Приглашение отображается на экране в виде строки, предоставленной в команде. Например:

set /p x="Введите значение для x: "

Конечно, нас в сущности не интересует установка значения переменной x как таковой, сейчас это просто средство для достижения другой цели. Все, что мы хотим — вывести строку «hello» без символов CR и LF, и команда set только лишь предоставляет способ для решения этой задачи.

Мы не хотим, чтобы команда set остановилась на ожидании ввода пользователя, чтобы он ввел значение для переменной x, для этого команда set перенаправлена на ввод из nul (т. е. нет ввода как такового, вместо обычного ввода, который обычно происходил бы из консоли). Это означает, что команда сразу завершит работу, вместо того, чтобы ожидать ввода пользователя. Перенаправление ввода осуществляется символом < , указанным перед nul.

set /p x="Enter a value for x: "

Теперь, чтобы вывести только корректные символы, и только их, нам нужно перенаправить вывод в COM22. Чтобы гарантировать, что имя COM-порта будет правильно распознано, и произошло перенаправление вывода, здесь вместо специального системного имени используется его полная форма «\\.\COM22».

set /p x="hello" < nul >\\.\COM22 

И наконец, чтобы сконфигурировать скорость перед отправкой строки в последовательный порт, можно использовать команду mode. Например, для настройки COM8 на 38400 бод, 8 бит данных, без проверочного бита четности, нужна следующая команда:

mode COM8 BAUD=38400 PARITY=n DATA=8

Вот полный пример на скриншоте окна консоли:

Windows send symbols COM port via cmdline

[Ссылки]

1. Simple command line trick for sending characters to a serial port in Windows site:batchloaf.wordpress.com.
2. SerialSend: утилита для работы с виртуальным COM-портом.

Отправить символы по COM-порту и получить ответ в Bash

К COM-порту /dev/ttyS0 подключен мобильник Siemens-M50.

Параметры порта: 9600 8N1, Апп. упр. потоком: Да

Мне нужно отправить на него команду «AT» через BASH и увидеть ответ «OK». Команда «AT» нормально срабатывает в minicom, но мне нужно отправлять ее не интерактивно, а скриптом.

Я заранее в соседней консоли запускаю команду:

cat /dev/ttyS0 

Затем в основной консоли даю команды:

stty 9600 cs8 -parenb crtscts -echo -F /dev/ttyS0 echo "AT" > /dev/ttyS0 

Но в логе в соседней консоли ответа «OK» не видно. А спустя несколько секунд в логе появляется «ERROR».

Я проверил в minicom, при каких условиях появляется «ERROR» в ответ на команду «AT». Оказалось, что если набрать «AT», но потом не нажимать Enter, а просто ждать, то через некоторое время появится «ERROR».

Я подумал, что может быть до модема не доходит символ переноса строки при выполнении echo «AT» > /dev/ttyS0.

Поэтому я выполнил подряд две команды:

echo "AT" > /dev/ttyS0. echo "ATZ" > /dev/ttyS0. 

Если бы перевод строки не отправлялся, в логе бы было видно:

ATATZ 

Однако, в логе я вижу

AT ATZ 

То есть, перевод строки таки отправляется.

Тогда вопрос: почему модем не отвечает «OK», а отвечает спустя некоторое время строкой «ERROR»?

Developing.ru

Здраствуйте!
Сразу скажу, что я не программист, а железячник. Делфи знаю постольку, поскольку.
У меня возник такой вопрос:
Нужно передать в COM-порт команду в HEX. Как это можно сделать в Делфи. И еще: как можно отправить текстовый фаил в ком порт из делфи (по аналогии с досом copy con filename.txt comN)?

Naeel Maqsudov Сообщения: 2551 Зарегистрирован: 20 фев 2004, 19:17 Откуда: Moscow, Russia Контактная информация:

Ну, если по аналогии с DOS, то и в DOS и в Windows имена файлов
PRN, LPTn, COMn и CON являются предопределенным и асоциированными с определенными устройствами.

Следовательно самый экологичный способ, это отдать работу с устройствами на откуп операционной системе. Т.е. открыть файл с таким именем и писать туда данные.

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

var f:text; . System.Assign(f,"COM1"); System.Rewrite(f); System.Write(f,#8#43#11#44#99#127+""+chr($23)+chr($FA)); Close(f); 

Так как Assing перекрыта модулями, которые обычно подгружаются позже System, то в Delphi скорее всего явно придется указать из какого модуля должна быть взята процедура Assign.

Ошибки отлавливутривать внутри опций компилятора . c помощью переменной System.Lastresult.

По файлы CON могут быть открыты на чтение (Reset вместо Rewrite). По идее с COMn тоже должно работать.

Naeel Maqsudov Сообщения: 2551 Зарегистрирован: 20 фев 2004, 19:17 Откуда: Moscow, Russia Контактная информация:

Да. Должно быть можно!

прокатывает! Становится в ожидание. Будет печатать на экран все что придет в ком-порт (1 байт = 1 символ) до тех пор пока не втретится символ ^Z (конец файла).

mch Сообщения: 5 Зарегистрирован: 08 дек 2005, 15:06
System.Write(f,#8#43#11#44#99#127+»<-там десятичные коды символов, здесь текст, а там НЕХ->«+chr($23)+chr($FA));
Можно подробней про формат

Naeel Maqsudov Сообщения: 2551 Зарегистрирован: 20 фев 2004, 19:17 Откуда: Moscow, Russia Контактная информация:

Да. Этот синтаксис существует начиная с версии ТурбоПаскаль 5.0

String: ‘это символы, заключенные в кавычки’
Char: ‘x’ — это 1 символ
Также, в случаях, когда в коде програмы целесообразнее (для читабельности)
употреблять коды символов вместо самих символов используется:
1) Char(X), (это не функция а typecast (приведение типов)). X может быть переменной (выражением) типа Byte или константой типа Byte. Шестнадцатеричные числа предваряются знаком $.
Например: Char(X); Char(48); Char($2A) являются выражениями типа Char. Их можно сложить — получится String — Char(X)+Char(48)+Char($2A).
2) Нотация #X. Здесь нельзя употреблять 16-чных чисел, но она может создавать и выражения типа Char и выражения типа String (без использования знака +).
#48=Char(48)=Char($30)=’0′
#48#49=Char(48)+Char(49)=Char($30)+Char($31)=’01’

mch Сообщения: 5 Зарегистрирован: 08 дек 2005, 15:06
Спасибо, буду пробовать. А как отправить текстовый файл в ком?

Naeel Maqsudov Сообщения: 2551 Зарегистрирован: 20 фев 2004, 19:17 Откуда: Moscow, Russia Контактная информация:

А читать файл по байтам, да и передавать.
Вот только непонятно, где конец файла. Для команды Copy это управляющий символ ^Z.
Выхода, собственно 2:
1) что-то типа битстаффинга (точнее, в нашем случае байтстаффинга) Собираем статистику, вычисляем, какое значение в файлах встречается реже всего. Объявляем его стоп-байтом. Чтобы исключить имитацию стоп-байта в данных, если нужно передать значение равное стоп-байту, то передаем его дважды. При приеме
если получено два значения равные стоп-байту подряд, то сохраняем только одно. А если получено одно и долго ничего нет, то завершаем прием.

2) Передача пакетами с указанием длины.
Берем кусочек файла в N байт. Перенаем сначала N, потом данные. А когда передавать больше нечего, то передаем 0. При приеме, получив N складываем следующие N байт в буфер (или пишем в файл). Если пришедшее N=0 то завершаем прием.

Первый способ надежнее, на мой взгляд.

Чтение: Read(f,Ch);
Запись: Write(f,Ch);
Ch — переменная типа Char
Числовое значение передаваемого/получаемого байта = byte(Ch)

ТЕМА: Как передать данные через com порт?

Как передать данные через com порт? 7 года 10 мес. назад #5015

Есть задача передать bin файл через com порт на плату DE2-35.
Модуль UART приемника я взял из проекта воспроизведения звука на плате марсаход.
Из командной строки CMD я отправляю файл длинной 16384 байта в порт командой copy 1.rom /b com1 передача проходит, но на плату приходит 15870 байт, причем иногда на пару сотен байт больше, иногда меньше. А хотелось бы бинарник передать на плату байт в байт- то есть если в бинарнике FF, то получить с модуля UART ресивера 11111111, если 00, то получить 00000000,
с первого по последний байт.
Подскажите ваши соображения.
Заранее спасибо!

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *