Глобальные переменные
Код:VAR_GLOBAL CONSTANT SOCKET_INVALID :SysTypes.RTS_IEC_HANDLE :=-1; //ошибка открытия порта END_VARфункция SocketCreate:
Код:FUNCTION SocketCreate : POINTER TO BYTE VAR_INPUT in_port :UINT; //порт, с которым нужно установить соединенеие in_ip :ARRAY [0..3] OF BYTE; //IP адрес END_VAR VAR_OUTPUT END_VAR VAR_IN_OUT sock_adr :SOCKADDRESS; //структура, которая содержит всю необходимую информацию для адресации сокета END_VAR VAR openSocket :SysTypes.RTS_IEC_HANDLE; //дескриптор открытого соккета result :POINTER TO RTS_IEC_RESULT; //указатель на код ошибки системы исполнения (см CmpErrors.library) err_ok :UDINT :=16#0; ip_addr :SysSocket.UDINT_IN_BYTES; //ip адрес в формате SysSocket.lib END_VAR openSocket:=SysSockCreate(SOCKET_AF_INET, SOCKET_STREAM, SOCKET_IPPROTO_IP, result); //открываем соккет (параметры смотреть в библиотеке/GVL) IF result = err_ok AND openSocket <> SOCKET_INVALID THEN //если нет ошибок, то заполняем структуру SOCKADDRESS sock_adr.sin_family:=SOCKET_AF_INET; //назначение соккета ip_addr.s_b1:=in_ip[0]; //формируем ip-адрес ip_addr.s_b2:=in_ip[1]; ip_addr.s_b3:=in_ip[2]; ip_addr.s_b4:=in_ip[3]; sock_adr.sin_addr.S_un_b := ip_addr; sock_adr.sin_port:=SysSockHtons(in_port); //указываем порт IF SysSockConnect(openSocket, ADR(sock_adr), SIZEOF(sock_adr)) < 0 THEN //если соединение с сервером неуспешно SysSockClose(openSocket); //закрываем соккет openSocket:=SOCKET_INVALID; //присваиваем ошибку END_IF; END_IF; SocketCreate:=ADR(openSocket^); //выход функции
переменные программы:Код:PROGRAM ntp VAR start_bl_ntp :BOOL; //Запуск генератора импульсов bl_ntp :blink_rst; //Генератор импульсов для работы ntp start_ntp :BOOL; //Переменная, запускающая ntp-клиент на плк oldstart_ntp :BOOL; //Предыдущеее значение переменной start_ntp data_received :BOOL; //Переменная,означающая что данные получены handle_sock :SysTypes.RTS_IEC_HANDLE;; //Номер открытого сокета result :__XINT; //Размер полученных данных ip_address :ARRAY [0..3] OF BYTE := [132,163,4,103]; //IP адрес ntp-сервера (132.163.4.103) buff_in :ARRAY [0..60] OF BYTE; //Размер принимаемого буфера sock_adr :SOCKADDRESS; result_recv :POINTER TO RTS_IEC_RESULT; //указатель на код ошибки системы исполнения (см CmpErrors.library) str :STRING; //Полученная строка данных с сервера ntp_true :BOOL; //Полученные данные с сервера - адекватные t_ntp_man :TOF; //Время ручного получения данных с сервера ntp hh_ntp :INT; mm_ntp :INT; ss_ntp :INT; dd_ntp :INT; mh_ntp :INT; yy_ntp :INT; set_ntp :BOOL; END_VAR VAR CONSTANT buff_cln : ARRAY [0..60] OF BYTE :=[61(0)]; //Очистка буфера END_VAR
код программы:
Код:(*****Отдельная благодарность capsar`у за ntp-клиент*****) IF vis_bright_time.current_time>10800 AND vis_bright_time.current_time<10980 AND gprs_online THEN (*Если текущее время 03:00 выполняем 6 попыток опроса сервера и есть связь с интернетом, либо вручную с панели, при наличии интернета*) start_bl_ntp:=TRUE; ELSE start_bl_ntp:=FALSE; END_IF bl_ntp(in:=start_bl_ntp , t_on:= T#5S, t_off:= T#25S, out=> ); //генератор импусьсов, который в течении работы таймера отправляет на панель данные t_ntp_man(IN:= ntp_man, PT:= T#5S, Q=> , ET=> ); //время опроса ntp-сервера при ручном опросе IF (bl_ntp.out OR t_ntp_man.Q) AND ntp_yes THEN //если подошло время обновления или синхр. вручную при условии разрешения синхронизации start_ntp:=TRUE; //запускаем ntp-клиент IF start_ntp AND start_ntp<>oldstart_ntp THEN //сравнение с передыдущим значением переменной handle_sock := SocketCreate(13,ip_address, sock_adr); //работа через соккет и получение данных от сервера data_received:=FALSE; buff_in:=buff_cln; ELSIF oldstart_ntp AND start_ntp<>oldstart_ntp THEN IF handle_sock<>SOCKET_INVALID THEN SysSockClose(handle_sock); handle_sock := SOCKET_INVALID; END_IF ELSIF start_ntp THEN IF NOT data_received THEN result:=SysSockRecv(handle_sock, ADR(buff_in[0]), SIZEOF(buff_in),0,result_recv); IF result > 0 THEN //если результат > 0, т.е. положителен*) str:=bytePackStr(ADR(buff_in[0]), __XINT_TO_DINT (result)); //формируется строка данных из буфера*) data_received:=TRUE; //формирование строки завершено*) ntp_true:=INT_TO_BOOL (FIND(str,'UTC')); //проверка,что строка не состоит из неопределенных символов (время от времени бывает) IF ntp_true THEN //соответственно, если данные адекватные - обрабатываем их hh_ntp:=STRING_TO_INT (MID(str,2,17))+gmt; //получаем значение часа - 18-19 символы и приводим к часовому поясу mm_ntp:=STRING_TO_INT (MID(str,2,20)); //См. hh_ntp ss_ntp:=STRING_TO_INT (MID(str,2,23)); //См. hh_ntp yy_ntp:=STRING_TO_INT (MID(str,2,8)); //См. hh_ntp mh_ntp:=STRING_TO_INT (MID(str,2,11)); //См. hh_ntp dd_ntp:=STRING_TO_INT (MID(str,2,14)); //См. hh_ntp set_ntp:=TRUE; //фронт для установки полученного времени в плк END_IF END_IF END_IF END_IF ELSE start_ntp:=FALSE; ntp_true:=FALSE; set_ntp:=FALSE; END_IF oldstart_ntp:=start_ntp; (*Присваиваем промежуточную переменную*)