標題: Lazarus 讀寫 PLC 範例 (MC 協議)
無頭像
canonpapago

帖子 28
註冊 2013-4-18
用戶註冊天數 4084
發表於 2020-4-7 22:08 
115.43.252.58
分享  私人訊息  頂部
與三菱 PLC 通訊, 使用 MC 協議 中的 A-1E 協議

■ 組合字串命令

[讀取] 從 D100 讀取一個值
01FF0A006400000020440100

01       副頭部(01=讀取)
FF       PLC 編號(固定)
0A00     時鐘(固定)
64000000 首地址(100=00000064)
2044     設備標識號(D=44)
0100     讀取長度(1個BYTES=0001)


[寫入] 將 100 這個值寫入 D100
03FF0A0064000000204401006400

03       副頭部(03=寫入)
FF       PLC 編號(固定)
0A00     時鐘(固定)
64000000 起始地址(100=00000064)
2044     設備標識(D=44)
0100     寫入長度(1個BYTES=0001)
6400     寫入數據(100=0064)


■ Lazarus 程式碼

//connect
procedure TForm1.LbSpeedButton1Click(Sender: TObject);
begin
  if (IdTCPClient1.Connected) then IdTCPClient1.Disconnect;

  IdTCPClient1.Host := Edit1.Text; //PLC ip address
  IdTCPClient1.Port := StrToInt(Edit2.Text); //PLC port


  IdTCPClient1.ConnectTimeout := 1000;
  IdTCPClient1.ReadTimeout := 200;


  IdTCPClient1.Connect;

end;      



//SEND "write command" to PLC
procedure TForm1.LbSpeedButton2Click(Sender: TObject);
var B:TBytes;
    var Buffer: array [0..99] of byte;
    res: string;
begin

  //送信 Edit5.Text:='03FF0A0064000000204401006400';
  _PByteFromStr(@Buffer, _HexToStr(Edit5.Text), Length(_HexToStr(Edit5.Text)));
  IdTCPClient1.IOHandler.Write(TIdBytes(Buffer), Length(_HexToStr(Edit5.Text)));

  //受信
  SetLength(B, 0);
  IdTCPClient1.IOHandler.ReadBytes(TIdBytes(B), -1); //uses idGlobal
  res:=BytesToString(B); //Indy has BytesToString() and ToBytes() functions for converting between String and TIdBytes


  //授信文字列
  Edit7.Text := '('+_StrToHex(res)+')';

end;

//SEND "read command" to PLC
procedure TForm1.LbSpeedButton3Click(Sender: TObject);
var B:TBytes;
    Buffer: array [0..99] of byte;
    res: string;
begin

  //送信 Edit6.Text:='01FF0A006400000020440100';
  _PByteFromStr(@Buffer, _HexToStr(Edit6.Text), Length(_HexToStr(Edit6.Text)));
  IdTCPClient1.IOHandler.Write(TIdBytes(Buffer), Length(_HexToStr(Edit6.Text)));

  //受信
  SetLength(B, 0);
  IdTCPClient1.IOHandler.ReadBytes(TIdBytes(B), -1); //uses idGlobal
  res:=BytesToString(B); //Indy has BytesToString() and ToBytes() functions for converting between String and TIdBytes

  //授信文字列
  Edit7.Text := '('+_StrToHex(res)+')';
end;  




download : https://mega.nz/file/A1knGCga#gO ... df6DCV0VQmKoJyj07MI

[ 本帖最後由 canonpapago 於 2020-4-7 22:59 編輯 ]


無頭像
canonpapago

帖子 28
註冊 2013-4-18
用戶註冊天數 4084
發表於 2020-4-7 22:47 
115.43.252.58
MC 協議 之 Qna-3E 協議二進制

IdTCPClient 元件的使用方法同上面 A-1E 協議
只是送信資料內容(組合字串命令)不同


■ 組合字串命令

500000FFFF03000C001000010400000A0000A80100      讀取 D10 的 1 個值
D00000FFFF0300040000000000        讀取結果(最後四碼)
         
說明
(送出)
5000    副頭部(固定)
00      網路編號(固定)
FF      PLC 編號(固定)
FF03    IO 編號(固定)
00      模塊站號(站編號)
0C00    請求數據長度(此欄位之後的 BYTE 數)
1000    時鐘(固定)
0104    指令(讀取=0104, 寫入=0114)
0000    子指令
0A0000  數據區(0A0000=00000A=10 暫存器的第 10 個位址)
A8      起始地址(D暫存器都用A8)
0100    長度(0100=0001 表示讀取 1 個值)

(讀回)
D000    副頭部(固定)
00      網路編號(固定)
FF      PLC 編號(固定)
FF03    IO 編號(固定)
00      模塊站號(站編號)
0400    應答數據長度(0400=0004 表示此欄位之後有四個 BYTES, 也就是八個字元)
0000    結束代碼
0000    數據部分



■ 舉一反三 (以下資料間的空格為方便閱讀之用, 實際應用之資料間勿加空格)

如下指令为向D7000写入0x000C (7000=0x1B58)
送出:50 00 00 FF FF 03 00 OE 00 10 00 01 14 00 00 58 1B 00 A8 01 00 0C 00
讀回:D0 00 00 FF FF 03 00 02 00 00 00

如下指令为读取D100开始的20个D值 (20=0x14)
送出:50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
讀回:D0 00 00 FF FF 03 00 2A 00 00 00 00 00 FF FF FF FF FF FF 00 00 01 00 FD FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  讀取結果(最後 80 個字元即為連續的 20 個 D 值)




參考資料
https://www.cnblogs.com/haozhanggy/p/12213159.html
https://blog.csdn.net/jackiewu3/article/details/82343531
https://blog.csdn.net/sinat_36988961/article/details/103087932

[ 本帖最後由 canonpapago 於 2020-4-8 14:50 編輯 ]