Показано с 1 по 2 из 2

Тема: Проблемы с отправкой посылки по RS-232 от контроллера СПК210-07-CS

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    По умолчанию Проблемы с отправкой посылки по RS-232 от контроллера СПК210-07-CS

    Добрый день, еще раз.

    Пытаюсь организовать обмен по RS-232 между платой и контроллером СПК210-07-CS, версия прошивки которой 3.6.0318.1402. Для обмена использую библиотеку SysCom. С приемом разобрался: мне в контроллер поступает кольцевой буфер myrs232, из которого извлекается 55-байтная посылка packet с заголовком (первые 3 байта), контрольной суммой (2 последних байта) и остальными значениями. Отправляю посылку в 7 байт packet1 тоже с заголовком (первые 3 байта) и контрольной суммой (последние 2 байта). Пока при отправке пытаюсь изменить значение TempZad (значение 4-го байта packet1 (номер настройки) = 1) с 4 на 5 (то есть, 5-ый байт в посылке отправки задан 50 и через какое-то время получаю 18-ый байт тоже равный 50). Контрольную сумму программа точно считает правильно. Но проверка осциллографом показала, что отправляются не 7 байт, как задано в packet1, а гораздо больше. Даже больше, чем в приемной посылке packet. И поэтому, значение TempZad не меняется при отладке. Хотя метод Write при той же отладке выводит значение, равное 7. Как исправить эту реализацию, чтобы отправленная посылка действительно оказалась 7 байт?

    Проект высылаю в виде файла и в текстовом режиме. Заранее надеюсь на оперативные ответы и решения.
    FUNCTION_BLOCK Com
    VAR_INPUT
    END_VAR
    VAR_OUTPUT
    END_VAR
    VAR
    hCom : POINTER TO BYTE;
    rCom : UDINT;
    ComSettings : SysCom.COM_Settings;
    END_VAR

    METHOD CRC16Modbus : WORD
    VAR_INPUT
    DataArray : ARRAY[*] OF BYTE;
    Length : UDINT;
    END_VAR
    VAR
    crc : WORD := 16#FFFF;
    i, j : UDINT;
    dataByte : BYTE;
    END_VAR

    FOR i := 0 TO Length - 1 DO
    dataByte := DataArray[i];
    crc := crc XOR dataByte;

    FOR j := 0 TO 7 DO
    IF (crc AND 16#0001) <> 0 THEN
    crc := SHR(crc, 1) XOR 16#A001;
    ELSE
    crc := SHR(crc, 1);
    END_IF;
    END_FOR;
    END_FOR;

    CRC16Modbus := crc;

    METHOD Read : BOOL;
    VAR_INPUT
    END_VAR
    VAR
    Size : UDINT;
    END_VAR

    // Reads a number bytes from the specifed device to the receive buffer
    Size := SIZEOF(myrs232 );
    Read_Size:=SysComRead(hCom, ADR(myrs232) , Size, SYS_INFINITE, ADR(rCom));

    IF (rCom <>0) THEN
    Read:=FALSE;
    Read_Size:=0;
    ELSE
    Read := TRUE;
    END_IF
    IF Read_Size > 0 THEN
    SysComWrite(hCom:= hCom, pbyBuffer:= ADR(myrs232), ulSize:= size, SYS_INFINITE, pResult:= ADR(rCom));
    END_IF
    SysComPurge(hCom);

    METHOD ExtractAndVerifyPacket : BOOL
    VAR
    i,j : UDINT;
    calculatedCRC : WORD;
    receivedCRC : WORD;
    packet : ARRAY [0..54] OF BYTE;
    END_VAR

    FOR i:=0 TO 54 DO
    IF (myrs232[i]=16#55) AND
    (myrs232[i+1]=16#AA) AND
    (myrs232[i+2]=16#32) THEN
    FOR j:=0 TO 54 DO
    packet[j]:=myrs232[j+i];
    receivedCRC := SHL(packet[54],8) OR packet[53];
    END_FOR;
    END_IF;
    END_FOR;
    calculatedCRC := CRC16Modbus(packet, 53);
    IF calculatedCRC = receivedCRC THEN
    ExtractAndVerifyPacket := TRUE;
    ELSE
    ExtractAndVerifyPacket := FALSE;
    END_IF
    IF ExtractAndVerifyPacket := TRUE THEN
    packet[0]:=16#55;
    packet[1]:=16#AA;
    packet[2]:=16#32;
    TEMP01_:=SHR(packet[3],8) OR packet[4];
    TEMP02_:=SHR(packet[5],8) OR packet[6];
    TEMP03_:=SHR(packet[7],8) OR packet[8];
    TEMP04_:=SHR(packet[9],8) OR packet[10];
    PZAD := packet[11];
    KONTRIN := packet[12];
    KONTROUT := packet[13];
    ERRORS1 := packet[14];
    ERRORS2 := packet[15];
    ERRORS3 := packet[16];
    TempZad := packet[17] / 10.0;
    Pruch := packet[18];
    Pogr := packet[19];
    temp01 := packet[20] / 10.0;
    ktemp01 := packet[21] / 128.0;
    temp02 := packet[22] / 10.0;
    ktemp02 := packet[23] / 128.0;
    temp03 := packet[24] / 10.0;
    ktemp03 := packet[25] / 128.0;
    temp04 := packet[26] / 10.0;
    ktemp04 := packet[27] / 128.0;
    kdif := packet[28] / 10.0;
    kpr := packet[29] / 10.0;
    kint := packet[30] / 10.0;
    deltaTi := packet[31] / 10.0;
    BUS1I1 := SHR(packet[32],8) OR packet[33];
    BUS1I2 := SHR(packet[34],8) OR packet[35];
    BUS1SOST1 := packet[36];
    BUS1SOST2 := packet[37];
    BUS1ERROR := packet[38];
    BUS2I1 := SHR(packet[39],8) OR packet[40];
    BUS2I2 := SHR(packet[41],8) OR packet[42];
    BUS2SOST1 := packet[43];
    BUS2SOST2 := packet[44];
    BUS2ERROR := packet[45];
    BUS3I1 := SHR(packet[46],8) OR packet[47];
    BUS3I2 := SHR(packet[48],8) OR packet[49];
    BUS3SOST1 := packet[50];
    BUS3SOST2 := packet[51];
    BUS3ERROR := packet[52];
    END_IF

    METHOD Write : BOOL
    VAR
    size : UDINT;
    calculatedCRC1 : WORD;
    END_VAR

    packet1[0]:=16#55;
    packet1[1]:=16#AA;
    packet1[2]:=16#02;
    packet1[3]:=16#01;
    packet1[4]:=16#32;
    calculatedCRC1 := CRC16Modbus(packet1, 5);
    packet1[5] := WORD_TO_BYTE(calculatedCRC1);
    packet1[6] := WORD_TO_BYTE(SHR(calculatedCRC1, 8));

    Size:=SIZEOF(packet1);
    Write_Size:=SysComWrite(hCom, ADR(packet1),Size, SYS_INFINITE, ADR(rCom));
    IF (rCom<>0) THEN
    Write:=FALSE;
    Write_Size:=0;
    ELSE
    Write:=TRUE;
    END_IF

    FUNCTION IsValidDate: BOOL;
    VAR_INPUT
    Year: UINT;
    Month: USINT;
    Day: USINT;
    END_VAR
    VAR
    DaysInMonth: ARRAY[1..12] OF INT := [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    MaxDay: INT;
    END_VAR

    // Корректировка для високосного года
    IF (Year MOD 4 = 0 AND Year MOD 100 <> 0) OR (Year MOD 400 = 0) THEN
    DaysInMonth[2] := 29;
    END_IF;

    MaxDay := DaysInMonth[Month];
    IsValidDate := (Day >= 1) AND (Day <= MaxDay);

    FUNCTION_BLOCK SetRTC
    VAR_INPUT
    Execute: BOOL;
    END_VAR
    VAR_OUTPUT
    WriteResult: BOOL;
    Status: STRING(50);
    END_VAR
    VAR
    // Локальные копии для проверки
    LocalYear: UINT;
    LocalMonth: USINT;
    LocalDay: USINT;
    LocalHour: USINT;
    LocalMinute: USINT;
    LocalSecond: USINT;
    // Вспомогательные переменные
    DateTimeStr: STRING(20);
    TempDateTime: DATE_AND_TIME;
    END_VAR

    WriteResult := FALSE;
    Status := 'Ожидание';

    IF Execute THEN
    // Копируем значения из глобальных рабочих переменных
    LocalYear := g_RTC_Year;
    LocalMonth := g_RTC_Month;
    LocalDay := g_RTC_Day;
    LocalHour := g_RTC_Hour;
    LocalMinute := g_RTC_Minute;
    LocalSecond := g_RTC_Second;

    // Проверка корректности данных
    IF (LocalYear >= 2000) AND (LocalYear <= 2099) AND
    (LocalMonth >= 1) AND (LocalMonth <= 12) AND
    IsValidDate(LocalYear, LocalMonth, LocalDay) AND
    (LocalHour >= 0) AND (LocalHour <= 23) AND
    (LocalMinute >= 0) AND (LocalMinute <= 59) AND
    (LocalSecond >= 0) AND (LocalSecond <= 59) THEN

    // Формируем строку в формате 'YYYY-MM-DD-HH:MM:SS'
    // Формируем строку в формате 'YYYY-MM-DD-HH:MM:SS'
    DateTimeStr := UINT_TO_STRING(LocalYear);
    DateTimeStr := CONCAT(DateTimeStr, '.');
    DateTimeStr := CONCAT(DateTimeStr, INT_TO_STRING(LocalMonth));
    DateTimeStr := CONCAT(DateTimeStr, '.');
    DateTimeStr := CONCAT(DateTimeStr, INT_TO_STRING(LocalDay));
    DateTimeStr := CONCAT(DateTimeStr, '');
    DateTimeStr := CONCAT(DateTimeStr, INT_TO_STRING(LocalHour));
    DateTimeStr := CONCAT(DateTimeStr, ':');
    DateTimeStr := CONCAT(DateTimeStr, INT_TO_STRING(LocalMinute));
    DateTimeStr := CONCAT(DateTimeStr, ':');
    DateTimeStr := CONCAT(DateTimeStr, INT_TO_STRING(LocalSecond));

    // Преобразуем строку в DATE_AND_TIME
    TempDateTime := STRING_TO_DT(DateTimeStr);
    g_RTC_DateTime := TempDateTime;

    // Активируем команду установки времени
    g_SetSettingsDT := TRUE;

    WriteResult := TRUE;
    Status := 'Время успешно обновлено';
    ELSE
    WriteResult := FALSE;
    Status := 'Ошибка: некорректные данные времени';
    END_IF;
    ELSE
    Status := 'Ожидание команды';
    END_IF;

    PROGRAM vis
    VAR
    xSound: BOOL;
    xSoundState: BOOL;
    xFrequency:UINT;
    TON1: TON;
    BLINK1: BLINK;
    END_VAR

    CASE nom_vis OF
    1:VisuElems.CurrentVisu :='Visualization';
    11:VisuElems.CurrentVisu :='Visualization_1_1';
    2:VisuElems.CurrentVisu :='Visualization_2';
    3:VisuElems.CurrentVisu :='Visualization_3';
    4:VisuElems.CurrentVisu :='Visualization_4';
    END_CASE

    IF nastroi AND NOT nastroiold THEN
    nom_vis:=3;
    ELSIF NOT nastroi AND nastroiold THEN
    nom_vis:=1;
    END_IF
    nastroiold:=nastroi;
    IF nom_vis=1 THEN
    IF KONTRIN.2 THEN
    regimrabot:="Настройка";
    ELSIF KONTRIN.3 THEN
    regimrabot:="Автоматический";
    ELSIF KONTRIN.4 THEN
    regimrabot:="Местный ручной";
    ELSIF KONTRIN.5 THEN
    regimrabot:="Дистанционный";
    ELSE
    regimrabot:="Не определен";
    END_IF
    (*BLINK1(ENABLE:=KONTROUT.0 AND NOT TON1.Q , TIMELOW:=T#500MS, TIMEHIGH:=T#500MS );
    TON1(IN:=KONTROUT.0, PT:=T#10S );
    IF KONTROUT.0 THEN
    xSoundState:=TRUE;
    xFrequency:=2000;
    xSound:=BLINK1.OUT AND NOT TON1.Q;
    ELSE
    xSound:=FALSE;
    xSoundState:=FALSE;
    END_IF*)
    IF (BUS1SOST1.7) AND (BUS1SOST2.7) THEN
    regimrabotBUS1:="дистанционное";
    ELSE
    regimrabotBUS1:="местное";
    END_IF
    IF (BUS2SOST1.7) AND (BUS2SOST2.7) THEN
    regimrabotBUS2:="дистанционное";
    ELSE
    regimrabotBUS2:="местное";
    END_IF
    IF (BUS3SOST1.7) AND (BUS3SOST2.7) THEN
    regimrabotBUS3:="дистанционное";
    ELSE
    regimrabotBUS3:="местное";
    END_IF
    END_IF;

    PROGRAM PLC_PRG
    VAR
    SetRTC_Instance: SetRTC; // Экземпляр программы настройки времени
    Timer_1s: TON; // Таймер для периодического чтения времени
    ReadRTC: BOOL := TRUE; // Флаг чтения времени
    END_VAR

    // Вызов FUNCTION_BLOCK для записи времени
    SetRTC_Instance(Execute := g_RTC_Update);

    // Копируем статус операции
    g_RTC_Status := SetRTC_Instance.Status;

    // Сбрасываем флаг после обработки
    IF g_RTC_Update AND SetRTC_Instance.WriteResult THEN
    g_RTC_Update := FALSE;
    END_IF;

    // Периодическое чтение текущего времени (каждую секунду)
    Timer_1s(IN := NOT Timer_1s.Q, PT := T#1S);
    IF Timer_1s.Q AND ReadRTC THEN
    Rs232IN:=TRUE;
    fbCom.Write();
    // Чтение из канала DATE_AND_TIME OwenRTC
    g_ReadDateTime := g_RTC_DateTime;

    // Преобразуем DATE_AND_TIME в строку
    DateTimeStr := DT_TO_STRING(g_ReadDateTime);

    // Разбор строки: формат 'YYYY-MM-DD-HH:MM:SS'
    // Год: первые 4 символа
    g_RTC_Year := STRING_TO_UINT(MID(DateTimeStr, 1, 4));

    // Месяц: символы 6–7
    g_RTC_Month := STRING_TO_USINT(MID(DateTimeStr, 6, 2));

    // День: символы 9–10
    g_RTC_Day := STRING_TO_USINT(MID(DateTimeStr, 9, 2));

    // Час: символы 12–13
    g_RTC_Hour := STRING_TO_USINT(MID(DateTimeStr, 12, 2));

    // Минуты: символы 15–16
    g_RTC_Minute := STRING_TO_USINT(MID(DateTimeStr, 15, 2));

    // Секунды: символы 18–19
    g_RTC_Second := STRING_TO_USINT(MID(DateTimeStr, 18, 2));
    END_IF;
    IF Rs232 THEN
    fbCom.Init(); // Initialize COM 4
    Rs232 := FALSE;

    ELSIF Rs232IN THEN //rsbuffer
    rsOk:=FALSE;
    rsOk:=fbCom.Write();
    rsOk:=FALSE;
    rsOk:=fbCom.Read();
    Rs232IN:=FALSE;
    IF rsOk THEN
    rsOk := fbCom.ExtractAndVerifyPacket();
    END_IF;

    Rs232IN := FALSE;
    END_IF
    vis();
    Вложения Вложения

  2. #2

    По умолчанию

    Зачем в методе Read используется функция Write? А вообще, нужно смотреть состав посылки, сколько байт и их значение. Потом разбираться, кто это шлет

Похожие темы

  1. Проблемы железа СПК210 (и не только)
    от papikrus в разделе СПК210, СПК1xx [М01]
    Ответов: 2
    Последнее сообщение: 30.10.2025, 15:08
  2. Проблема с отправкой по UDP
    от PaphozZ в разделе ПЛК2хх
    Ответов: 3
    Последнее сообщение: 04.08.2023, 15:41
  3. Решение проблемы с загрузкой контроллера
    от Мастеренко Иван в разделе ПЛК2хх
    Ответов: 0
    Последнее сообщение: 22.07.2020, 13:46
  4. Проблемы связи СПК210 через WiFi
    от EugeneS в разделе СПК2xx (архив)
    Ответов: 29
    Последнее сообщение: 30.01.2014, 16:12
  5. Проблемы после замены контроллера
    от mike_if в разделе ПЛК1хх
    Ответов: 24
    Последнее сообщение: 01.06.2011, 14:39

Метки этой темы

Ваши права

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