PDA

Просмотр полной версии : Програмный код ПЛК63 + ПЧВ1



Brandon_heat_dre
05.11.2018, 15:06
Всем доброго дня, всю голову изломал как законектить ПЛК63 и ПЧВ1 по RS-485 протокол modbus если кому не сложно , можете поделиться проектом хотя бы на чтение слова состояния, буду очень признателен, спасибо.

_Mikhail
05.11.2018, 15:16
Для чего ломать голову? Вся информация
https://www.owen.ru/product/preobrazovatel_chastoti_oven_pchv1_i_pchv2

Brandon_heat_dre
05.11.2018, 15:33
IF COM_SERVICE1.ready=FALSE THEN
com_num1:=0;
Settings1.Port:=com_num1;
Settings1.dwBaudRate:=9600;
Settings1.byParity:=0;
Settings1.dwTimeout:=10;
Settings1.byStopBits:=0;
Settings1.dwBufferSize:=0;
Settings1.dwScan:=100;
COM_SERVICE1 (Enable:=TRUE, Settings:=Settings1, Task:=OPEN_TSK);
com_ready1:=FALSE;
COM_SERVICE1.Opened;
ELSE
COM_SERVICE1.Enable:=FALSE;
com_ready1:=TRUE;
END_IF


IF com_ready1=TRUE THEN
w1(
Enable:=TRUE,
Mode:= MB_RTU,
DevAddr:=1,
RegAddr:=16#C359,
Value:=10000,
ComHandle:=0,
TimeOut:=T#10ms,
);

compl:=w1.Complete;
err:=w1.Exception;

END_IF

Brandon_heat_dre
05.11.2018, 15:36
39638

собственно говоря ошибка 254 , аппаратная ошибка плк, пытаюсь задать частоту через регистра задания по интерфейсу RS-485

ASo
05.11.2018, 17:02
C сокращениями

PROGRAM ExModbus
VAR
SendModbus1: MB_RD_COILS;
SendModbus2: MB_WR_SNG_REG;
SendModbus3: MB_WR_SNG_COIL;
SendModbus4: MB_RD_HOLD_REGS;
SendModbus5: MB_WR_REGS;
ES: BOOL:= TRUE;
TimeOut: TIME:= T#100ms;
Buffer: ARRAY[0..255] OF BYTE;
ErrorSend1: ARRAY[1..4] OF BYTE;
ErrorSend2: ARRAY[1..4] OF BYTE;
ErrorSend3: ARRAY[1..4] OF BYTE;
ErrorSend4: BYTE;
ErrorSend5: BYTE;
Stage: BYTE:= 1;
EndSendStored: BOOL;
EndSendError: BOOL:= FALSE;
HavePause:TON;
SpeedTmp: DWORD;
Speed: WORD;
END_VAR

IF ComPortState = 2 THEN
IF NOT EndSendStored THEN
CASE Stage OF
1: SendModbus1(
Enable:= ES,
Mode:= MB_RTU,
DevAddr:= 1,
FirstAddr:= 40,
Quantity:= 8,
ComHandle:= Settings.Port,
TimeOut:= Timeout,
Buffer:= Buffer);
IF SendModbus1.Complete THEN
EndSendStored:=TRUE;
ErrorSend1[1]:= SendModbus1.Exception;
IF ErrorSend1[1] = 0 THEN
AHU_CONT:= BYTE_TO_BOOL(Buffer[0] AND 8);
ELSE
AHU_CONT:= FALSE;
EndSendError:= TRUE;
Stage:= 4;
END_IF;
END_IF;
2: CASE FanSpeed OF
0: SpeedTmp:= (AHU_Speed1 - 25)*16#4000;
1: SpeedTmp:= (AHU_Speed2 - 25)*16#4000;
2: SpeedTmp:= (AHU_Speed3 - 25)*16#4000;
END_CASE;
Speed:= DWORD_TO_WORD(SpeedTmp / 75);
SendModbus2(
Enable:= ES,
Mode:= MB_RTU,
DevAddr:= 1,
RegAddr:= 50009,
Value:= Speed,
ComHandle:= Settings.Port,
TimeOut:= Timeout);
IF SendModbus2.Complete THEN
EndSendStored:=TRUE;
ErrorSend2[1]:= SendModbus2.Exception;
END_IF;
3: SendModbus3(
Enable:= ES,
Mode:= MB_RTU,
DevAddr:= 1,
CoilAddr:= 6,
Value:= AHU_START,
ComHandle:= Settings.Port,
TimeOut:= Timeout);
IF SendModbus3.Complete THEN
EndSendStored:=TRUE;
ErrorSend3[1]:= SendModbus3.Exception;
END_IF;



END_CASE;
ES:= FALSE;
ELSE
IF EndSendError THEN
EndSendError:= FALSE;
ES:= TRUE;
EndSendStored:= FALSE;
ELSE
HavePause(IN:= EndSendStored,PT:=T#40ms);
IF HavePause.Q THEN
ES:= TRUE;
EndSendStored:= FALSE;
IF Stage >= 14 THEN
Stage:= 1;
ELSE
Stage:= Stage+1;
END_IF;
END_IF;
END_IF;
END_IF;
HavePause(IN:= EndSendStored,PT:=T#40ms);
END_IF;

Brandon_heat_dre
05.11.2018, 20:47
SendModbus1(
Enable:= ES,
Mode:= MB_RTU,
DevAddr:= 1,
FirstAddr:= 40,
Quantity:= 8,
ComHandle:= Settings.Port,
TimeOut:= Timeout,
Buffer:= Buffer);


FirstAddr:= 40 а можно узнать что это за регистр?

ASo
05.11.2018, 21:09
Катушки слова состояния.

Brandon_heat_dre
05.11.2018, 21:29
так сейчас, что бы в голове все устаканить , в описании пчв есть страница с адресами регистров Номер регистра hex (Modbus) C417 Выходные данные: регистр слова состояния привода (STW), все страницы пересмотрел 40го адресам там не нашел, хотя регистр управления по RS-485 частотой совпадает.

ASo
05.11.2018, 21:38
Вы читать умеете? Я же написал - катушки, т.е. битовые регистры. Слово состояния ложится на диапазон 33..48 при адресации с 1 или 32..47 при адресации с 0. Тогда 43 катушка это останов-работа, она и анализируется.

Brandon_heat_dre
08.11.2018, 14:30
В общем не знаю что это был за регистр 40 , слово состояния прекрасно считалось с адреса C417 кодом приведенным выше. Есть теперь пара других вопросов по итогу что такое Buffer и как он заполняется, числа там совсем не понятные по логике же они должны быть в двоичном виде типа 101011100 и так далее а там какой то набор из 1 23 2 64 215 и так далее в итоге строчкой x:=BYTE_TO_WORD(buf2[1]) OR SHL(BYTE_TO_WORD(buf2[0]),8); все переводится в божеский вид 515 или 519 и это уже число полностью соотвествует битам заложенным в слово состояния если число 515 перевести в двоичный вид.

и теперь всплывает вопрос а как бы записать правильно командное слово?


ShowString(0,0,0,WORD_TO_STRING(x));


IF com_ready1=TRUE THEN


w2(
Enable:=TRUE,
Mode:= MB_RTU,
DevAddr:=1,
FirstAddr:=16#C417,
Quantity:=2,
ComHandle:=Settings1.Port,
TimeOut:=T#100ms,
Buffer:=buf2,
);

compl1:=w2.Complete;
err1:=w2.Exception;

IF err1=0 AND compl1 THEN
ClearScreen(0);

x:=BYTE_TO_WORD(buf2[1]) OR SHL(BYTE_TO_WORD(buf2[0]),8);
ShowString(0,0,0,WORD_TO_STRING(x));
END_IF

END_IF

_Mikhail
08.11.2018, 20:20
В общем не знаю что это был за регистр 40 , слово состояния прекрасно считалось с адреса C417 кодом приведенным выше. Есть теперь пара других вопросов по итогу что такое Buffer и как он заполняется, числа там совсем не понятные по логике же они должны быть в двоичном виде типа 101011100 и так далее а там какой то набор из 1 23 2 64 215 и так далее в итоге строчкой x:=BYTE_TO_WORD(buf2[1]) OR SHL(BYTE_TO_WORD(buf2[0]),8); все переводится в божеский вид 515 или 519 и это уже число полностью соотвествует битам заложенным в слово состояния если число 515 перевести в двоичный вид.

и теперь всплывает вопрос а как бы записать правильно командное слово?


ShowString(0,0,0,WORD_TO_STRING(x));


IF com_ready1=TRUE THEN


w2(
Enable:=TRUE,
Mode:= MB_RTU,
DevAddr:=1,
FirstAddr:=16#C417,
Quantity:=2,
ComHandle:=Settings1.Port,
TimeOut:=T#100ms,
Buffer:=buf2,
);

compl1:=w2.Complete;
err1:=w2.Exception;

IF err1=0 AND compl1 THEN
ClearScreen(0);

x:=BYTE_TO_WORD(buf2[1]) OR SHL(BYTE_TO_WORD(buf2[0]),8);
ShowString(0,0,0,WORD_TO_STRING(x));
END_IF

END_IF


Что не понятно с буфером?
Буфер обЪявлен byte.
Считываются регистры, то есть 1 регистр = 2 byte.
Сложив данные двух byte вы получаете нужное вам значение.
Для записи обратное дейстие:
раскладываются переменные по Byte в буфер и передаются