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

[ C# ] LS 산전 PLC 이더넷 통신-헤더 프레임 만들기

by jeong-f 2021. 12. 7.
반응형

LS PLC의 데이터의 전송은 헤더 + 프레임(읽기/쓰기 명령)을 합쳐서 데이터를 전송하는 방식으로 데이터의 구조를 알아야 정상적으로 통신이 가능합니다,
읽기와 쓰기 명령에 공통적으로 들어가야 할 헤더를 만드는 법을 먼저 확인하고 읽기/쓰기 명령을 만들어 보도록 하겠습니다.

헤더 구조

데이터 헤더는 아래와 같으며 고정은 적색으로 표시하겠습니다.

  • Compay ID(8): 고정값으로 "LSIS-XGT"를 입력합니다.
  • Reserved(2) : 예약 영역으로 0x00 고정입니다
  • PLC Info(2) : 클라이언트로 접속할 것이므로 0x0000 고정입니다.
  • CPU Info(1) : PLC 모델에 따라 다르나 XGK와 XGB는 0xA0를 쓰면 됩니다.
  • Source of Frame(1) : 클라이언트 이므로 0x33 고정입니다.
  • Invoke ID(2) : 프레임 순서 구분용으로 그냥 0x0001을 사용하시면 됩니다.
  • length(2) : 헤더 뒤에 붙을 데이터 프레임 바이트 수를 넣어 줍니다.
  • FEnet Position(1) : 모듈의 슬롯 번호이나 보통 CPU에 붙어 있으므로 0x00을 사용하시면 됩니다.
  • Reserved2(BCC)(1) : 앞의 데이터들을 모두 더한 값들에 대하여 체크썸 값을 계산해서 넣으면 됩니다.

위의 헤더 구조를 보면 프로그램으로 구현할 경우 뒤에 붙을 프레임의 데이터 길이를 입력받아 BCC 체크하는 코드를 입력한 후 헤더들의 바이트들을 만들면 될 것으로 보입니다.

함수로 만들기

아래 방식으로 헤더를 생성하는 함수를 만들면 됩니다.

byte [] 헤더 만들기(프레임 길이)
{
헤더 프레임 고정 변수 할당
프레임 길이 넣기
앞에서 입력된 값의 BCC 구함
return 데이터들의 바이트 배열 반환
}

또한 BCC도 별도의 함수로 제작하면 됩니다.

C# 함수 만들기

함수들을 구조체로 만들고 프레임 데이터를 받는 함수(Copy)와 BCC를 구하는 함수(BCC_Check)를 만들어 줍니다.

먼저 뒤에 들어갈 바이트 명령(읽기/쓰기)들을 만든 후 Copy 함수에 길이와 데이터들을 입력하면 바이트 배열로 받을 수 있습니다.

C# 코드 확인

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
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct _LS_FENET_HRADER
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    public char[] CompanyID;
    public ushort Reserved;
    public ushort PLC_Info;
    public byte CPU_Info;
    public byte Source_of_Frame;
    public ushort InVoke_ID;
    public ushort Length;
    public byte FEnet_Position;
    public byte Reserved_BCC; // 바이트 배열로 리턴
    public char[] Copy(int length, params char[] cDataFrame)
    {
        CompanyID = new char[] { 'L''S''I''S''-''X''G''T' };
        Reserved = 0x0//0x00 : 예약영역
        PLC_Info = 0x00;//클라이언트(MMI) → 서버(PLC) : Don’ care (0x00CPU_Info = 0xA0; //XGK: 0xA0
        Source_of_Frame = 0x33//클라이언트(MMI) → 서버(PLC) : 0x33
        InVoke_ID = 0x01//레임간의 순서를 구별하기 위한 ID
        Length = (ushort)length; //Application Instruction의 바이트 크기 // CPU 이므로 0 //(Bit0~3 : FEnet I/F 모듈의 슬롯(Slot) 번호 // Bit4~7 : FEnet I/F 모듈의 베이스(Base) 번호
        FEnet_Position = 0x00//0x00 : 예약영역 (Application Header의 Byte Sum)
        Reserved_BCC = 0x00;
        byte[] byHeader = new byte[Marshal.SizeOf(this)];
        unsafe
        {
            fixed (byte* fixed_buffer = byHeader)
            {
                Marshal.StructureToPtr(this, (IntPtr)fixed_buffer, false);
            }
        } // 배열 변환
        char[] cHeader = Array.ConvertAll(byHeader, x => (char)x); // 체크썸
        cHeader[cHeader.Length - 1= (char)BCC_Check(cHeader, 0, cHeader.Length - 2); // 배열 합치기
        char[] reArray = new char[cHeader.Length + length];
        Array.Copy(cHeader, reArray, cHeader.Length);
        Array.Copy(cDataFrame, 0, reArray, cHeader.Length, length);
        return reArray;
    } // BCC 체크
 
    int BCC_Check(char[] buff, int iStart, int iEnd)
    {
        int CheckSum = 0for (int i = iStart; i < iEnd; i++)
        {
            CheckSum = CheckSum + buff[i];
            if (CheckSum > 255)
            {
                CheckSum = CheckSum - 256;
            }
        }
        return CheckSum;
    }
};
cs

2021.11.17 - [프로그래밍/하드웨어] - [ FA ] LS산전 PLC와 PC와 이더넷 통신하기

 

[ FA ] LS산전 PLC와 PC와 이더넷 통신하기

LS 이더넷 타입 PLC는 자체 적으로 통신 기능을 가지고 있어 설정에서 변경만 해주면 PC와 통신이 가능합니다. 아래 설정을 따라가시면 통신 설정을 할 수 있습니다. 장치 소개 XGB / XGP 등 이더넷

jeong-f.tistory.com

 

반응형

댓글