Страница 165 из 167 ПерваяПервая ... 65115155163164165166167 ПоследняяПоследняя
Показано с 1,641 по 1,650 из 1668

Тема: CODESYS V3.5. Настройка обмена с другими устройствами (Modbus, ОВЕН, OPC и др.)

  1. #1641

    По умолчанию

    Цитата Сообщение от Iliaaer Посмотреть сообщение
    Подскажите, возможно ли сделать свое сетевое оборудование в CodeSys, чтобы как и на фотографии, было свое оборудование?
    Вложение 86946
    Как на скрине нельзя, но по ТСР вы можете опросить любой сторонний слейв, главное иметь таблицу адресов регистров.

  2. #1642

    По умолчанию

    Добрый день, столкнулся с неясностью в работе блока OCL.UNM_SerialRequest.
    Задача - установить связь с платой с микроконтроллером STM32 по RS-485 с помощью собственного протокола обмена. Нужно передавать данные с командой на плату (пакет из 17 байт), получать в ответ пакет с информацией о статусе платы (тоже 17 байт) и отслеживать, есть или нет в данный момент связь с платой. Написал следующую программу (под спойлером). Интервал для её задачи – 20 мс, время таймаута опроса – 100 мс.
    Скрытый текст:
    ПЕРЕМЕННЫЕ
    PROGRAM PSM_PLC_Communication
    VAR
    bPointerMemoryError: BOOL; //TRUE, если есть ошибка выделения памяти под указатели буфеоров команлы и статуса
    fb_COM_Control: OCL.COM_Control;
    fb_Serial_Request: OCL.UNM_SerialRequest;
    bNeedReset: BOOL; // флаг, активируется при окончании отсылки пакета и появлении необходимости очистки буфера
    abyCommand: ARRAY [0..16] OF BYTE; //буфер команды плате
    abyCommand_for_CRC: ARRAY [0..11] OF BYTE; //массив для расчета CRC
    abyStatus: ARRAY [0..16] OF BYTE; //буфер ответа платы
    dwCRC_Command: DWORD; //переменная для расчёта CRC
    wCRC_command: WORD; //младший байт предыдущей переменной
    byCRC_LSB: BYTE; //младший байт CRC
    byCRC_MSB: BYTE; //старший байт CRC
    i: INT; //номер опрашиваемого устройства
    abyID_LSB: ARRAY [1..PSM.iPS_county] OF BYTE; //массив младших байт ID опрашиваемого устройства
    abyID_MSB: ARRAY [1..PSM.iPS_county] OF BYTE; //массив старших байт ID опрашиваемого устройства
    END_VAR
    VAR CONSTANT

    //параметры обмена
    udiBaudrate: UDINT:=115200; //скорость обмена
    udiComPortNumber:UDINT:=1; //номер COM порта
    udiByteSize:UDINT:=8; //биты информации

    tTimeout: TIME:= T#100MS; //таймаут опроса
    usiRetry: USINT:=3;//число попыток
    END_VAR

    КОД ПРОГРАММЫ
    //открытие COM порта с заданными параметрами (номер порта 1, скорость 9600, биты информации 8, контроля четности нет, стоповые биты 1)
    fb_COM_Control(
    xEnable:=TRUE,
    udiComPort:=udiComPortNumber,
    udiBaudrate:=udiBaudrate,
    udiByteSize:=udiByteSize,
    eParity:=2,
    eStopBit:=0
    );
    //код для очистки буферов после работы ФБ SerialRequest
    IF bNeedReset THEN
    MEM.MemFill(ADR(abyCommand), SIZEOF(abyCommand), 0);
    MEM.MemFill(ADR(abyStatus), SIZEOF(abyStatus), 0);
    bNeedReset:=FALSE;
    END_IF
    // *далее код, заполняющий буфер данными на отправку (17 байт) и никак не задействующий ФБ SerialRequest
    //проверка корректности выделения памяти указателей.

    IF fb_Serial_Request.pRequest <> CAA.Constants.gc_pNULL AND fb_Serial_Request.szRequest > CAA.Constants.gc_szZERO AND fb_Serial_Request.pResponse <> CAA.Constants.gc_pNULL AND fb_Serial_Request.szResponse > CAA.Constants.gc_szZERO THEN
    bPointerMemoryError:= FALSE;
    ELSE
    bPointerMemoryError:= TRUE;
    END_IF
    // вызов ФБ Serial Request, отсылание запроса
    fb_Serial_Request (
    xExecute:=TRUE AND NOT bPointerMemoryError AND NOT bNeedReset ,
    tTimeout:=tTimeout,
    usiRetry:=usiRetry,
    hCom:=fb_COM_Control.hCom,
    pRequest:=ADR(abyCommand),
    szRequest:=17, pResponse:=ADR(abyStatus),
    szResponse:=17,
    szExpectedSIze:=17,
    wStopChar:=16#FF
    );
    IF fb_Serial_Request.xDone THEN
    //разбор ответа платы, если адрес совпадает с ожидаемым
    IF abyStatus[4]=INT_TO_BYTE((1+16#200) AND 16#FF) AND abyStatus[5]=INT_TO_BYTE (SHR(1+16#200,8) AND 16#FF) THEN
    PSM.ar_PS_statuses[1].bMagFanError:= abyStatus[6].1; //бит ошибки вентилятора магнетрона (6 байт 1-й бит)
    PSM.ar_PS_statuses[1].bPSFanError:= abyStatus[6].2; //бит ошибки вентилятора БП (6-й байт 2-й бит)
    PSM.ar_PS_statuses[1].bPSLocked:= abyStatus[6].5; //бит блокировки БП (6 байт 5-й бит)
    PSM.ar_PS_statuses[1].bIllegalTurnOn:= abyStatus[6].6; //бит несанкционированного включения магнетрона (6 байт 6-й бит)
    PSM.ar_PS_statuses[1].bMagNotTurnedOn:= abyStatus[6].7; //TRUE, если магнетрон не смог запуститься (6-й байт 7-й бит)

    PSM.ar_PS_statuses[1].bConnect:= abyStatus[7].5; // TRUE, если связь установлена, 7 байт 5-й бит

    PSM.ar_PS_statuses[1].bTurnOnCommandReceived:= abyStatus[13].2; // TRUE, если команда на включение получена БП, 13 байт 2-й бит
    PSM.ar_PS_statuses[1].bMagNotTurnedOn:= abyStatus[13].3; //TRUE, если есть ток магнетрона, 13 байт 3-й бит
    PSM.ar_PS_statuses[1].rMagnetronCurrent:= OCL.WORD2_TO_REAL (BYTE_TO_WORD (abyStatus[3]),BYTE_TO_WORD (abyStatus[4]), FALSE);// ток магнетрона. TODO проверить работу, порядок операндов.
    END_IF
    bNeedReset:=TRUE; // флаг необходимости очистки буферов
    fb_Serial_Request(xExecute:=FALSE);
    ELSIF fb_Serial_Request.xError THEN
    bNeedReset:=TRUE; // флаг необходимости очистки буферов
    fb_Serial_Request(xExecute:=FALSE);
    END_IF


    При подключении ПЛК к плате связь устанавливается, данные передаются и вычитываются. Непонятки начинаются, когда я физически отключаю плату от ПЛК. Я ожидаю, что ФБ SerialRequest с этого момента начнет на выходе xError выдавать TRUE, а на выходе eError – TIME_OUT. В реальности xError и xDone остаются в нуле, блок остается в статусе xBusy (иногда xBusy на долю секунды уходит в FALSE, затем возвращается), на выходе eError – NO_ERROR.
    В буфере, куда помещаются читаемые данные – нули, буфер этот очищается по переменной bNeedReset, которая, по идее, взводится только при завершении работы ФБ с результатом xDone или xError. Если запустить программу, не подключая ПЛК к плате – результат такой же (в буфере нули, ошибки на выходе ФБ нет).
    Что я упускаю и как можно добиться индикации ошибки при пропаже соединения?

  3. #1643
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    13,709

    По умолчанию

    Что я упускаю
    Код:
    ELSIF fb_Serial_Request.xError THEN
       bNeedReset:=TRUE; // флаг необходимости очистки буферов
       fb_Serial_Request(xExecute:=FALSE);
    END_IF
    В момент вызова fb_Serial_Request(xExecute:=FALSE); выходы "сбрасываются".
    Поэтому глазами вы не видите xError и eError - к концу цикла, в котором они детектированы, они уже сброшены.

    Вы можете добавить внутрь ELSIF счетчик ошибок для наглядности.
    Или запускать таймер от NOT(fb_Serial_Request.xDone) - в стиле "успешных транзакций не было уже 5 секунд, пора бы зажечь аварийную лампу".

  4. #1644

    По умолчанию

    Цитата Сообщение от Вячеслав1605 Посмотреть сообщение
    Добрый день, столкнулся с неясностью в работе блока OCL.UNM_SerialRequest.
    Как Вы проверяете, что на выходе eError нет ошибки?
    Добавьте по флагу xError запись выхода fb_Serial_Request.eError в промежуточную переменную. Что записывается?


    Скрытый текст:
    VAR
    eReqError : OCL.ERROR;
    END_VAR

    ...
    ELSIF fb_Serial_Request THEN
    eReqError := fb_Serial_Request.eError;
    bNeedReset:=TRUE;
    fb_Serial_Request(xExecute:=FALSE);
    END_IF
    Инженер по продукту ПЛК

    e-mail: a.pineko-skvortsov@owen.ru

  5. #1645

    По умолчанию

    Цитата Сообщение от Евгений Кислов Посмотреть сообщение
    Код:
    ELSIF fb_Serial_Request.xError THEN
       bNeedReset:=TRUE; // флаг необходимости очистки буферов
       fb_Serial_Request(xExecute:=FALSE);
    END_IF
    В момент вызова fb_Serial_Request(xExecute:=FALSE); выходы "сбрасываются".
    Поэтому глазами вы не видите xError и eError - к концу цикла, в котором они детектированы, они уже сброшены.

    Вы можете добавить внутрь ELSIF счетчик ошибок для наглядности.
    Или запускать таймер от NOT(fb_Serial_Request.xDone) - в стиле "успешных транзакций не было уже 5 секунд, пора бы зажечь аварийную лампу".
    Цитата Сообщение от Александр Пинэко-Скворцов Посмотреть сообщение
    Как Вы проверяете, что на выходе eError нет ошибки?
    Добавьте по флагу xError запись выхода fb_Serial_Request.eError в промежуточную переменную. Что записывается?


    Скрытый текст:
    VAR
    eReqError : OCL.ERROR;
    END_VAR

    ...
    ELSIF fb_Serial_Request THEN
    eReqError := fb_Serial_Request.eError;
    bNeedReset:=TRUE;
    fb_Serial_Request(xExecute:=FALSE);
    END_IF
    Спасибо за консультацию, именно это и происходило. Добавил запись события fb_Serial_Request.xError = TRUE в промежуточную переменную bCommunicationError, а также счётчик таких событий. При отключении провода от платы эта переменная уходит в TRUE, счетчик растёт. При подключении провода обратно - всё восстанавливается. Привязал переменную-индикатор связи дополнительно к этой промежуточной переменной.
    Заодно выяснил, что при таймауте в 100 мс и интервале задачи 20 мс ошибки появляются и при подключенной линии (хотя буфер вычитывается), а при таймауте в 101мс ошибки пропадают. Похоже, связано с интервалом задачи, при его уменьшении до 15 мс при таймауте 90 мс все работает стабильно.

  6. #1646

    По умолчанию

    Добрый день
    Подскажите как из кода работающей программы поменять параметры RS485 на плк 210
    метод описанный в документе "Настройка обмена по протоколу Modbus" не срабатывает

    Modbus_Master_COM_Port.xStop:=True;
    Modbus_Master_COM_Port.UpdateComParameters(115000, 1,0,8,2,true,5);
    Modbus_Master_COM_Port.xStop:=False;

  7. #1647
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    13,709

    По умолчанию

    Цитата Сообщение от Andrunchic Посмотреть сообщение
    Добрый день
    Подскажите как из кода работающей программы поменять параметры RS485 на плк 210
    метод описанный в документе "Настройка обмена по протоколу Modbus" не срабатывает

    Modbus_Master_COM_Port.xStop:=True;
    Modbus_Master_COM_Port.UpdateComParameters(115000, 1,0,8,2,true,5);
    Modbus_Master_COM_Port.xStop:=False;
    Добрый день.
    Посмотрите это видео:
    https://oscat.ru/wp-content/Video/Co...geSettings.mp4

  8. #1648

    По умолчанию

    Цитата Сообщение от Andrunchic Посмотреть сообщение
    Добрый день
    Подскажите как из кода работающей программы поменять параметры RS485 на плк 210
    метод описанный в документе "Настройка обмена по протоколу Modbus" не срабатывает

    Modbus_Master_COM_Port.xStop:=True;
    Modbus_Master_COM_Port.UpdateComParameters(115000, 1,0,8,2,true,5);
    Modbus_Master_COM_Port.xStop:=False;
    Если это у вас в коде в послед стоит, то это не рабочий код. Т.к. xStop у вас для модбаса всегда false.

  9. #1649

    По умолчанию

    Цитата Сообщение от Евгений Кислов Посмотреть сообщение
    Добрый день.
    Посмотрите это видео:
    https://oscat.ru/wp-content/Video/Co...geSettings.mp4
    написал код как в Видео у меня ПЛК210 первый RS485 настроен на мое устройство и работает.
    при подаче команды INIT запускающей Modbus_Master_COM_Port.UpdateComParameters с этими же параметрами контроллер пишет
    в состоянии 'не запущено' и SLAVE становится серым

    IF (Init) THEN
    Modbus_Master_COM_Port.Enable:=FALSE;
    Ton_1(IN:=TRUE, PT:=T#1S);
    IF Ton_1.Q THEN
    Modbus_Master_COM_Port.UpdateComParameters
    (
    udiBaudrate := 115200,
    usiMedium := 1,
    usiParity := 0,
    usiDataBits := 8,
    usiStopBits := 2,
    xPolarization:= FALSE,
    COMPORT := 5
    );
    Encoder_ob.SlaveAddress:=5;
    Modbus_Master_COM_Port.Enable:=TRUE;
    Ton_1(IN:=FALSE);
    Init:=FALSE;
    END_IF
    END_IF

  10. #1650
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    13,709

    По умолчанию

    Повторил проблему у себя.
    Она связана с

    Код:
    usiStopBits := 2;
    По каким-то причинам (вероятно, из-за бага) драйвер не воспринимает значение 2 и формирует ошибку.
    Если установить 1 - работает корректно.
    Я бы рекомендовал проверить, имеет ли значение эта настройка на стороне прошивки вашего slave-устройства - возможно, подойдет и 1 стоп-бит.
    Если нужно принципиально выставить именно 2 стоп-бита, то потребуется организовать обмен через библиотеку OwenCommunication.

Страница 165 из 167 ПерваяПервая ... 65115155163164165166167 ПоследняяПоследняя

Похожие темы

  1. Настройка ПР200, управление 3-мя устройствами через RS-485
    от Orbes в разделе Среда программирования OWEN Logic
    Ответов: 20
    Последнее сообщение: 15.05.2017, 16:45
  2. СП3ХХ Пример настройка обмена с ПЛК на CODESYS 2.3
    от Denis_Kay в разделе Панели оператора (HMI)
    Ответов: 6
    Последнее сообщение: 02.03.2017, 15:12
  3. Ответов: 43
    Последнее сообщение: 13.04.2015, 14:05
  4. Универсальная функция для обмена с устройствами OwenIO и всеми любимый LabView.
    от Алексей Крагель в разделе Помощь Разработчикам
    Ответов: 0
    Последнее сообщение: 30.05.2014, 13:38

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •