표시설비 제어 프로그램 개발

개발경험담, 2019

by 노정윤

이 프로그램은 P기업의 광양제철소 후판공장에서 사용 중인 세 종류의 인쇄 및 타각 장비에 인쇄할 내용을 보내는 기능을 하는 프로그램으로 2000년대 초반에 포항제철소용으로 개발된 코드를 광양 여건에 맞게 약간 수정하여 2009년부터 사용 중이었다.


그러다가 2017년에 약간의 기능 수정이 필요하게 되었는데, 그때는 이미 원 프로그램의 개발자가 관련업무에서 손을 떼고 다른 일을 하고 있어서 대응이 불가능했고, 그 프로그램과 연동되는 PLC 관련 개발 업무를 하던 우리 회사에 SW 개발 의뢰가 같이 들어왔다.


우리 회사는 모두 10명이 근무하고 있는데, 두 명만 SW 개발자이고 다른 사람들은 모두 PLC 개발자들이다. 영업을 담당했던 K 이사님 역시 PLC 개발자였는데, 자기 파트가 아닌 다른 사람들의 업무는 대체로 간단하고 쉽다고 여기시는 분이었고, 해당 프로그램의 소스코드만 구해놓으면 나머지는 우리(=SW 개발자들)가 알아서 만들어놓을 거라 믿고, 원 개발자를 수소문해서 소스 코드를 1500만 원에 구입한 다음, 저 프로젝트를 덜컥 수주해 버리셨다. (사실, 소스코드는 현장 PC 안에 그대로 있었고, 수정 과정에서 몇 차례 질의응답에 응하는 조건이 추가되었다)


당연히 우리는 개발할 수 없다고 했고, 그 프로젝트는 험난한 길을 걸었다.


일단 그 코드는 Visual C++ 6.0에서 개발되었고, 우리는 Delphi 개발자였다. 게다가 그때 나는 S기업의 전기자동차용 배터리 공장 관련 프로젝트를 마무리하던 중이라 다른 일을 할 수 없었다. 할 수 없이 J 과장이 명목상 개발 업무를 맡기로 하고 다른 일을 하고 있던 원 개발자에게서 몇 차례 교육을 받고 진행하기로 했다. 돌이켜보면 프로그램에서 수정할 내용 자체는 간단했고, PLC에서 할 일이 더 많았긴 했지만.. 처음 들여다보는 VC++ 환경이 낯설기만 한 J 과장 입장에서는 난처할 수밖에 없었다.


그런데, 여직원인 J 과장에게는 여러 가지 이점이 있었다. 사회분위기가 미묘하게 변하고 있을 무렵이었기 때문에 여자 사람과의 관계를 잘못 설정하면 큰 봉변을 당할 수 있다는 사실을 모든 남자들이 심각하게 인식하기 시작할 무렵이었는 데다가, J 과장은 70년대와 그 이전에 출생한 사람들의 관점에서 보면 상당한 미모의 소유자이기도 했고, 성격도 붙임성이 있어서 같이 일하는 사람들의 호감을 이끌어내는데 아주 능숙했다.


사실, 이 사회가 여자들에게만 잔인했던 것은 아니다. 남자들끼리 일할 때, 갑의 입장에 있는 사람들이 을의 입장에 있는 사람들을 괴롭혔던 방식은 여자들이 그토록 억울해하는 성희롱 등과 비교해서 결코 부족함이 없었다고 생각한다. 욕설, 폭언, 술자리 강요, 성접대 강요(자기네들이 놀고 돈을 대신 내라는 식. 물론 공범이 되어야 하므로 호불호에 관계없이 같이 놀아야 하는 식) 등등은 말할 것도 없고, 저런 부당한 대우를 하지 않는 회사라 해도 을 입장에서 친절하게 느껴지는 갑은 거의 없었다. 업무 환경, 개발기간 등에 대한 편의를 고려해 주는 회사는 극히 드물었다.


그런데, J 과장과 함께 일하면, 세상 여자들이 받는 혜택을 함께 누릴 수 있었다. 우리나라 사람들이 원래부터 이렇게 친절했었나 싶을 정도였다. 프로그램에서 오류가 발생하고, 라인이 멈추고, 생산라인 사람들이 흥분해서 분노를 감추지 못하는 그 어떤 순간에도 내가 당연히 예상했던 욕설과 폭언은 없었다. 표시설비 프로젝트를 하면서 우리가 들었던 가장 심한 말이.. "우리가 변명을 들으려고 이 일(프로젝트)을 하는 게 아니다"라는 정도였다. J 과장과 일하기 전에는 세상이 이렇게 멋진 곳인 줄 정말 몰랐다.


그리하여 2017년의 수정 과정은 J과장의 개입 하에 원 개발자가 모든 코드를 대신 수정해 주는 방식으로 마무리되었다. 물론 그 코드를 받아서 현장에 적용하는 것은 J과장이 직접 했다.


그 당시 나는 호기심을 갖고 VC++로 작성된 코드와 그 프로그램이 다른 장비들과 통신하는 방식들을 관찰했는데, Delphi로 이 프로그램을 처음부터 다시 개발하면 어떨까.. 하는 생각을 하기 시작했다. 이것은 호기심이기도 했고 자존심 문제이기도 했다. 63년(64년?) 생인 직장 상사 K 이사님은 이 에피소드 이외의 다른 여러 개발경험담에서도 악역을 맡고 계실 예정인데, 자기와는 별 상관없었던 이 프로젝트에도 입을 대시면서 개발자인데 소스코드가 있는데 왜 손을 못 대느냐 너희가 할 줄 알았으면 아까운 돈 1500만 원을 안 써도 됐을 텐데.. 등등 무심히 내뱉은 다음 본인 스스로는 그런 얘기를 했는지 기억도 못하지만 듣는 입장에서는 쉽게 잊혀지지 않는.. 그런 얘기를 자주 하셨다.


나는 거의 모든 한국인들이 대부분 다 그렇겠지만 "한"의 정서를 갖고 있어서.. 누군가 나를 모욕하거나 무시하면 쉽게 잊지 못한다. K 이사님의 무심한 몇 마디들은 내 오기를 자극했고 나는 광양제철소의 해당 운전실을 들를 일이 있을 때마다 해당 프로그램을 재개발하면 그 시스템이 갖는 몇 가지 치명적 문제를 해결할 수 있다고 얘기하면서 다시 개발하자고 부추겼다.


그러던 2019년... 잘못 마킹된 후판제품이 출하되어 고객 클레임이 발생하는 상황이 빚어지자 고객사에서 드디어 반응이 오기 시작했다. 그때까지의 시스템은 전산실에서 받은 제품 정보를 보관하고 있다가 측면과 타각, 상면 마킹기에게 차례대로 정보를 보내는 구조였는데, 전산실에서 정보를 받는 시점과 각 마킹기로 정보를 보내는 시점이 다르고, 롤테이블의 현재 제품에 대한 추적 정보를 참조하지 않고 있었기 때문에 정상적인 경우에는 별 문제가 없지만, 마킹기 오류로 재인쇄 작업을 하거나 기타 여러 돌발적인 상황 하에서 잘못된 제품정보를 마킹할 위험성이 있었다.


이것은 2009년에 납품된 컴퓨터의 WindowsXP 환경에서 작동하는 기존 프로그램을 수정만 해서는 해결된 문제가 아니었다. 기존 프로그램은 전산실에서 받는 정보를 저장하는 용도로 MySQL5.0을 사용 중이었는데, 내 입장에서는 굳이 DB를 사용할 이유가 없어 보였다. 게다가 그 DB는 그냥 MySQL5.0을 사용한 게 아니라 무려 APM(Apache + PHP + MySQL)으로 깔려있었고, 기본 계정 root 비밀번호 apmsetup 상태인.. 뭐랄까.. 요즘의 보안 개념으로는 도저히 용납할 수 없는 방식이었다.


이것을 나는 Windows10, Delphi, DB 사용하지 않음, PLC 등과의 직접 통신(기존은 DAServer라는 일종의 IO 서버를 통한 통신), HMI 재개발 등등을 포함한 수억 대의 프로젝트로 제안했다. 이것을 거듭, 여러 차례 제안을 했는데.. 무슨 이유에서였는지 K 이사님은 자꾸 Windows7을 고집하셨다. 그래서 나는 사장님께 따로 보고 드리면서 바쁘신 K이사님은 진행 중인 다른 프로젝트에 집중할 수 있도록 이번 프로젝트에서 배제해 달라고 요청했고, 이사님은 이 프로젝트에서 배제되었다. 단순히 OS에 관한 입장차이 때문이 아니라 여러 선례에 비추어 볼 때 K이사님이 이 프로젝트에 개입하시면 사소한 것 하나를 결정하는 것도 쉽지 않을 것이라는 (결과적으로 매우 훌륭했던) 판단 때문이었다. 그리고 이 회사에 와서 진행했던 프로젝트 중에서 가장 깔끔하고 빠르게 끝낸 프로젝트가 되었다.


그렇게 해서 P 기업은 드디어 이 프로젝트를 진행하기로 결심하였는데.. 문제는 돈 많은 후판부(생산)가 아니라 가난한 정비부 예산으로 진행하게 된 것이었고, 기존의 구조를 유지하면서 OS를 업그레이드하고 제어프로그램만 바꾸기로 한 것이었다.


기존의 구조를 유지한다는 것은 매우 많은 문제점을 안고 있었다. 기존 프로그램은 다른 프로그램들과 DDE 통신으로 정보를 교환하고 있었는데, 일단 나는 DDE로 뭔가 개발해 본 일이 없었다. 게다가 DDE 통신은 2003년부터 더 이상 지원되지 않고 내버려진 기능이기도 했고, 보안 등의 문제로 사용하지 말 것을 강력하게 권고받는 기능이기도 했다. 그리고 막상 해보니 되는 게 아무것도 없었다. 계약한 6개월의 개발 기간 중 대부분을 DDE에 대해 생각하며 보냈다.


나는 우선 기존 프로그램이 하는 일을 다음과 같이 분석했다.


1. 제품이 특정 지점에 도달하면 전산실로부터 소켓통신을 통하여 제품 정보를 받고, 응답신호를 보낸다. 신호를 보낼 때는 클라이언트 소켓, 받을 때는 서버 소켓을 사용한다. 받은 제품정보 전문은 별도의 텍스트 파일에 일자별로 저장한다.

2. 전산실과는 Healthy 신호를 주고받는다.

3. 특정 센서 신호를 이용하여 제품 마킹 완료 신호를 보낸다.

4. 전산실로부터 받은 제품정보를 InTouch HMI 화면에 표시하기 위하여 DDE 서버 통신을 이용한다.

5. HMI로부터 명령을 받기 위해서는 DDE 클라이언트 통신을 이용한다.

6. 각종 센서 신호를 받기 위해서 DDE 클라이언트 통신을 이용한다.

7. 측면 마킹을 위해서는 잉크젯 프린터와 소켓통신을 한다. 서버 소켓만 사용해서 접속한 클라이언트에게 통신

8. 타각 마킹을 위해서는 PLC로만 정보를 보내는데, DDE 클라이언트 통신을 이용한다.

9. 상면(메인) 마킹을 위해서는 마킹기에게 클라이언트 소켓으로 마킹정보를 보내고, 사용할 마킹기를 선택하고 마킹기의 위치를 제어하고 인쇄명령 트리거를 보내는 용도로 PLC와 DDE 클라이언트 통신을 이용한다.

10. 각 DDE 통신은 DAServer에서 제공하는 기능을 이용하는데, Intouch와의 통신을 위해서는 FSGateway를 이용하고 각각의 PLC와 통신하기 위해서는 또 다른 프로그램들을 이용하는 식이다.

11. 전산실에서 받은 정보는 MySQL의 마킹기별 테이블에 일단 저장했다가 각 센서 값의 변화에 따라 순차적으로 먼저 받은 정보를 하나씩 보낸다.

12. 타각과 상면 마킹기의 경우 MySQL 별도의 테이블에 저장된 특수문자 코드를 참조하여 전산실에서 받은 전문 정보를 치환하여 보낸다.


우리가 납품할 프로그램은 기본적으로 기존 프로그램과 동일한 역할을 하되 다음과 같은 부분이 변경될 예정이었다.


1. MySQL의 사용을 배제한다. 대신 받는 정보는 배열을 선언하여 일시적으로 메모리에 저장한다. (기존 프로그램에서 MySQL이 "DB"로서 기능하는 일은 거의 없었고, 구조만 복잡하게 보일 뿐이었다. DB를 굳이 사용한 이유는 견적 가격을 올리기 위함이 아니었을까.. 하는 막연한 추측만 남았을 뿐..) MySQL에서는 최대 3개까지만 저장하던 제품정보를 10개 이상 저장하도록 해서 이미 마킹된 제품이 후진해 올 경우 다시 출력하지 않도록 하는 용도로 사용한다.

2. MySQL에 저장되어 있던 특수문자 코드를 그냥 별도의 정수 배열 상수로 선언하여 사용한다. (10년 동안 한 번도 변경되지 않았던 내용이므로 그냥 프로그램 안에 두고 사용하기로 했다)

3. ini 파일에 상대편(전산실 서버, 각종 프린터 등) 아이피와 포트 번호를 두고 사용한다. (기존은 아이피가 바뀌면 프로그램을 다시 컴파일하던 구조)

4. 각 롤테이블에 위치한 제품들의 제품 번호를 라인 PLC로부터 추가로 가져온 다음, 마킹 시점에 해당 테이블의 제품번호와 일치하는 제품 정보를 MySQL 대신 사용하기로 한 배열로부터 검색하여 가져와서 사용한다. 이로서 마킹정보와 실제 제품이 다르게 출력되는 가능성을 원천적으로 제거한다.


아주 바람직하고 깔끔하게 끝날 것 같은 분위기였다.


DDE 통신기능 구현도 처음에는 자료가 부족했지만 J 과장이 밤낮으로 검색하여 찾아준 코드들 덕분에 비교적 손쉽게 완성할 수 있었다.


그런데.. DDE 통신이라는 것이 어떨 때는 되고 어떨 때는 안되며, 사무실에서는 되는데 현장에서는 안 되는 등 종잡을 수 없었다. 게다가 PLC들도 10년 이상 사용해서 그런 건지 원래 그런 건지 PC를 껐다가 켜면 다시 연결이 되지 않는 상황이 계속 발생했고, 설비를 가동 중인 상태에서 개발을 진행했기 때문에 정해진 정기수리일이 아니면 프로그램을 교체할 수 없었는데, 막상 그날은 프로그램을 교체해도 제품이 지나가지 않기 때문에 충분한 테스트를 할 수 없어서 라인이 다시 가동되기를 기다리다가 막상 라인이 가동되면 그때는 원인을 알 수 없었던 문제 때문에 라인이 멈추고 다시 원래 시스템으로 원상복구를 시키기 일쑤였다. PLC 연결 문제가 발생했을 때는 원래 시스템도 동작하지 않았는데 그 원망을 오로지 우리가 덮어쓸 수밖에 없었다. 만약 J과장이 없었다면 나는 그 원망 앞에서 쓰러져 아무 일도 할 수 없었을 것이다.


J과장이 여러 가지 조화를 부려서 벌어주는 시간 동안 PLC의 연결문제는 온갖 인맥을 동원해서 알아낸 Melsec PLC들의 고질적인 문제인 "생존확인 기능"설정을 통해 어느 정도 해결했고, 요상한 DDE 문제들은 모든 DDE 관련 프로그램들이 같은 ID로 실행되어야 하며 특히 DDE 클라이언트들은 반드시 관리자 권한으로 실행되어야 함을 알게 되었고.. 비로소 해결될 수 있었다.


그렇지만 그 이후에도 돌발상황은 자주 일어났는데, 어느 일요일에 운전실에서 걸려온 전화는 라인이 섰을 때 느껴지는 특유의 분노와 흥분된 상태의 막말 등이 걸러지지 않은 채 그대로 전해졌고, J과장이 없는 순간 무슨 일이 일어나게 되는 지를 다시 한번 상기시켜 주었다.


우리가 예상하지 못했던 돌발 상황은 계속 발생했다.


전산실에서 오는 전문은 헤더와 전문 크기만 확인하고 받아들였는데, 같은 헤더가 두 번 세 번 반복된 다음 전체 길이는 같은 상태로 오는 버그가 한 번씩 있어서 우리 프로그램의 오작동을 유발하기도 했고, (이건 전산실에 통보해 주었더니 우리에게 통보하지 않은 상태로 어느 순간 해결되었다. 전산실에서 보내는 비슷한 류의 신호를 공장 전체가 받고 있기 때문에 이런 류의 오류가 있었다는 것은 전산실로서는 기밀일 수밖에 없다. 특히 실무자들이 협력업체 직원인 현 상태에서는 더더욱!) 같은 신호를 동시에 두 번씩 보내서 우리 프로그램을 헷갈리게 만들기도 했다.


PLC 프로그램은 손대지 않았기 때문에 기존 PLC 로직들이 가진 문제는 해결할 수 없었는데, 그중 하나는 두대의 메인마킹기가 한 번씩 서로 박치기를 하려고 달려드는 문제다. 이건 매우 심각한 문제라 우리 회사 PLC 개발자 중 한 명에게 기존 로직에 대한 분석을 요청하기도 했다.


...


시간이 흘러 이제 2024년.


J과장과 나는 따로 독립하여 동업으로 프로그램 개발 회사를 운영 중이고 지금 이 순간에는 인도네시아 포스코에서 또 다른 후판프로젝트를 진행 중이다.


그런데 여기에 예전에 상면과 측면 마킹기를 공급했던 그 업체가 와서 다른 공정에서 일하는 것을 보게 되었고 공장 MES와 공정 PLC 쪽 엔지니어들이 그 회사 사람들과 일하며 고생하는 걸 보니 문득 옛 생각이 떠올랐다.


기억이 다 사라지기 전에 이런저런 프로젝트들의 개발경험담이라도 남겨놓아야겠다는 생각이 들어서 글을 쓰게 되었다.

keyword