본문 바로가기
프로그래밍/C Sharp

[ C# ] 미쯔비시 PLC 이더넷 TCP/UDP 통신 소스( github 소스 내용 분석)

by jeong-f 2022. 11. 8.
반응형

미쯔비시의 통신 소스를 작성하여 공유한 소스 중 쓸만한 사이트가 있어서 공유하고자 합니다
통신은 이더넷 타입의 TCP 또는 UDP의 통신을 지원하며  프로그램의 제작 형태를 참고하고자  소스를 확인 분석합니다.

* 다양한 프로그램 코드들을 참고하여 가장 적합한 소스를 만들 수 있도록 추가적인 자료 링크를 공유합니다. *

https://github.com/SecondShiftEngineer/McProtocol/blob/master/McProtocol/MCProtocol.cs

 

GitHub - SecondShiftEngineer/McProtocol: This is a protocol for communicating with Mitsubishi PLCs. This is very similar to a Mo

This is a protocol for communicating with Mitsubishi PLCs. This is very similar to a Modbust protocol only it is a bit more proprietery. This protocol can be used without addition hardware on some ...

github.com

 

소스에서 사용된 주요 함수들

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public interface Plc : IDisposable 
        {
            int Open();
            int Close();
            int SetBitDevice(string iDeviceName, int iSize, int[] iData);
            int SetBitDevice(PlcDeviceType iType, int iAddress, int iSize, int[] iData);
            int GetBitDevice(string iDeviceName, int iSize, int[] oData);
            int GetBitDevice(PlcDeviceType iType, int iAddress, int iSize, int[] oData);
            int WriteDeviceBlock(string iDeviceName, int iSize, int[] iData);
            int WriteDeviceBlock(PlcDeviceType iType, int iAddress, int iSize, int[] iData);
            int ReadDeviceBlock(string iDeviceName, int iSize, int[] oData);
            int ReadDeviceBlock(PlcDeviceType iType, int iAddress, int iSize, int[] oData);
            int SetDevice(string iDeviceName, int iData);
            int SetDevice(PlcDeviceType iType, int iAddress, int iData);
            int GetDevice(string iDeviceName, out int oData);
            int GetDevice(PlcDeviceType iType, int iAddress, out int oData);
        }
cs

 

  • Open : 연결
  • Close : 중지
  • SetBitDevice : 비트 쓰기
  • GetBitDevice : 비트 읽기
  • WriteDeviceBlock : 다중영역 디바이스 쓰기
  • ReadDeviceBlock : 다중영역 디바이스 읽기
  • SetDevice : 단일 다비이스 쓰기
  • GetDevice : 단일 다비이스 읽기

MC 프로토콜의  패킷 내용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class McCommand
            {
                private McFrame FrameType { get; set; }  
                private uint SerialNumber { get; set; }  
                private uint NetwrokNumber { get; set; }
                private uint PcNumber { get; set; } 
                private uint IoNumber { get; set; } 
                private uint ChannelNumber { get; set; }
                private uint CpuTimer { get; set; }  
                private int ResultCode { get; set; } 
                public byte[] Response { get; private set; }   
 
                public McCommand(McFrame iFrame)
                {
                    FrameType = iFrame;
                    SerialNumber = 0x0001u;
                    NetwrokNumber = 0x0000u;
                    PcNumber = 0x00FFu;
                    IoNumber = 0x03FFu;
                    ChannelNumber = 0x0000u;
                    CpuTimer = 0x0010u;
                }
 
                public byte[] SetCommand(uint iMainCommand, uint iSubCommand, byte[] iData)
                {
                    var dataLength = (uint)(iData.Length + 6);
                    var ret = new List<byte>(iData.Length + 20);
                    uint frame = (FrameType == McFrame.MC3E) ? 0x0050u :
                                 (FrameType == McFrame.MC4E) ? 0x0054u : 0x0000u;
                    ret.Add((byte)frame);
                    ret.Add((byte)(frame >> 8));
                    if (FrameType == McFrame.MC4E)
                    {
                        ret.Add((byte)SerialNumber);
                        ret.Add((byte)(SerialNumber >> 8));
                        ret.Add(0x00);
                        ret.Add(0x00);
                    }
                    ret.Add((byte)NetwrokNumber);
                    ret.Add((byte)PcNumber);
                    ret.Add((byte)IoNumber);
                    ret.Add((byte)(IoNumber >> 8));
                    ret.Add((byte)ChannelNumber);
                    ret.Add((byte)dataLength);
                    ret.Add((byte)(dataLength >> 8));
                    ret.Add((byte)CpuTimer);
                    ret.Add((byte)(CpuTimer >> 8));
                    ret.Add((byte)iMainCommand);
                    ret.Add((byte)(iMainCommand >> 8));
                    ret.Add((byte)iSubCommand);
                    ret.Add((byte)(iSubCommand >> 8));
                    ret.AddRange(iData);
                    return ret.ToArray();
                }
 
 
                public int SetResponse(byte[] iResponse)
                {
                    int min = (FrameType == McFrame.MC3E) ? 11 : 15;
                    if (min <= iResponse.Length)
                    {
                        var btCount = new[] { iResponse[min - 4], iResponse[min - 3] };
                        var btCode = new[] { iResponse[min - 2], iResponse[min - 1] };
                        int rsCount = BitConverter.ToUInt16(btCount, 0);
                        ResultCode = BitConverter.ToUInt16(btCode, 0);
                        Response = new byte[rsCount - 2];
                        Buffer.BlockCopy(iResponse, min, Response, 0, Response.Length);
                    }
                    return ResultCode;
                }
 
 
 
                public bool IsIncorrectResponse(byte[] iResponse)
                {
                    var min = (FrameType == McFrame.MC3E) ? 11 : 15;
                    var btCount = new[] { iResponse[min - 4], iResponse[min - 3] };
                    var btCode  = new[] { iResponse[min - 2], iResponse[min - 1] };
                    var rsCount = BitConverter.ToUInt16(btCount, 0- 2;
                    var rsCode  = BitConverter.ToUInt16(btCode, 0);
                    return (rsCode == 0 && rsCount != (iResponse.Length - min));
                }
            }
        }
cs

 

  • McCommand :  생성자( iFame 통신 프로토콜 선택 --> 3E 또는 4E)
  • SetCommand : PLC에 명령 전송
  • SetResponse : PLC로 부터 수신된 데이터 분석
  • IsIncorrectResponse : PLC로부터 수신된 데이터가 정상 인지 확인(오류 확인)

 

소스 코드

McProtocol-master.zip
0.02MB

통신 관련 문서

2021.11.23 - [프로그래밍/C Sharp] - [ C# ] 미쯔비시 QnA 시리즈 PLC와 PC 이더넷 통신하기

 

[ C# ] 미쯔비시 QnA 시리즈 PLC와 PC 이더넷 통신하기

통신 설정 통신 설정을 위해서 [ PLC 파라미터 ] 설정 메뉴를 눌러 파라미터 창을 띄웁니다. IP 설정 : [ 디바이스 설정 ]에서 IP 및 서블릿 기본 라우터 IP를 입력합니다. 통신 모드: 바이너리로 체크

jeong-f.tistory.com


반응형

댓글