Вот решил освоить работу ПЛК с модемами, вроде разобрался как работать с портом, с настройками, чтением и записью. Но вот с модемом ничего не выходит, при отправке ему любой АТ команды, модем отвечает "$R" не могу понять почему, подскажите как программно работать с модемом, если вас не затруднит поясните как работает ваша программа, которую я здесь скачал. Основная часть в принципе понятна, но лучше если полностью мне кто нибудь пояснить саму суть. По Гипер Терминалу модем все прекрасно понимает, отвечает на АТ команды. Подключал так же ПЛК - ПК - Модем, контроллер по изменению переменной отправлял АТ команду, в гипер терминале я ее увидел, так же контроллер принимает данные отправленные с гипер терминала, а модем ничего не видит, думал что то с кабелем, но нет, скорее всего я где то в программе допускаю ошибку, мне кажется что неправильно принимаю данные, подскажите как именно это делается?
FUNCTION_BLOCK GSM_Modem_SMS
VAR_INPUT
com_num:PORTS:=COM1; (*Номер порта для работы с модемом*)
phone_num:STRING; (*Телефонный номер для посылки смс*)
send_SMS_text:STRING(255); (*Строка для отправки по указанному номеру шлем если не пустая*)
rcvSMS:BOOL:=FALSE; (*Флаг необходимости проверки SMS*)
use_unicode: BOOL := FALSE; (* Использование кодовой таблицы - юникод - ограничение на сообщ - 21 символ*)
END_VAR
VAR_OUTPUT
rcvedSMS:STRING(255); (*Полученное СМС*)
rcvedPhonNum:STRING(20); (*Телефон с которого отправлено SMS*)
rcvedTm:STRING(25); (* Время отправки*)
sended_OK:BOOL; (*Признак отправки СМС*)
END_VAR
VAR
port_opened: BOOL := FALSE; (*Признак открытия порта*)
com_handle: DWORD;
init_stage:BYTE:=0; (*Стадия инициализации*)
dbecodeBuf;
(*Буфферы для обмена*)
rcvBUF: ARRAY [0..1023] OF BYTE;
rcvStr:STRING(255);
snd_str:STRING(255);
iter: DWORD;
com_set: COMSETTINGS;
(*Комманда чтения СМС*)
strTakeNewSMS:STRING:='AT+CNMI=1,1$R';
strGetNewSMS:STRING:='+CMTI: ';
strSetCharSetUC:STRING:='AT+CSCS="UCS2"$R'; (* Формат UNICODE*)
strSetCharSet8B:STRING:='AT+CSCS="GSM"$R'; (* Формат UNICODE*)
strSetMsgMode:STRING:='AT+CMGF=0$R'; (* Использовать !НЕ! Text Mode!! А __PDU__*)
strGetNewMsg:STRING:='AT+CMGR=';
strGetDelMsg:STRING:='AT+CMGD=';
strGetAllMsg:STRING:='AT+CMGL=1$R';
strSMS_num:STRING(20);
do_send_sms2: BOOL := FALSE;
sz: DWORD := 0;
a_char: POINTER TO STRING;
do_rcv_sms2: BOOL := FALSE;
port_init:BOOL:=FALSE;
res:BOOL;
(*Таймеры ожидания для работы*)
tmr_rcv_wait:TON;
tmr_snd_wait:TON;
tmr_rq_wait:TON;
(* Number out*)
NUMBER_OUT: STRING(20);
I: BYTE;
PACKET:STRING(255);
uc_sms_text:STRING(255);
sms_c:STRING(255);
END_VAR
(*Открываем порт*)
IF NOT port_opened THEN
com_handle:=SysComOpen(com_num);
IF com_handle<>16#FFFFFFFF THEN
port_init:=TRUE;
ELSE
SysComClose( com_num);
com_handle:=SysComOpen( com_num);
port_init:=TRUE;
END_IF
(*Настраиваем скорость*)
com_set.Port:=com_num;
com_set.dwBaudRate:=9600;
com_set.byParity:=0;
com_set.dwTimeout:=0;
com_set.byStopBits:=0; (* *)
com_set.dwBufferSize:=0;
com_set.dwScan:=0;
res:=SysComSetSettings(com_num,ADR(com_set));
(*Успешно открыли*)
IF NOT res THEN
port_opened:=TRUE;
END_IF
(* Установка PDU*)
SysComWrite(com_num,ADR(strSetMsgMode),LEN(strSetM sgMode),0);
rcvstr:='';
END_IF
IF init_stage<2 THEN (* Ожидание настройки PDU*)
tmr_rq_wait(in:=(init_stage=1),PT:=t#3s);
init_stage:=1;
sz:=SysComRead(com_num,ADR(rcvBUF),1024,0);
IF sz>0 THEN (*Что то приняли*)
FOR iter:=0 TO sz-1 DO
a_char:=ADR(rcvBuf[iter]);
rcvStr:=CONCAT(rcvStr,LEFT(a_char^,1) );
IF LEN(rcvStr)>250 THEN
rcvStr:=DELETE(rcvStr,1,1);
END_IF
END_FOR
END_IF
IF FIND(rcvStr,'OK')<>0 THEN
init_stage:=2;
(*Инициализация успешна шлем CharSet*)
IF use_unicode THEN
SysComWrite(com_num,ADR(strSetCharSetUC),LEN(strSe tCharSetUC),0);
ELSE
SysComWrite(com_num,ADR(strSetCharSet8B),LEN(strSe tCharSet8B),0);
END_IF
rcvstr:='';
END_IF
IF tmr_rq_wait.Q THEN (*Недождались - переиниц-ая*)
init_stage:=0;
port_init:=FALSE;
END_IF
RETURN;
END_IF
IF init_stage>1 AND init_stage<4 THEN (* Ожидание настройки CSCS*)
tmr_rq_wait(in:=(init_stage=3),PT:=t#3s);
init_stage:=3;
sz:=SysComRead(com_num,ADR(rcvBUF),1024,0);
IF sz>0 THEN (*Что то приняли*)
FOR iter:=0 TO sz-1 DO
a_char:=ADR(rcvBuf[iter]);
rcvStr:=CONCAT(rcvStr,LEFT(a_char^,1) );
IF LEN(rcvStr)>250 THEN
rcvStr:=DELETE(rcvStr,1,1);
END_IF
END_FOR
END_IF
IF FIND(rcvStr,'OK')<>0 THEN
init_stage:=4;
(*Инициализация успешна*)
rcvstr:='';
SysComWrite(com_num,ADR(strTakeNewSMS),LEN(strTake NewSMS),0);
END_IF
IF tmr_rq_wait.Q THEN (*Недождались - переиниц-ая*)
init_stage:=0;
port_init:=FALSE;
END_IF
RETURN;
END_IF
IF init_stage>3 AND init_stage<6 THEN
tmr_rq_wait(in:=(init_stage=4),PT:=t#3s);
init_stage:=5;
sz:=SysComRead(com_num,ADR(rcvBUF),1024,0);
IF sz>0 THEN (*Что то приняли*)
FOR iter:=0 TO sz-1 DO
a_char:=ADR(rcvBuf[iter]);
rcvStr:=CONCAT(rcvStr,LEFT(a_char^,1) );
IF LEN(rcvStr)>250 THEN
rcvStr:=DELETE(rcvStr,1,1);
END_IF
END_FOR
END_IF
IF FIND(rcvStr,'OK')<>0 THEN
init_stage:=6;
(*Инициализация успешна*)
rcvstr:='';
END_IF
IF tmr_rq_wait.Q THEN (*Недождались - переиниц-ая*)
init_stage:=0;
port_init:=FALSE;
END_IF
RETURN;
END_IF
(*Взводим таймер если надо*)
tmr_snd_wait(IN:=LEN(send_SMS_text)>0 AND do_send_sms2,PT:=t#5s);
(*Если таймер сработал больше не ждем ответа от модема*)
IF tmr_snd_wait.Q THEN
do_send_sms2:=FALSE;
tmr_snd_wait(IN:=LEN(send_SMS_text)>0 AND do_send_sms2,PT:=t#5s);
rcvStr:='';
END_IF
(*Начинаем посылку*)
sended_OK:=FALSE;
(*Если нужно послать СМС*)
IF LEN(send_SMS_text)>0 AND NOT do_send_sms2 THEN
NUMBER_OUT:='';
FOR I:=1 TO 10 DO
IF (I MOD 2)<>0 THEN
NUMBER_OUT:=CONCAT(NUMBER_OUT,MID(phone_num,1,I+1) );
ELSIF (I MOD 2)=0 THEN
NUMBER_OUT:=CONCAT(NUMBER_OUT,MID(phone_num,1,I-1));
END_IF
END_FOR
NUMBER_OUT:=CONCAT(NUMBER_OUT, 'F');
NUMBER_OUT:=CONCAT(NUMBER_OUT, MID(phone_num,1,11));
PACKET:='0001000B91'; (*SCA =00 PDU=01 MR=00*)
PACKET:=CONCAT(PACKET,NUMBER_OUT);
IF use_unicode THEN
PACKET:=CONCAT(PACKET,'0008'); (*PID 00(обычн смс) = DCS=06(кодовая схема - полный UCS2)*)
IF LEN(send_sms_text)>69 THEN (*Обрезаем строку до 70*)
send_sms_text:=LEFT(send_sms_text,69);
END_IF
uc_sms_text:=CP1251_TO_UTF8oct(send_sms_text);
ELSE
(* 0001000B919762527348F500040E *)
PACKET:=CONCAT(PACKET,'0004'); (*PID 00(обычн смс) = DCS=04(кодовая схема - 8 битовое)*)
IF LEN(send_sms_text)>159 THEN (*Обрезаем строку до 255 символов*)
send_sms_text:=LEFT(send_sms_text,159);
END_IF
uc_sms_text:=CP1251_TO_Octets(send_sms_text);
END_IF
uc_sms_text:=CONCAT(uc_sms_text,'$1A');
IF use_unicode THEN
I:=INT_TO_BYTE(LEN(send_sms_text)*2);
ELSE
I:=INT_TO_BYTE(LEN(send_sms_text));
END_IF
PACKET:=CONCAT(PACKET,tetr2hex[SHR(I,4)]);
PACKET:=CONCAT(PACKET,tetr2hex[I AND 16#F]);
snd_str:=CONCAT('AT+CMGS=',INT_TO_STRING((LEN(PACK ET)/2)-1+I));
snd_str:=CONCAT(snd_str,'$R');
SysComWrite(com_num,ADR(snd_str),LEN(snd_str),0);
rcvStr:='';
(*Ждать ответа от модема*)
do_send_sms2:=TRUE;
END_IF
(*
(*Таймер ожидания получения*)
tmr_rcv_wait(IN:=do_rcv_sms2,PT:=t#5s);
IF tmr_rcv_wait.Q THEN
do_rcv_sms2:=FALSE;
SysComWrite(com_num,ADR(strSetDelivRep),LEN(strSet DelivRep),0);
tmr_rcv_wait(IN:=do_rcv_sms2,PT:=t#5s);
rcvStr:='';
END_IF
*)
(*Если нужно получить ответ от модема*)
IF rcvSMS AND NOT do_send_sms2 AND NOT do_rcv_sms2 THEN
rcvStr:='';
do_rcv_sms2:=TRUE;
END_IF
(*Получаем данные из порта*)
sz:=SysComRead(com_num,ADR(rcvBUF[0]),20,0);
(*Таймер получения ответа от модема -2 секунды*)
IF LEN(rcvStr)=0 THEN
tmr_rq_wait(IN:=FALSE,PT:=t#2s);
ELSE
tmr_rq_wait(IN:=TRUE,PT:=t#2s);
END_IF
IF sz<>0 THEN
FOR iter:=0 TO sz-1 DO
a_char:=ADR(rcvBuf[iter]);
rcvStr:=CONCAT(rcvStr,LEFT(a_char^,1) );
IF LEN(rcvStr)>250 THEN
rcvStr:=DELETE(rcvStr,1,1);
END_IF
END_FOR
IF do_send_sms2 THEN
(*При посылке СМС ожидаем готовности модема знак >*)
IF FIND(rcvStr,'>') <> 0 THEN
(*Шлем SMS*)
SysComWrite(com_num,ADR(PACKET),LEN(PACKET),0);
SysComWrite(com_num,ADR(uc_sms_text),LEN(uc_sms_te xt),0);
i:=16#1A;
SysComWrite(com_num,ADR(i),1,0);
do_send_sms2:=FALSE;
(*СМС Послано*)
sended_OK:=TRUE;
END_IF
END_IF
END_IF
(*Если прием СМС*)
IF do_rcv_sms2 AND tmr_rq_wait.q THEN
(*Если ждем эхо*)
IF FIND(rcvStr,strGetNewSMS) <> 0 THEN
rcvStr:=DELETE(rcvStr,FIND(rcvStr,strGetNewSMS) +LEN(strGetNewSMS)+1,1);
WHILE (LEFT(rcvStr,1)<>',') DO
rcvStr:=DELETE(rcvStr,1,1);
END_WHILE
rcvStr:=DELETE(rcvStr,1,1);
strSMS_num:=rcvStr;
rcvStr:=CONCAT(strGetNewMsg,rcvSTR);
SysComWrite(com_num,ADR(rcvSTR),LEN(rcvSTR),0);
rcvStr:='';
END_IF
(*Начато тел. номера из россии это +7 *)
IF FIND(rcvStr,'+CMGR: ')<>0 THEN
rcvStr:=DELETE(rcvStr,FIND(rcvStr,'$0A') ,1);
rcvStr:=DELETE(rcvStr,FIND(rcvStr,'$0A') ,1);
(*СМС ограничено переводами строк*)
DB(pBuf:=ADR(rcvStr),str_sender=>rcvedPhonNum,str_ time=>rcvedTm,str_message=>rcvedSMS);
rcvStr:=CONCAT(strGetDelMsg,strSMS_num);
SysComWrite(com_num,ADR(rcvSTR),LEN(rcvSTR),0);
rcvStr:='';
END_IF
rcvStr:='';
END_IF