Передача данных с помощью модемного соединения GSM
 

Понятие ‘GSM модем’ у большинства людей прочно ассоциируется с современным интернет-модемом в виде флешки, которая вставляется в USB порт. Однако существует еще достаточно большой класс модемов, предназначенных для использования в промышленных целях. Мы рассмотрим особенности применения таких модемов для простой передачи данных(CSD, это типа Dial-Up) на достаточно  большие расстояния. Честно говоря, данная информация справедлива также и к модемам CDMA. Я делаю упор на то, что вы уже немножко знакомы с АТ-командами и общими положениями стандарта V25Ter.
Типичный промышленный  модем представляет собой коробку с отсеком для SIM-карты, с разъемом RS-232(или RS485), антенным гнездом, гнездом для подключения телефонной трубки и разъемом питания(9-12В). Да-да, можно подключить самую обычную телефонную трубку и болтать как по мобильнику)).

 
Внутри модема на плате располагается радиомодуль(типа SIM300) и минимальная обвязка из компонентов, чтобы этот модуль себя чувствовал комфортно. Радиомодуль – это достаточно сложное и умное устройство на процессоре типа ARM7 или ARM9 со своей операционной системой. Некоторые модули позволяют загружать программы пользователя(например, GSM модули Wismo с поддержкой OpenAT ) или даже выполнять JAVA программы. Но мы оставим происходящие внутри процессы и будем рассматривать радиомодуль/радиомодем как «черный ящик».
Управление, как вы уже догадались, происходит через этот самый разъем RS-232(или 485) с помощью АТ-команд. Основные сигналы, присутствующие в RS-232:
DTR – сигнал готовности терминала. Когда компьютер(или контроллер) желает обратиться к модему, он должен активировать эту линию. Т.е. она должна быть установлена на протяжении всего сеанса связи.
Rx, TX – линия приема и передачи данных соответственно.
RTS, CTS – сигналы управления потоком(квитирование).
GND – общий(земля).

В большинстве случаев для подключения модуля/модема достаточно всего 3 линии: Rx, Tx и GND. Однако, мне попадались радиомодули, перед обращением к которым требовалось подергать сигналом DTR. Линии RTS-CTS лучше замкнуть между собой  чтобы модем никого не ждал. Рекомендую поэкспериментировать со своим модемом т.к. изделия разных производителей  могут немного по-разному реагировать на данные сигналы.
Для управления модемом используются АТ-команды. Т.к. они стандартизированы и хорошо описаны, то можно надеяться, что поставив модем другого производителя он сразу же начнет работать. Однако, это далеко не всегда так, потому что производители самостоятельно могут изменять поведение команд и добавлять свои собственные нестандартные команды. По этой причине рекомендуется изучить руководство по АТ-командам на ваш модем.

В качестве примера я выбрал модем MC52iWDT фирмы iRZ(построен на модуле MC52i).
Примерная инициализация модема перед началом использования:

ATE0 отключить режим эхо для упрощения обработки ответов
AT&D0 отключить проверку линии DTR
ATS0=0 блокировать автоподнятие трубки(если оно было включено)
AT+CBST=71,0,1 перевести модем в режим приема данных(принимать входящие подключения)
 
Теперь мы можем набрать номер нашего модема:

ATD1234567

1234567 – это номер модема, его следует набирать без точки с запятой(;) т.к. нам нужна передача данных, а не голоса.
Разумеется, это надо делать с другого(удаленного) модема, подключенного, например, к компьютеру с терминальной программой HyperTerminal.
На каждый сигнал вызова модем будет выдавать ответ RING. Чтобы поднять трубку, надо послать в модем команду ATA. После поднятия трубки и успешного установления соединения будет выдана текстовая строка типа:

CONNECT 9600 RL/P

С этого момента он переходит из текстового режима АТ-команд в режим передачи данных. Все принимаемые байты будут отправляться в RS-232, все передаваемые в модем  данные будут отправляться в эфир.
Т.о. мы получили почти прозрачное соединение(некое подобие длиннющего кабеля, соединяющего 2 СОМ-порта). Я говорю «почти прозрачное», потому что модем изначально требует некоторой инициализации и даже при настройке автоподнятия трубки выдает некоторые незапрашиваемые результирующие ответы типа RING, CONNECT, NO CARRIER и т.д. Более того есть  особенности  работы самой сотовой связи, которые мы рассмотрим чуть ниже.
Чтобы разорвать соединение, нужно перейти в режим АТ-команд. Для этого сделайте паузу более секунды и быстро передайте 3 плюса( +++ ). Модем скажет OK – все, теперь можно завершить связь командой ATH – повесить трубку. Если же вы передумали или входили в АТ-режим по другой причине(например для смены настроек), то чтобы возвратиться в режим передачи данных наберите команду ATO.

Шаг вперед: использование мультиплексора. Управление модемом осуществляется по одному физическому каналу RS-232. Это вызывает некоторые неудобства(или даже проблемы) если идет передача данных. Модем необходимо переключать между командным режимом и передачей данных. Протокол мультиплексора позволяет открыть сразу несколько виртуальных каналов(канал передачи данных + канал команд). Настраивается командой AT+CMUX. Протокол довольно подробно описан в статье «Реализация мультиплексного протокола для GSM-модулей Siemens»(Современная электроника №8, 2008г).

При передаче данных я столкнулся со следующими особенностями работы сотовой связи:
1. Услугу передачи данных CSD необходимо дополнительно заказывать у оператора. При этом надо набраться терпения и быть готовым к тому, что в офисе или службе техподдержки о ней почти ничего не знают.
2. После установления связи и прихода сообщения CONNECT реальная передача данных может начаться секунд через 10. А может и вовсе не начаться, о чем просигнализирует сообщение NO CARRIER.
3. При сильной загрузке сети целостность передаваемых данных может быть нарушена(вы будете принимать куски пакетов). Полезно использовать механизм таймаутов, чтобы через какой-то интервал перезапросить испорченный пакет или вовсе прекратить связь, чтобы впустую не тратить деньги на счету.
4. Передача данных может быть прекращена в любой момент времени. Как мне объяснили, у сотовых операторов голосовой звонок имеет наибольший приоритет. Поэтому когда кто-то желает позвонить, у вас тут же отнимают канал.
5.  Передача данных успешно идет с одного GSM-модема на другой GSM модем. Также нормально идет связь если звонить с GSM-модема на модем в городской телефонной сети(PSTN). Обратно(т.е. когда PSTN->GSM) связь не получается. Что-то здесь перемудрили наши ташкентские операторы. Оставим это на их совести.
6. Передача данных с GSM модема на простой PSTN модем идет значительно быстрее т.к. исключаются дополнительные задержки.
7. Сама по себе скорость передачи данных невысока, типичное значение – 9600 бод.

Теперь перейдем к рассмотрению подпрограмм для работы с модемом. Для примера я рассматриваю код из одного действующего проекта. Все лишнее, что не относится к АТ-командам и модему, было удалено. Код был написан для микроконтроллера STM32(процессор Cortex-M3)  в среде Keil uVision. Но т.к. написан на языке C, то не составит большого труда его портировать под какой-нибудь другой контроллер(надо переписать лишь аппаратно-зависимые функции ввода-вывода).  Задачи приведенной программы довольно просты: выполнить инициализацию модема и при установлении входящего подключения перевести буферы из командного режима в режим передачи двоичных данных.

USART. Функции для инициализации и работы с USART находятся в файле uart.c. Для передачи используется кольцевой буфер uart_tx_buf[] , управляемый по прерываниям. Кольцевой буфер позволяет организовать передачу байтов без потери процессорного времени на ожидание в функциях посылки небольших строк. В принципе можно было подключить DMA, но пока имеем то, что имеем.  Принимаемые от модема данные складываются в буфер uart_rx_buf[] и расшифровываются(в режиме АТ-команд). В файле irq.c вы найдете код обработчика прерывания USART.

Модем. Функции модема(файл modem.c) используют программные функции USART для организации физического канала связи с модемом. Поступающие от модема ответы в виде потока байтов сравниваются в подпрограмме modem_rsp_search()  с образцами ответов, находящимися в массиве at_cmd_pattern[]. Если такой ответ найден – в буфер ответов modem_respbuf[] помещается его номер. Машина состояний модема находится в функции modem_state_process().  Я просмотрел довольно много чужих  исходников. В большинстве случаев программисты сначала отсылают команду, а затем в бесконечном цикле ждут поступления ответа модема.   Такой подход прост в реализации, но здорово тормозит работу основной программы. Во многих случаях подобное  поведение кода просто недопустимо, поэтому я реализовал машину состояний на структуре выбора switch.

Основная программа (файл main.c)  содержит функцию main(), в ней запускается инициализация модема, за которой следует суперцикл.  В суперцикле происходит постоянный опрос буфера расшифрованных ответов(ф-ция modem_state_process) и при поступлении какого- либо ответа машина состояний изменяет свое состояние.

Приведенный код также был проверен на старом проводном(PSTN) факс-модеме Multitech 28.8K и показал свою работоспособность.

Мы рассмотрели особенности создания и программирования прямого модемного соединения GSM.   Несмотря на то, что сейчас большое распространение получили новые интернет технологии(GPRS/3G), они могут потребовать дополнительных затрат времени/ресурсов на их освоение и внедрение во встраиваемую систему. Но они хорошо подходят там, где требуется передача значительных объемов информации. Организация CSD соединения, напротив, требует минимума знаний, ресурсов и хорошо подходит для систем, которые редко передают небольшие пакеты информации.

 

    Скачать:

    Исходные коды для работы с модемом
 

На главную

Hosted by uCoz