설비 PLC 연동 질문드립니다.

안녕하세요. LS 산전 PLC와 PC를 TCP/IP 연결을 하려고 합니다.

읽기는 PLC 메뉴얼에 예제가 있어서 쉽게 구현을 했는데 쓰기는 메뉴얼에 없어서 질문을 남깁니다.

읽기, 쓰기의 통신 프로토콜 헤더 구성은 동일하며 아래와 같이 byte열을 담아줘야 하는데

checksum을 어찌 산출하는지 도통 모르겠습니다.

아래는 프로토콜 헤더 부분입니다.

sendToPlc = new byte[20];

        //Company ID 고정 값 
        sendToPlc[0] = 0x4C; //L
        sendToPlc[1] = 0x53; //S
        sendToPlc[2] = 0x49; //I
        sendToPlc[3] = 0x53; //S
        sendToPlc[4] = 0x2D; //-
        sendToPlc[5] = 0x58; //X
        sendToPlc[6] = 0x47; //G
        sendToPlc[7] = 0x54; //T
        sendToPlc[8] = 0x00; //\n
        sendToPlc[9] = 0x00; //\n

        //PLC Info - 클라이언트 접속이므로 고정값
        sendToPlc[10] = 0x00;
        sendToPlc[11] = 0x00;

        //PLC Cpu 정보 - XGK : 0xA0 , XGR : 0xA8 (Cpu 정보는 메뉴얼보고 설정해야함)
        sendToPlc[12] = 0xA0;

        //프레임설정 (Client -> Plc : 0x33 , plc -> Client : 0x11)
        sendToPlc[13] = 0x33;

        //InvokeID 프레임간 순서를 지정 (응답시 이ID를 활용함)
        sendToPlc[14] = 0x00;
        sendToPlc[15] = 0x00;

        //Length 명령어부분부터 끝까지 전체 데이터의 byte 길이 (Ascii)
        sendToPlc[16] = 0x0E;
        sendToPlc[17] = 0x00;

        //위치정보 (개별요청이므로 고정값임)
        sendToPlc[18] = 0x00;

        //체크섬 - 이건 솔직히 체크섬을 어찌 계산하는지 모름 
        sendToPlc[19] = 0x4E; <-- 이부분이 왜 4E가 나오는지 ;;

메뉴얼상에서는 BCC (체크섬) 이 위치정보까지의 byte sum이라고 나와있는데 해당 byte들을 더해보면 4E가 나오질 않습니다.
명령어부가 전송되어야할 데이터에 따라 달라지는 부분이기에 체크섬을 다시 계산해야하는데 저 값이 어찌 나온건지 혹시 아시는 분 계실까요??

2개의 좋아요

예전에 읽기, 쓰기 명령어를 작성할 때 체크섬은 무시하고 00으로 해서 썼던 기억이 나네요
메뉴얼에 예약영역이라고 돼있지 않던가요?

개인적으로는 Length 계산을 잘못해서 응답이 안온적이 많았었던…

2개의 좋아요

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

3개의 좋아요

안녕하세요. 저도 메뉴얼에는 예약영역이라고 되어 있어 고정값을 지정해주려했는데 메뉴얼 하단부의 예제에는 산출값을 넣어주었더라고요. 뭐가 맞는건지;; 메뉴얼이 너무 성의가 없습니다…

2개의 좋아요

안녕하세요. 해당 블로그 참고하여 체크섬을 산출했는데 예제에 나온 헤더부분의 체크섬 값이 나오질 않아서 뭔가 다른 산출방법이 있나해서 이곳에 문의드렸습니다.

3개의 좋아요

예제코드를 작성하던 중에 특정 변수의 값이 바뀌었는데 BCC값은 그대로 놔뒀거나 했을 가능성도 있지 않을까요?
다만 그라목손 님께서 공유해주신 코드에 정의된 체크섬 함수는 바이트 최종합에 1의 보수를 취하지 않는 것 같네요. 바이트 체크섬에 종류가 몇 가지 있는데 단순히 더하고 끝나는게 있고 마지막에 1의 보수를 취하는 경우도 있습니다. 이 부분은 한 번 프로토콜 명세 같은게 있다면 확인해보시는게 좋겠네요.

일단 체크섬은 00이나 적당한 값으로 두고 전송을 했을때 응답이 제대로 오는지 확인해보셔도 좋을 것 같습니다.

2개의 좋아요

오타 일 가능성 있고요. 직접 계산 해보니 저 값 아닌데요^^.
LS산전 매뉴얼이 좀 그렇습니다. 오타도 있고, 있어야 될 내용이 없기도 하고요.

저는 통신이 잘됩니다.
아래 코드는 제가 사용하고 있는 코드입니다.

private List<byte> MakeHeader(ushort length)
  {
      List<byte> header = new List<byte>();

      //Company ID
      header.AddRange(Encoding.ASCII.GetBytes("LSIS-XGT"));
      //Reserved Data Area
      header.AddRange(new byte[] { 0x00, 0x00 });
      //PLC Info Area, 데이터 요청일 때는 0x00
      header.AddRange(new byte[] { 0x00, 0x00 });
      //CPU Info Area, Reserved 영역을 통해서 확인 가능(매뉴얼 내용)
      header.Add(0xA0);
      //Source of Frame, 요청 = 0x33, 응답 = 0x11
      header.Add(0x33);
      //Invoke ID, Frame 순서를 구별하기 위한 ID, 한개의 Frame으로 고정됨
      header.AddRange(new byte[] {0x00, 0x01});
      //요청 데이터 길이
      header.AddRange(BitConverter.GetBytes(length));
      //Module Position, 응답 패킷에서 유효함
      header.Add(0x00);

      ushort bcc = 0;
      for (int i = 0; i < header.Count; i++)
      {
          bcc += header[i];
      }

      header.Add((byte)(bcc));

      return header;
  }
6개의 좋아요

메뉴얼이 이상한거 같아 긴가민가 했는데 역시 메뉴얼이 잘못된거 였네요. BCC 코드까지 너무 감사합니다…!! 직접사용하시는 코드이니 확실하겠네요. 감사드립니다!

1개의 좋아요

안녕하세요. 계속 체크섬 산출에 시간을 끄느니 다양한 예제를 보고 그냥 TEST를 해보려 했는데 아래분이 알려주셨네요. 감사합니다!

1개의 좋아요