PC에서 파이썬으로 PLC를 제어하여 하드웨어 기계제어를 하고 PLC로부터 데이터를 가져오고 보내는 프로그램을 만들어 보겠습니다.
우선 PLC와 시리얼 통신이 무엇인지 간단히 알아보겠습니다.
(이미 알고 계신 분들은 넘어가셔도 좋습니다.)
PLC란?
- Programmable Logic Controller의 줄임말로 주로 산업현장에서 기계를 제어할 때 많이 쓰이며, 산업 플랜트의 유지관리 및 자동 제어 및 모니터링에 사용하는 제어 장치입니다.
- PLC는 순차제어에 사용되는 대표적인 장치이며, 노이즈에 강하여 산업현장에서 신뢰할 수 있는 제어 장치 중 하나입니다.
- 주로 래더 다이어그램으로 프로그래밍되고 래더뿐만 아니라 ST, LI 등 을 사용해서 프로그래밍을 할 수 있습니다.
시리얼 통신이란?
- 다른 말로 직렬 통신이라고도 합니다.
- 시리얼 통신은 하나의 데이터를 비트 단위로 쪼개서 시간차를 두고 하나씩 전송하는 통신 방법입니다.
- 두 개의 선만으로도 전송이 가능하고 적은 수의 선을 사용하기에 비용 면에 저렴하게 통신을 할 수 있습니다. 산업현장에서 가장 많이 쓰고 있는 시리얼 통신은 RS-232C, RS-422, RS-485입니다.
RS-232C : 비동기 통신 3가닥
RS-422 : 전이중 방식 통신(전화기 방식) 선 4가닥
RS-485 : 반이중 통신(무전기 방식) 2가닥
통신을 할 때 꼭 서로 맞춰줘야 하는 사항
1. bps(통신속도)
2. 데이터 길이
3. 패리티(검증)
4. 정지 비트
흔히들 많이 알고 있는 USB도 사실 원래는 주로 시리얼 포트의 데이터 입출력 단자에 연결하여 이용하는 주변 기기들을 좀 더 쉽게 이용하기 위해 만들어진 단자입니다.
※ 아래는 시리얼 통신에 사용한 제품은 LS의 XGB XBC-DN32H입니다.
LS의 제품들은 XG5000이라는 레더 언어를 이용하는 PLC 전용 프로그램이 있습니다.
LS 홈페이지에 들어가면 다운로드할 수 있습니다.
상당히 간편하고 조작이 용이하며 여러 가지 기능들을 사용할 수 있는 전용 프로그램입니다.

위아래 각각 24개의 단자가 있고 우선 아래의 단자는 전원만 연결하였고 위의 단자는 사진에 보이는 IN 부분에 해당하는 16개의 단자와 8개의 RX, TX, SG, COM0 등등 연결하는데 필요한 단자들이 있습니다. 우리는 그중에서 위에 보이는 빨간색, 흰색, 녹색선이 물려있는 RX, TX, SG만 사용할 것입니다.
위에서 설명한 시리얼 통신 중에 우리는 RS-232C로 통신을 할 것입니다.
RS-232C의 통신 케이블 규격은 DB25핀과 DB9핀가 있는데 25핀의 단자 규격은 단말 쪽은 아니고 모뎀 쪽의 연결기 규격으로 정해져 있기 때문에 PC에서 모뎀에 붙어 있는 것이 많습니다. 현재 많이 이용되고 있는 규격으로는 IBM사가 만든 9핀 단자가 있으며 널리 보급되어 있습니다.
1,2,3,4,5
6,7,8,9
1번 핀 DCD
2번 핀 RXD 외부 장치에서 들어오는 직렬통신 데이터를 입력받는 신호선
3번 핀 TXD 비동기식 직렬통신 장치가 외부 장치로 정보를 보낼 때 직렬통신 데이터가 나오는 신호선
4번 핀 DTR
5번 핀 GND 그라운드 접지
6번 핀 DSR
7번 핀 RTS
8번 핀 CTS
9번 핀 RI
우리는 이 중에서 3가닥이 필요하다. 2번 핀 RXD, 3번 핀 TXD, 5번 핀 GND
RS-232C에서 가장 중요한 단자는 송신(TXD) : 출력, 수신(RXD) : 입력, GND입니다.
※ 연결할 때 가장 중요한 부분 ※
RXD - TXD
TXD - RXD
GND - GND
같은 신호끼리 연결하는 것이 아닌 서로 주고받은 신호로 연결해야 합니다.
PC에서 나온 RXD 선은 PLC의 TXD에 연결
PC에서 나온 TXD 선은 PLC의 RXD에 연결
PC에서 나온 GND 선은 PLC의 SG에 연결합니다
여기까지 하셨다면 시리얼 통신을 할 준비는 끝났습니다.
컴퓨터에서 자신이 사용하는 에디터를 켠 후 파이썬 프로그램을 짜시면 됩니다.
import serial
ser = serial.Serial('COM3', 9600, timeout=1)
read = 0
print("Start")
print(ser.name)
ser.write(b'dasdfasdf475 ')
print("Reading")
read = ser.readline().decode('ascii')
print("Reading: ", read)
ser.close()
- import serial : pyserial 라이브러리를 불러옵니다.
- ser = serial.Serial('COM3', 9600, timeout=1) : COM3 포트를 통신속도 9600으로 1초 동안 수신 대기하며 연결 객체를 생성합니다.
- read = 0: read 변수를 0으로 초기화합니다.
- print("Start"): "Start"를 출력합니다.
- print(ser.name): 연결된 시리얼 포트의 이름(COM3)을 출력합니다.
- ser.write(b' '): PLC에 byte 문자열로 어떤 메시지를 보낼지를 적으면 됩니다. b는 byte표시입니다.
- print("Reading"): "Reading"을 출력합니다.
- read = ser.readline().decode('ascii'): 값을 readline으로 받아오는데 이때 byte 단위로 보냈으니까 byte 단위로 들어옵니다, 아스키(ASCII)로 디코드 하여 read 변수에 저장합니다.
- print("Reading: ", read): "Reading: "과 함께 read 변수에 저장된 값을 출력합니다.
- ser.close(): 시리얼 포트 연결 객체를 닫습니다.
여기서 각자의 COM포트 번호를 확인해 주시기 바랍니다.
결과
PC에서 PLC로 무작정 메시지를 보내면 메시지가 제대로 보내졌는지 아닌지 잘 모릅니다.
그래서 위의 사진처럼 아무런 값도 안 옵니다.
그래서 값이 제대로 전송이 되었는지 확인하기 위해서 XG5000 프로그램의 프레임 모니터 기능을 사용하였습니다.
보낸 데이터가 나타나는데 PLC가 오류로 처리하는 것도 아니고 모른다고 합니다.
왜 이런 현상이 일어나냐면 통신 프로토콜을 무시하고 보냈기 때문입니다.
그러므로 우리는 먼저 PC와 PLC끼리 통신을 하려면 통신 프로토콜을 알아야 합니다.
통신 프로토콜이란 컴퓨터나 통신 장비 사이에서 메시지를 주고받는 규칙입니다.
프로토콜은 구현되는 방법은 독립적이라서 하드웨어, 소프트웨어 모두를 사용하여 구현되기도 합니다.
그렇다면 PLC와 통신할 때도 XGT 전용 프로토콜을 알아야 PC에서 요청을 보낼 수 있습니다.
LS 홈페이지에 들어가면 PLC별 설명서가 있는데 찾아보시면 아래 사진처럼 XGT 전용 프로토콜이 나옵니다.
XGT 전용 프로토콜
일단 지금 필요한 Request 프레임의 형태만 알아두고 넘어가겠습니다.
위 사진은 쓰기 부분이라서 명령어가 W고 PLC에 나타나 있는 것을 읽기 위해서는 읽기 부분의 명령어인 R을 써야 합니다.
우선 PLC에 시각적으로 표시가 나야 잘 동작하는지 직관적으로 확인할 수 있기 때문에 OUT 부분에 데이터를 보내고 받는 식으로 만들어야 합니다.
헤더 : ENQ
국번 : 01
명령어 : W
명령어 타입 : SS
블록수 : 01
변수의 길이 : 06
변수 이름 : %PW002
데이터 (16진수) : FFFF
테일 : EOT
PLC의 여러 영역 중 OUT부분의 변수 이름이 %PW002 입니다.
데이터 부분에 FFFF는 PLC OUT 부분에 전부다 불이 들어오게 합니다.
ser.write 부분에 이것을 바로 적용시키면 위와 마찬가지로 PLC가 모른다고 나오는데 그 이유는 헤더와 테일의 문자를 그대로 적으면 ENQ로 받아들이는 것이 아닌 E, N, Q 따로따로 받아들이기 때문입니다.
문자 ENQ는 ^D이고 EOT는 ^E인데 파이썬에서는 이것을 16진수로 바꾸어서 적어야 컴퓨터가 ENQ, EOT 문자로 알아듣습니다.
ENQ : \x05
EOT : \x04
코드
import serial
ser = serial.Serial('COM3', 9600, timeout=1)
read = 0
print("Start")
print(ser.name)
ser.write(b'\x0501WSS0106%PW002FFFF\x04')
print("Reading")
read = ser.readline().decode('ascii')
print("Reading: ", read)
ser.close()
결과
Reading에 답장이 온 것을 볼 수 있습니다.
이것을 XG5000에서 잘 보내졌는지 확인해 보겠습니다.
일단 성공적으로 보내졌습니다.
송신 답장을 보면 ACK01WSSETX로 온 것을 확인할 수 있습니다.
파이썬에는 01WSS로 왔는데 파이썬 터미널 창에서는 헤더와 테일은 표시되지 않는다는 것을 알 수 있습니다.
PLC에도 성공적으로 불이 전부 다 들어온 것을 확인할 수 있습니다.
이번 시간에는 여기까지 하고 다음 시간에는 PC에서 OUT부분에 해당하는 버튼들을 만들어서 누르면 해당 번호(20~2F)에 불이 들어오는 프로그램을 만들어 보겠습니다.
감사합니다