본문 바로가기
PLC 전기제어 기술자료/프로그램 기술자료

미쓰비시 PLC 문자열 분리: INSTR/MIDR로 콤마 데이터 파싱하기

by 위치결정JP 2022. 1. 22.
728x90
반응형

 

계측기나 검사장비와 데이터를 주고받다 보면 콤마(,)로 구분된 문자열(예: OK,162.5,165.8,126.1)을 자주 만납니다.
이 글은 미쓰비시 MELSEC PLC에서 INSTR/MIDR 두 명령어만으로 콤마 구분 문자열을 항목별로 분리하는 방법을, 실제 GX Works2 래더와 모니터링 화면으로 단계별 정리합니다.

문자열 분리의 핵심은 두 가지입니다.
구분자(콤마)의 위치를 찾고(INSTR), 그 위치를 기준으로 사이의 문자를 잘라내는(MIDR) 것입니다.

1. 문자열 검색: INSTR 명령어

INSTR 은 기준 문자열에서 특정 문자를 찾아 그 위치를 돌려주는 명령입니다. 인수 구조는 다음과 같습니다.

인수 의미
검색 문자 찾을 문자 (예: 콤마)
기준 문자열 검색 대상 전체 문자열
검색 문자 위치 결과(찾은 위치)를 저장할 디바이스
검색 시작 위치 몇 번째 문자부터 찾을지

 

테스트로 예문 "OK,162.5,165.8,126.1"D0 에 저장하고, 찾을 콤마("," = 0x2C)를 D1000 에 저장합니다.
검색 시작 위치를 상수 K1 로 두면 문자열 맨 앞부터 검색하고, 찾은 위치는 D10 으로 돌려받습니다.

처음 발견한 콤마의 위치는 D10 = 3 으로 리턴됩니다.
실제로 예문 "OK,162.5,..." 에서 콤마는 세 번째 자리에 있으니 정확합니다.

이제 다음 콤마를 찾을 차례입니다.
그런데 검색 시작 위치를 다시 1 로 두면 또 같은 세 번째 콤마를 찾게 됩니다.
그래서 이번에는 시작 위치를 바꿔 줘야 합니다.

 

 

마지막으로 찾은 콤마 위치보다 +1 뒤부터 검색하면 됩니다.
방금 찾은 위치 D10 에 1을 더해 D11 에 저장하고, 그 위치부터 INSTR 로 다음 콤마를 찾아 D12 에 저장합니다.
이번에는 D12 = 9 가 리턴되는데, 예문에서 두 번째 콤마도 아홉 번째 자리에 있습니다.

📝 NOTE

INSTR 의 검색 시작 위치를 "직전에 찾은 콤마 위치 +1" 로 갱신해 가며 반복하면, 문자열 안의 모든 콤마 위치를 순서대로 얻을 수 있습니다.
이 위치 값들이 다음 단계(MIDR 추출)의 경계가 됩니다.

2. 문자열 추출: MIDR 명령어

콤마 위치를 알았으니 이제 그 사이의 문자를 잘라낼 차례입니다. MIDR 은 기준 문자열에서 지정한 시작점부터 지정한 개수만큼의 문자를 추출합니다. 인수 구조는 다음과 같습니다.

인수 의미
기준 문자열 추출 대상 전체 문자열
추출 문자열 저장 영역 잘라낸 문자를 담을 디바이스
시작점 + 문자 개수 연속된 워드 어드레스로 자동 할당 (주의)
⚠️ 주의

MIDR 의 "추출 시작점"과 "추출 문자 개수"는 지정한 디바이스부터 연속된 두 워드로 자동 할당됩니다.
시작점을 D20 으로 지정하면 개수는 D21 이 됩니다.
인접 어드레스가 다른 용도로 쓰이지 않도록 주의해야 합니다.

추출에 필요한 값은 두 가지입니다.
시작점은 콤마 기준 +1 위치, 문자 개수는 (다음 콤마 위치 − 시작점) 입니다.

첫 번째 항목 "OK" 를 예로 들면, 시작점은 문자열 맨 앞이므로 상수 1D20 에 저장하고, 개수는 첫 콤마 위치 D10 에서 시작점 D20 을 뺀 값을 D21 에 저장합니다.
그러면 D20 = 1, D21 = 3 − 1 = 2 가 되어 "1번째 문자부터 2개를 추출" 한다는 의미가 됩니다.

 

 

MIDR 을 실행하면 "OK" 가 추출됩니다.

 

 

두 번째 항목 "162.5" 도 같은 방법입니다.
시작점은 직전 콤마 위치 +1, 개수는 다음 콤마 위치 − 시작점입니다.
직전 콤마 위치 D10 에 +1 한 값을 시작점 D22 에, 다음 콤마 위치 D12 에서 시작점 D22 를 뺀 값을 D23 에 저장합니다.

 

 

D22 = 4, D23 = 5 가 되어 "4번째 문자부터 5개" 를 D55 에 추출합니다.

 

 

정확히 "162.5" 가 추출됩니다. 이 과정을 반복하면 콤마로 구분된 문자열을 원하는 만큼 잘라낼 수 있습니다.

3. 반복 분리 프로그램과 에러 방지 인터락

INSTR 로 위치를 찾고 MIDR 로 추출하는 흐름을 합쳐, 네 항목을 한 번에 분리하는 프로그램으로 만듭니다. 이때 명령어가 잘못된 값으로 실행되지 않도록 인터락을 함께 넣습니다.

 

  • LEN 명령으로 문자열의 총 길이를 파악해, 시작 포인트가 총 길이를 넘지 않도록 인터락을 건다.
  • MIDR 은 시작 포인트와 문자 개수가 모두 0보다 클 때만 실행되도록 인터락을 건다.

 

 

 

이렇게 네 번에 걸쳐 문자열을 D20, D25, D30, D35 로 추출하면, 예문 "OK,162.5,165.8,126.1" 이 각각 분리되어 다음처럼 들어가길 기대합니다.

디바이스 기대 값
D20 "OK"
D25 "162.5"
D30 "165.8"
D35 "126.1"

 

그런데 1~3번째 항목은 잘 분리됐는데 4번째 항목이 정리되지 않습니다.
프로그램으로 돌아가 원인을 찾아봅니다.

4. 마지막 항목 처리: 다음 콤마가 없을 때

 

원인은 마지막 항목 뒤에는 콤마가 없다는 데 있습니다.
INSTR 이 콤마를 찾지 못해 반환값이 0 이 되고, 그 결과 문자 개수(D1021)가 정상적으로 계산되지 않았습니다.

이런 경우 종료 코드(별도 구분자)로 끝점을 찾는 방법도 있지만, 예문에는 종료 코드도 없습니다.
그래서 문자열의 총 길이로 끝점을 대신 합니다.
앞서 인터락용으로 LEN 명령을 통해 총 길이를 D1002 에 저장해 두었으니 이를 활용합니다.

 

 

콤마를 찾지 못한 경우(INSTR 반환값 D1022 = 0)에는 문자열 총 길이 + 1 을 다음 콤마 위치로 써 줍니다.
이렇게 하면 기존 프로그램 틀을 바꾸지 않고도 마지막 항목까지 처리됩니다.

 

 

 

이제 네 항목이 모두 깔끔하게 분리됩니다.
다른 데이터가 수신되어도 같은 로직으로 정상 동작합니다.

위 예제를 그대로 담은 GX Works2 프로젝트 파일을 첨부합니다.
실제로 모니터링하며 INSTR/MIDR 동작을 직접 확인해 보세요.

 

Instr_Midr_1.gxw
0.89MB

💡 TIP

실제 현장에서는 분리 항목 수가 가변일 수 있습니다. 콤마 개수를 먼저 세어 반복 횟수를 동적으로 정하거나, 위 "콤마 없음 = 총 길이로 종료" 처리를 항상 마지막 반복에 적용하면 항목 수가 달라져도 안전합니다.

마무리

콤마로 구분된 문자열 분리는 결국 INSTR 로 구분자 위치를 찾고 / MIDR 로 사이를 잘라내는 두 명령의 반복입니다.
여기에 LEN 기반 인터락과 "마지막 항목은 총 길이로 종료" 처리만 더하면, 계측기·검사장비에서 들어오는 CSV 형태 데이터를 PLC 안에서 바로 가공할 수 있습니다.

💡 TIP

같은 분리 로직을 매번 새로 짜지 않고 XCALL 함수 하나로 재사용하는 방법은 미쓰비시 PLC 문자열 스플릿 함수화: 콤마 구분 데이터 분리 (함수화 2편) 에서 다룹니다. 또한 시리얼/이더넷으로 받은 데이터를 수신·파싱하는 전체 흐름은 Modbus 입문 가이드 2편: CRC-16 생성 원리와 수신 데이터 파싱 과 이어집니다.

728x90
반응형