Содержание:
В настоящее время в промышленности применяется широкий спектр способов связи технологических объектов. в качестве примера можно привести одни из наиболее распространённых — беспроводная связь по стандартам GPRS, 3G, 4G и проводные способы по интерфейсам RS-485 или Ethernet.
Они позволяют передавать относительно большие объёмы данных за малые промежутки времени. Однако, не всегда возможно применение указанных способов по разным причинам. К числу таких ограничений можно отнести технические (невозможность прокладки кабеля на местности или низкий уровень сигнала по стандарту GPRS/3G) или экономические (цена автоматических GPRS/3G роутеров выше чем цена GSM-модемов).
Cвязь, использующая пакетную передачу данных, зачастую требует наличия статического IP-адреса опрашиваемого узла сети, а также постоянных расходов на трафик. Поэтому использование сервиса коротких сообщений (SMS) для информирования персонала о ходе технологического процесса, а также управления им, ещё широко распространено. Однако, GSM-модемы не имеют встроенной логики и управляются с помощью АТ-команд.
Панели оператора ELHART имеют возможность программирования на языке С (написание макросов), что позволит в рамках конкретного примера исключить применение ПЛК для управления GSM-модемом. При помощи макросов панель оператора может получать прямой доступ к любому из интерфейсов и записывать в него последовательность символов в определённой кодировке. Расширением данного применения может быть использование макросов для установки соединения панелей оператора ELHART с устройствами, использующими нестандартные протоколы.
Настройка оборудования заключается в настройке GSM-модема Cinterion BGS2T-RS485+MC1,5/6-ST-3,81 и панели оператора ELHART ЕСР-07. Для реализации данного примера возможно использование любого GSM-модема.
Настройка GSM-модема заключается в настройке скорости обмена, количества битов данных, длины интервала стоп-бита и контроля чётности по используемому интерфейсу. Модем должен быть подключен к персональному компьютеру (ПК) по интерфейсу RS-485 через преобразователь интерфейсов RS-485/USB (например, Delta IFD6500), одновременно он может быть подключен и к панели оператора по тому же интерфейсу. Интерфейс RS-485 выбран для удобства, возможно использование RS-232 и, соответственно, модема с таким интерфейсом.
Для настройки модема возможно использовать любую программу для ПК, позволяющую записывать данные непосредственно в СОМ-порт (в данном примере используется ComPUMP).
Настройка скорости обмена GSM-модулей модемов, как правило, заключается в подаче АТ-команды «AT+IPR=9600». После последнего символа (в данном случае это «0») необходимо добавить символы возврата каретки и перевода строки, их коды в таблице ASCII - 0D и 0A соответственно. Программа ComPUMP должна изначально иметь настройки скорости обмена, количества битов данных, длины интервала стоп-бита и контроля чётности, соответствующие настройкам модема. в случае успешного приёма и исполнения команды модем ответит «AT+IPR=OK». Скорость обмена 9600 бод выбрана для примера и будет использоваться далее при настройке интерфейса RS-485 панели оператора.
Настройку скорости обмена также можно произвести с панели оператора, добавив соответствующий код в макрос, в данном примере это показано ниже. Настройки проверки чётности, количества стоп-битов и битов данных остаются по умолчанию.
Настройка модема завершена.
Настройка сенсорной панели оператора производится на примере модели ECP-07 и в данном случае сводится к написанию макроса. Графический интерфейс используется для визуализации процесса. Основными задачами при отправке SMS являются:
Основными задачами при приёме:
для создания макроса необходимо перейти в пункт меню «Макросы» - «Главный макрос» - «Создать макрос»:
Для макросов панелей оператора ELHART существуют понятия внешних и внутренних переменных. Внешними переменными являются все переменные из области памяти панели (например, область памяти LW). Внутренние переменные объявляются в теле макроса.
Внешними переменными в данном примере являются:
1. error_com_param: возвращает значение «0» в случае ошибки установки параметров интерфейса, «1» - в случае удачной передачи; адрес
2. error_outport: возвращает значение «-1» в случае ошибки передачи, в случае удачной передачи возвращает число переданных байтов;
3. error_inport: возвращает значение «-1» в случае ошибки приёма, в случае удачного приёма возвращает число принятых байтов;
4. Imm_alarm: стартовый адрес внешних битов регистров панели, запускающих цикл отправки SMS;
5. modemok: стартовый адрес байтовых регистров для записи строки признака успешной настройки модема;
6. LB50: битовый адрес, изменяемый по команде в SMS-сообщении;
7. Pressure: стартовый адрес байтовых регистров для записи значений в отправляемое SMS-сообщение;
8. number_input: байтовый регистр (тип данных «string») для ввода номера телефона.
Соответственно указанным на Рисунке 4 адресам регистров необходимо создать элементы визуализации на экране панели:
Элементу ввода «Ввод телефонного номера без +7» соответствует адрес LW3 (тип данных «строка», количество символов — 10, кодировки ASCII и Unicode), элементу «Имитация события No1» - LB0, «Значение параметра No1» - LW16 (тип данных «целое число», 1 разряд до запятой, 2 после), «Значение параметра No2» - LW17 (тип данных «целое число»), «Имитация события No4» - LB3, элементу отображения «Включение/выключение бита по СМС-команде» - LB50, элементу «Настройка модема прошла успешно» - LW18 (тип данных «строка», количество символов — 11, кодировки ASCII и Unicode).
Макрос решает следующие задачи:
1. Распознавание внешнего признака отправки SMS в виде битовой переменной памяти панели, в данном примере реализовано 10 признаков.
2. Запуск алгоритма отправки SMS по одному из внешних признаков. Если в один момент времени активно несколько признаков, они будут отработаны по очереди. СМС отправляется в текстовом режиме (латиница, кодировка ASCII). в СМС вставляется заголовок (задан по умолчанию в теле макроса) и 2 переменные из байтовых регистров памяти панели.
3. Распознавание получения нового СМС.
5. Выполнение одной из двух команд, заложенных в СМС.
Подробный листинг кода макроса.
// Строки 2...5: вызов внешних стандартных библиотек, требуемых для выполнения данного макроса #include#include #include #include // Строка 8: вызов основного метода макроса (является обязательным) int MacroMain() { /* Строки 17...23: блок объявления внутренних переменных макроса i, j, switch_byte – переменные вспомогательных циклов и оператора «switch»; send_sms_last, CR, LF – переменные, содержащие специальные символы («1А», возврат каретки, перевод строки) для коммуникации с модемом; alarm, alarm_ff, done — битовые переменные признаков необходимости отправки (alarm), фиксации получения признака необходимости отправки (alarm_ff), признак завершённой отправки (done); *send_baud, *send_format, *send_echo, *send_sms_notify, *send_store, *send_command, send_number[10], number_input[20], *read_command, *delete_command — указатели на строковые константы (кроме send_number[10], number_input[20], которые являются массивами строк), используемые для настройки модема; *header[10] — заголовок СМС-сообщения, formed_sms[22] — сформированное СМС, записываемое в интерфейс, modem_cond[] - строка состояния модема для экрана визуализации, recv_buff[200] — буфер чтения из интерфейса. */ short i,j,switch_byte,send_sms_last[]={26},CR[]={13},LF[]={10}; bool alarm[10], alarm_ff[10], done[10]; unsigned char *send_baud={"at+ipr=9600"},*send_format={"at+cmgf=1"},*send_echo={"ate0"},*send_sms_notify={"at+cnmi=2,1"},*send_store={"at&w"},*send_command={"at+cmgs=8"}, send_number[10],number_input[20]="",*read_command={"at+cmgr=1"},*delete_command={"at+cmgd=1"}, *header[10]={"Awariya No1","Awariya No2","Awariya No3","Awariya No4","Awariya No5","Awariya No6","Awariya No7","Awariya No8","Awariya No9","Awariya No10"}, formed_sms[22]="",modem_cond[]="Modem is OK!",recv_buff[200]; // end Блок объявления внутренних переменных /* Строки 28...50: блок предварительной настройки модема конфигурация модема посредством настройки его интерфейса (инструкция SetComParam) и последовательной подачи команд установки скорости обмена, отключения эха, установки текстового формата СМС, включения уведомления о приёме СМС, команды сохранения настроек. */ int error=SetComParam(1,9600,8,1,110,2); // команда настройки интерфейса: интерфейс COM2, 9600 бод, 8 бит данных, 1 стоп-бит, без проверки чётности, СОМ2 используется как двухпроводный RS-485 SetWord(@error_com_param@,0,error); int error_outport=Outport(1,send_baud,strlen(send_baud)); // команда настройки скорости модема - в данном примере 9600 бод error_outport=Outport(1,CR,1); // команда возврата каретки error_outport=Outport(1,LF,1); // команда перевода строки Delay(50); error_outport=Outport(1,send_echo,strlen(send_echo)); // команда включения/выключения эха модема - в данном примере эхо выключено error_outport=Outport(1,CR,1); error_outport=Outport(1,LF,1); Delay(50); error_outport=Outport(1,send_format,strlen(send_format)); // команда выбора формата отправки СМС - в данном примере текстовый формат error_outport=Outport(1,CR,1); error_outport=Outport(1,LF,1); Delay(50); error_outport=Outport(1,send_sms_notify,strlen(send_sms_notify)); // команда включения уведомления о приёме СМС - в данном примере уведомление включено error_outport=Outport(1,CR,1); error_outport=Outport(1,LF,1); Delay(50); error_outport=Outport(1,send_store,strlen(send_store)); // команда включения сохранения настроек модема error_outport=Outport(1,CR,1); error_outport=Outport(1,LF,1); SetWord(@error_outport@,0,error_outport); Delay(50); // end блок предварительной настройки модема // Оба блока выполняются однократно при загрузке панели // Строка 56: инициализация бесконечного цикла while(1) для выполнения инструкций, расположенных в теле цикла, каждый цикл панели оператора. Все строки, расположенные выше строки 55, выполняются 1 раз при подаче питания. while(1) { // Строка 59: опрос интерфейса модема каждый цикл панели оператора при помощи стандартной инструкции Inport. в буфер приёма читается 200 байтов int data_count=Inport(1,recv_buff,200,100); // приём данных из интерфейса каждый цикл панели // Строки 61...74: проверка содержимого буфера приёма на наличие символов 'OK' как признака получения настроечных команд модемом; проверка содержимого буфера приёма на наличие символов 'CMTI' как признака получения нового СМС; опрос состояния признака требуемой отправки СМС (alarm[i]) и установка вспомогательных флагов в соответствии с текущим состоянием. for(i=0;i<23;i++) { if(recv_buff[14]=='O'&&recv_buff[15]=='K') // если полученная строка содержит последовательные символы 'OK' в определённом месте, на экран панели выводится признак 'Modem is OK' {SetWord(@modemok@,i,modem_cond[i]);} if(recv_buff[3]=='C'&&recv_buff[4]=='M'&&recv_buff[5]=='T'&&recv_buff[6]=='I') // если полученная строка содержит последовательные символы 'CMTI', то начинается последовательность чтения СМС {switch_byte=33;} if(i<10) { alarm[i]=GetBit(@Imm_alarm@,i); // приём признака отправки СМС if(alarm[j]&!alarm_ff[j]){alarm_ff[j]=1;} // если признак отправки СМС с данным номером появился впервые, то это событие фиксируется if(!alarm[j]){alarm_ff[j]=0;done[j]=0;} // если нет признака отправки СМС, то флаги фиксации и окончания посыла сбрасываются if(alarm_ff[j]&!done[j]){switch_byte=2;} // если есть признак отправки СМС, но он не отработан, то начинается последовательность отправки СМС } } // end проверка содержимого буфера приёма // Строка 78: вызов оператора switch с выражением switch_byte для реализации последовательности приёма-отправки СМС switch(switch_byte) { // Строки 82...86: заполнение строкового массива send_number символами, введёнными с экрана визуализации панели (номер телефона); формирование буфера отправки number_input конкатенацией строк команды отправки СМС и номера телефона case 2: { for(i=0;i<20;i++){send_number[i]=GetWord(@number_input@,i);} // номер телефона, введённый с экрана панели, из строки преобразуется в последовательность символов sprintf(number_input,"%s%s",send_command,send_number); // в буфер обмена записывается команда отправки СМС с номером телефона } // end заполнение строкового массива // Строки 90...97: запись буфера отправки и двух специальных символов отправки СМС в интерфейс модема при помощи инструкции Outport, ожидание в течении 3 секунд для приёма ответа от модема case 3: { error_outport=Outport(1,number_input,strlen(number_input)); // запись команды отправки СМС в интерфейс error_outport=Outport(1,CR,1); // команда возврата каретки error_outport=Outport(1,LF,1);SetWord(@error_outport@,0,error_outport); // команда перевода строки Delay(3000); // задержка для ожидания ответа модема о готовности ввода СМС switch_byte=4; } // end запись буфера отправки // Строки 101...108: очистка буфера приёма перед его заполнением, чтение 12 байтов из интерфейса модема, поиск в буфере приёма последовательности '> ' для продолжения алгоритма отправки — ввода текста сообщения case 4: { for(i=0;i<12;i++){recv_buff[i]=0;} // очищение буфера приёма перед чтением интерфейса data_count=Inport(1,recv_buff,12,100); // чтение 12 байтов из интерфейса SetWord(@error_inport@,0,data_count); // установка признака ошибки или количества прочитанных байтов Delay(1000); if(recv_buff[2]==62&&recv_buff[3]==32) {switch_byte=5;}else{switch_byte=100;break;} // если в буфер принята последовательность '> ', то переход к следующему шагу, иначе стоп и выход из цикла отправки } // end очистка буфера // Строки 112...132: запись заголовка СМС-сообщения и формирование основного текста исходя из номера события. в данном примере различные тексты СМС формируются для групп событий 1..3, 4..6, 7..8, 9..10. Для группы 4..6 СМС состоит только из заголовка. Стандартная инструкция sprintf формирует строковый массив «formed_sms» для записи в интерфейс из строки-константы в кавычках “symbols%f symbols %d” (специальны символы «%f» и «%d» используются для подстановки в этой позиции строки переменных из следующих аргументов инструкции sprintf), а также из произвольного количества переменных (в любом формате), записываемых через запятую внутри скобок инструкции sprintf. В данном примере в одно СМС записывается максимально 2 переменных из памяти панели оператора из регистров LW16 и LW17. Переменная LW16 преобразуется в число с плавающей точкой при помощи инструкции «(float)» и записывается в строку по месту символа «1.2%f». Переменная LW17 используется как целое число и подставляется в строку по месту символа «%d». Окончательный вид строки в СМС - «D=5.26 bar, Dgaz=49 kPa» (в случае, если переменные LW16 и LW17 будут содержать 526 и 49 соответственно). case 5: { error_outport=Outport(1,header[j],strlen(header[j])); // запись заголовка СМС сообщения error_outport=Outport(1,LF,1); // команда перевода строки Delay(1000); if(j>=0&j<=2){ // если произошло событие с 1 по 3, то sprintf(formed_sms,"D=%1.2f bar, Dgaz=%d kPa",((float)(GetWord(@Pressure@,0)))/100,GetWord(@Pressure@,1)); // записываемое значение складывается из строки и двух переменных, записываемых в строку по месту символов '%f' (для float) и '%d' (для short) error_outport=Outport(1,formed_sms,strlen(formed_sms)); // количество записанных данных SetWord(@error_outport@,0,error_outport); } if(j==6|j==7){ // если произошло событие 7 или 8, то sprintf(formed_sms,"D=%1.2f bar",((float)(GetWord(@Pressure@,j)))/100); // записываемое значение складывается из строки и одной переменной, записываемой в строку по месту символа '%f' (для float) error_outport=Outport(1,formed_sms,strlen(formed_sms));SetWord(@error_outport@,0,error_outport); } if(j==8|j==9){ // если произошло событие 9 или 10, то sprintf(formed_sms,"Dgaz=%d kPa",GetWord(@Pressure@,j+1)); // записываемое значение складывается из строки и одной переменной, записываемой в строку по месту символа '%d' (для short) error_outport=Outport(1,formed_sms,strlen(formed_sms));SetWord(@error_outport@,0,error_outport); } Delay(10); switch_byte=6; } // end запись заголовка СМС-сообщения // Строки 145...154: запись символа окончания ввода СМС «1A». После записи этого символа модем начнёт процедуру отправки СМС. В строке 109 вызывается функция задержки с временным интервалом 4 секунды для ожидания ответа о статусе отправки от модема case 6: { error_outport=Outport(1,send_sms_last,1);SetWord(@error_outport@,0,error_outport); // запись признака окончания СМС - символа '1A' Delay(4000); // задержка для ожидания ответа об отправке СМС switch_byte=7; } // end запись символа окончания ввода СМС // Строки 145...154: очистка буфера приёма перед его заполнением, чтение 100 байтов из интерфейса модема, анализ полученных данных. В случае, если в любом месте строки принята последовательность '+CM', устанавливается признак завершения отправки СМС по данному номеру события и производится выход из цикла отправки (инструкция «break»). Иначе если принята последовательность 'ERR', то производится выход из цикла отправки (инструкция «break») без установки признака о завершении. Таким образом в следующем цикле макроса процедура отправки начнётся заново case 7: { for(i=0;i<100;i++){recv_buff[i]=0;} // очищение буфера приёма перед чтением интерфейса data_count=Inport(1,recv_buff,100,100); // чтение 100 байтов из интерфейса SetWord(@error_inport@,0,data_count); Delay(100); if(recv_buff[2]=='+'&recv_buff[3]=='C'&recv_buff[4]=='M'){switch_byte=0;done[j]=1;} // если в буфер принята последовательность 'ERR', то возврат в начало цикла, иначе стоп и выход из цикла отправки с установкой признака отправки if(recv_buff[2]==69&recv_buff[3]==82&recv_buff[4]==82){;} break; } // end чистка буфера приёма перед его заполнением // Строки 158...165: запись команды чтения СМС в интерфейс case 33: { error_outport=Outport(1,read_command,strlen(read_command)); // запись команды чтения СМС error_outport=Outport(1,CR,1); error_outport=Outport(1,LF,1);SetWord(@error_outport@,0,error_outport); Delay(1000); switch_byte=34; } // end запись команды чтения СМС в интерфейс // Строки 169...183: очистка буфера приёма перед его заполнением, чтение 200 байтов из интерфейса модема, анализ полученных данных. В случае, если в любом месте строки принята последовательность 'run', устанавливается бит LB50 в памяти панели. Иначе если принята последовательность 'stop', то производится сброс бита LB50. Принятое СМС сохранится под номером «1» в хранилище модема в том случае, если не было ранее полученных СМС case 34: { for(i=0;i<100;i++){recv_buff[i]=0;} // очищение буфера приёма перед чтением интерфейса data_count=Inport(1,recv_buff,200,1000); // чтение 200 байтов из интерфейса SetWord(@error_inport@,0,data_count); for(i=0;i<200;i++) { if(recv_buff[i-2]=='r'&recv_buff[i-1]=='u'&recv_buff[i]=='n') // если в принятой строке присутствуют символы 'run' {SetBit(@LB50@,0,1);} // то установка бита LB50 в 1 if(recv_buff[i-3]=='s'&recv_buff[i-2]=='t'&recv_buff[i-1]=='o'&recv_buff[i]=='p') // если в принятой строке присутствуют символы 'stop' {SetBit(@LB50@,0,0);} // то установка бита LB50 в 0 } Delay(1000); switch_byte=35; } // end запись команды чтения СМС в интерфейс // Строки 187...194: запись команды удаления первого СМС в хранилище модема. Таким образом следующее принятое СМС также будет сохранено модемом под номером «1» и для работы с хранилищем модема не потребуется дополнительных действий case 35: { error_outport=Outport(1,delete_command,strlen(delete_command)); // запись команды удаления первого СМС error_outport=Outport(1,CR,1); error_outport=Outport(1,LF,1);SetWord(@error_outport@,0,error_outport); Delay(1000); switch_byte=0; } // end запись команды удаления первого СМС в хранилище модема } // Строки 200...201: увеличение счётчика событий на «1» в конце каждого цикла и присвоение ему значения «0» в случае, если счётчик равен «10» (всего 10 событий с 0 до 9) j+=1; // увеличение счётчика событий каждый цикл панели оператора if(j==10){j=0;} // если значение счётчика равно 10, то обнуление счётчика // end увеличение счётчика событий return 0; }
Данный алгоритм реализован при помощи макросов панелей оператора ELHART на языке С. Алгоритм показывает возможности операторских панелей ELHART по прямой работе со встроенными интерфейсами и может использоваться не только как пример работы с GSM-модемами, но и с другими устройствами, имеющими нестандартные протоколы связи.
В алгоритме (в качестве примера) показаны способы чтения и записи произвольных последовательностей символов в интерфейс, а также работа с такими типами данных, как указатели на строки и строковые массивы данных.
Инженер ООО «КИП-Сервис»
Петров Н.П.
Список использованной литературы:
Читайте также:
При добавлении товара возникла ошибка. Пожалуйста, повторите попытку чуть позже.