Отправка AT команд на COM-порт через командную строку Windows 10?
Через программу HyperTerminal все AT команды работают. Все ок. Модем выполняет звонки на указанный номер. Но вот через cmd все глухо. При отправке команды «echo ATD+48*********; >> COM9» ноль реакции (модем на 9-м ком порте). Есть какие-то идеи в чем проблема? Я хочу создать .bat файл в котором будет скрипт из нескольких команд. Только сначала нужно чтобы модем принимал AT команды через командную строку.

Отслеживать
20.2k 6 6 золотых знаков 37 37 серебряных знаков 81 81 бронзовый знак
задан 10 июл 2017 в 11:34
Andriy Hryvachevskyi Andriy Hryvachevskyi
1 1 1 серебряный знак 1 1 бронзовый знак
Как из браузера отправлять команды в COM порт?
Столкнулся на днях с очень интересной задачей, на работе, мною же, внедрялась Система Быстрых Платежей по QR коду.

Задача не сложная, у банков представлены достаточно удобные API для интеграций и собственно первый этап интеграции, с самописной CRM системой, работающей на web сервере – прошел гладко и быстро.
Работая в браузере можно было легко сформировать QR код и отправить его клиенту для последующей оплаты или показать в окошке на новой вкладке, как удобно…

Но как оказалось это не слишком удобно и есть специальные девайсы – дисплеи для вывода именно QR кода.

Собственно, не раздумывая был заказан один такой дисплей для интеграции в CRM и упрощения действий для менеджеров, ну и конечно же большего удобства клиентов.
Буквально через 3 дня курьер принес посылку с заказанным дисплеем (в интернете не так много контор которые предлагают подобное решение) и вот этот чудо девайс на рабочем столе.

Далее при распаковке посылки оказалось, что кроме самого дисплея и пупырки в которую он был упакован, больше ничего не было, от слова совсем, ни драйверов, ни инструкций, ничего, даже гарантийного талона, только талон на доставку…
После переписки с менеджерами, где был куплен сей девайс, на почту прилетело письмо с краткой инструкцией:

А дальше в папочке лежал текстовый файл с примером команд и программка (Terminal v1.9b by Bray) для проверки что сие чудо работает.

На законный вопрос о существовании какого-либо API или приложения для интеграции был следующий ответ:

Достаточно странный ответ для компании, которая продает не запчасти для последующего самостоятельного сбора, а готовый продукт, продает, по сути, полурабочий девайс, вокруг которого нужны еще танцы с бубном чтобы он заработал. Хотя еще более интересно посмотреть на «ПО которое будет работать с банками с внешним API» …
Но делать нечего, надо как-то интегрировать, что-то придумывать.
Набор команд у девайса не большой:
[QL]Вывод QR кода с логотипом
[CQ]Стирание QR кода с экрана
[CQL]Стирание QR кода с экрана без стирания логотипа
[T1]Вывод текста в верхней зоне экрана над QR кодом
[T2]Вывод текста в нижней зоне экрана под QR кодом
Поддерживает UTF-8, команда должна завершаться переводом строки.
После изучения списка команд, тестового формирования QR кода, начались поиски каких-либо решений на просторе интернета.

Основная сложность заключалась в том, что девайс подключен к компьютеру по USB, а менеджеры работают в CRM системе через браузер. И как организовать связь между ними сходу мыслей не было.
На хабре нашел статью про возможность подключения к COM порту у браузера Chrome, но в последствии оказалось, что там есть возможность только читать с COM порта, а тут задача именно отправлять команды.
В общем и целом, интеграция зашла в тупик, не понятно, что делать и с какой стороны подходить.
К счастью, в голове вовремя проскользнула мысль про XMLHttpRequest и кроссдоменную работу.
Быстро была сверстана страничка для теста, на компьютере включен XAMPP и простенький PHP код который должен был получать POST запрос с параметрами, после чего создавался текстовый файл и уже после этого PHP запускал BAT файл который посылал команду в COM порт.


На удивление все сработало, на дисплее появилось заветное сообщение!
На самом деле на этом можно было бы и остановиться, на каждой машине тихонечко поднять локальный сервер XAMPP, добавить в автозагрузку службы и в принципе все бы работало, но внутренняя тяга к максимальному удобству заставила подумать еще чуть-чуть и найти более красивое решение.
К сожалению, последний раз с программированием именно для windows я сталкивался больше 15 лет назад, поэтому пришлось читать и вспоминать самые азы, благо не все забыто и вспомнить получилось.

Приложение, выполняет те же функции, как и сервер XAMPP – просто слушает на локальном хосте 80 порт, создается небольшой сервер, но уже без всяких BAT файлов отправляет нужные команды в COM порт, дисплей работает…
Конечно, там еще есть очень много к чему приложить руки, но данное решение лично мне нравится гораздо больше, оно более лаконично.
Если вдруг кто-то знает еще варианты как решить проблему интеграции браузера и COM порта, напишите пожалуйста, буду благодарен.
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 порт
Мне часто нужно посылать короткие строки символов в последовательный порт на операционной системе 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
Вот полный пример на скриншоте окна консоли:

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