Всем доброго дня, всю голову изломал как законектить ПЛК63 и ПЧВ1 по RS-485 протокол modbus если кому не сложно , можете поделиться проектом хотя бы на чтение слова состояния, буду очень признателен, спасибо.
Всем доброго дня, всю голову изломал как законектить ПЛК63 и ПЧВ1 по RS-485 протокол modbus если кому не сложно , можете поделиться проектом хотя бы на чтение слова состояния, буду очень признателен, спасибо.
Для чего ломать голову? Вся информация
https://www.owen.ru/product/preobraz..._pchv1_i_pchv2
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
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;
SendModbus1(
Enable:= ES,
Mode:= MB_RTU,
DevAddr:= 1,
FirstAddr:= 40,
Quantity:= 8,
ComHandle:= Settings.Port,
TimeOut:= Timeout,
Buffer:= Buffer);
FirstAddr:= 40 а можно узнать что это за регистр?
так сейчас, что бы в голове все устаканить , в описании пчв есть страница с адресами регистров Номер регистра hex (Modbus) C417 Выходные данные: регистр слова состояния привода (STW), все страницы пересмотрел 40го адресам там не нашел, хотя регистр управления по RS-485 частотой совпадает.
Вы читать умеете? Я же написал - катушки, т.е. битовые регистры. Слово состояния ложится на диапазон 33..48 при адресации с 1 или 32..47 при адресации с 0. Тогда 43 катушка это останов-работа, она и анализируется.
В общем не знаю что это был за регистр 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