반응형
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 = 0; for (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와 이더넷 통신하기
반응형
'프로그래밍 > C Sharp' 카테고리의 다른 글
[ C# ] LS 산전 PLC 이더넷 통신 - 개별 쓰기 (2) | 2021.12.07 |
---|---|
[ C# ] LS 산전 PLC 이더넷 통신하기 - 연속 읽기 (0) | 2021.12.07 |
[ C# ] 미쯔비시 QnA 시리즈 PLC와 PC 이더넷 통신하기 (3) | 2021.11.23 |
[ C# ] 비트연산 처리 모음 (2) | 2021.11.19 |
[ C# ] 키보드 기능키 ( Num Lock, Caps Lock , Scroll Lock ) 확인하기 (0) | 2021.11.16 |
댓글