페이지

2016년 3월 15일 화요일

pvbrowser MODBUS 데몬 컴파일

하위 혹은 상위 기기와 데이터 교환을 하기 위한 여러가지 방식 중 가장 보편적인 통신 규약인 MODBUS 데몬을 만드는 방법에 대해 알아보자.

MODBUS 프로토콜은 RTU, Socket 두가지 방식을 지원해 준다. RTU 방식은 일반 시리얼통신(RS-232, RS-485,..), Socket은 Internet 방식이라고 단순하게 생각하자.
일반적인 기기(PLC, embeded Device, Arduino,...)들은 기본 혹은 옵션사양으로 시리얼 통신 방식을 지원해 준다. 통신 방식이 485인 경우 MODBUS 프로토콜을 많이 지원해 주지만 232를 이용하는 경우도 기기가 지원만 해준다면 Modbus 프로토콜을 사용할 수 있다. 근래 들어 USB를 이용하는 경우도 있는 것 같다. 이것은 MODBUS 가 통신 프로토콜 규약이지 통신 방식 규정이 아니기 때문이다.

이상한 이야기는 집어 치우고 pvdevelop에서 MODBUS 통신용 daemon을 어떻게 만드는지 알아보자 매우 간단하다.

pvbrowser 통신 데몬 작동 방식

pvbrowser에서 사용하는 데이터 수집(통신)은 서버 프로그램과 별도의 통신 전용 데몬 프로그램에서 전담한다. 통신 데몬은 내부적으로 두개의 스레드로 구성되어 있다. 한개의 스레드는 주기적으로(cyclically) 데이터를 읽어들인 후 shared memory에 읽어들인 결과를 저장한다. 다른 한개의 스레드는 출력값이 메일박스에 들어오는 것을 감시하다가 메일 박스에 출력할 값이 들어오면 외부기기로 값을 전송한다.
서버 프로그램은 shared memory에 저장된 값을 읽어들어 필요한 조작을 수행한다. 만약 서버 프로그램에서 외부 기기로 데이터 전송이 필요한 경우에는 mail box로 값을 전송하기만 하면 된다.
 이 방식은 서버 프로그램을 재 시작할 필요가 발생한 상황에서도 외부 기기로 부터의 데이터 입력을 계속 받을 수 있을 뿐 아니라, 개별적인 shared memory와 mailbox를 갖는 여러 대몬을 한꺼번에 사용할 수 있다는 장점이 있다. 즉 통신 채널이 틀리거나, 통신 규약이 다른 여러 데몬을 함께 실행할 수 있다는 것이다.


그림 1. 모드버스 데몬 설정파일
그림 1은 pvdevelop 프로그램에서 Demon->Modbus를 선택했을 때 나타나는 MODBUS DAEMON Make 다이얼로그 창이다. 이창의 하부에 위치한 버튼을 이용하여 기존에 있는 파일을 선택하거나, 새로만들거나 할 수 있다. 새창이 열렸을 때 기본 파일 명은 컴파일 버튼 옆에서 확인 할 수 있다. 이 경우에는 modbusdaemon.mkmodbus 이다.



1. Shared Memory, Mailbox 설정

하드 드라이브에 shared memory와 mailbox가 사용할 폴더를 만든 후, 하위 폴더로 shm, mbx를 만들고 modbusdaemon.mkmodbus(기본 파일, 파일명이 다를 수도 있다.) 파일의 shared_memory, mailbox에 전체 경로명을 적어 주면 된다.
pvbrowser 에서 추천하는 표준 위치는 c:/automation/shm, c:/automation/mbx 이지만 원하는 위치에 폴더를 만든 후 modubsdaemon.mkmodbus 에 경로를 지정해 주면 된다.

주의 사항

  • 윈도우의 경우 경로에 \ 기호를 사용하지만, 이렇게 사용하면 인식하지 못하므로 역슬래쉬(/)기호를 사용하여 경로를 지정하여야 정상 작동한다.
  • 하드 디스크에 폴더까지만 만들어 주면 된다.
    데몬이 동작하면 파일이 자동으로 생성된다.
  • modbusdaemon.mkmodus 파일에는 파일명이 포함된 전체 경로를 적어 주어야 한다.
    예) shared_memory=c:/automation/shm/modbus.shm
        mailbox=c:/automation/mbx/modbus.mbx

2. 시리얼 통신 포트 설정


통신 방식은 두가지가 있다. serial, socket 두가지 방식을 지원한다.
  • Serial 방식
    #communication=serial    <- 주석처리 되어 있다.
    tty=/dev/ttyS0
    baudrate=9600
    rtscts=1
    parity=0 # 0=NONE 1=ODD 2=EVEN
    protocol=0 # 0=RTU 1=ASCII
  • Socket 방식
    communication=socket
    tcpadd=lehrig2
    tcpport=502

기본적으로 socket 방식이 활성화되어 있는 것을 알 수 있다. 기본적으로 리눅스 device 형태로 기술되어 있다. 재미 있는 것은 data 길이, stop bit 와 같은 항목을 설정할 수 없다.
만약 이러한 항목을 변경해야 할 경우에는 modbusdaemon.cpp 파일 메인 함수의 다음 항목을 직접 수정한 후 재 검파일하면 된다.

serial.openDevice(SERIAL_DEVICE,B115200,1,0,8,1,rlSerial::NONE)

자,... 나는 OS 가 윈도우이니까, 어느 항목을 수정하여야 할까?
  1. communication=serial 의 주석을 제거하고, communicaton=socket은 주석 처리 하자.
  2. tty=COM1 <--사용하는 COM 포트 번호를 넣어준다.
  3. baudrate, parity, protocol을 순차적으로 원하는 값으로 변경해 준다.
  4. rtscts <-- Flowcontrol 항목은 사용하지 않으니까, 0
% 연결 테스트 목적이라면 protocol 항목을 ASCII로 하여 연결 테스트 및 패킷 전송상태를 확인한 후 RTU 방식으로 변경하는 것이 신상에 이롭다.


시리얼 포트 1, 통신속도 115200, 패리티 None, 프로토콜 ASCII 로 설정하였다.


3.순차 통신 데이터 설정(?)


 pvbrowser 통신 데몬을 설명할 때 주기적 (cyclically)이란 단어를 사용하였다. 뭐라고 표현을 해야 할 지 뽀족한 단어가 생각나지 않지만 지정된 혹은 나열된 순서로 기기로 부터 데이터를 읽어 들인 후 다시 처음부터 데이터를 읽어 들인다.<--설명이 OTL... 이라 죄송



  • cycle
    1 ~ 원하는 사이클
    1 번 부터 순차적으로 진행된다.
  • slave
    연결되는 통신 기기의 modbus slave address 지정
  • function
    1 : Read Coil Status
    2 : Read Input Status
    3 : Read Holding Registers
    4 : Read Input Registers

    % 1, 2 은 1 비트 데이터 기준
       3, 4 는 2 byte 데이터 기준
  • start_adr
    통신 기기로 부터 읽어들일 내부 어드레스 시작 번지
  • num_register
    통신 기기로 부터 읽어들일 데이터(비트 혹은 워드) 갯수



여기서 잠깐 모드버스 레지스터 맵에 대해 알아보자.간과하기 쉽지만 중요한 내용이다.



 rlModbus 라이브러리에서 데이터가 저장되는 시작 주소값은 항상 0 부터 시작한다(C/C++ 언어에서 배열은 항상 0부터 시작한다.). 이 말은 start_adr 에서 지정한 시작 주소가 내부적으로는 0번지에 저장된다는 것을 의미하며, 사용하는 function 코드값으로 부터 어떤 레지스터리를 이용하는지 알 수 있다.
예를 들어 funcdtion =4, start_adr = 1 은 물리적으로 400001 holding register를 의미한다. 이 레지스터 번지가 0번지에 저장되는 것이다.
만약 function = 4, start_adr=108은 내부적으로 107 (006BH) 번지를 의미한다.



--- 메모리 대응에 대해 한번더 테스트 해보자... 하도 사용한지 오래되서 OTL....---

서버 프로그램에서 shared_memory에 저장된 값을 읽어 들이들이기 위한 함수
  • val = modbus.readBit(offset, number);
  • val = modbus.readByte(offset, number);
  • val = modbus.readShort(offset, number);
서버 프로그램에서 mailbox로 값을 전송할 때 사용하는 함수
  • modbus.write(slave, function, data, len);
  • modbus.writeSingleCoil(slave, adr, value);
  • modbus.writeMultipleCoils(slave,adr, values[], num_coils);
  • modbus.writePresetSingleRegister(slave, adr, value);
  • modbus.writePresetMultipleRegisters(slave, adr, values[], num_values);

함수들의 자세한 사용법은 help파일에 소스코드까지 포함되어 있으니 검토하기 바란다.

4. Compile

modbus 데몬 설정 다이얼로그 창에서 편집이 다 끝났으면 닫기 버튼을 눌러주자 닫기 버튼을 눌러주면 자동적으로 컴파일을 수행하여 modbusdaemon.exe 파일을 만들어 준다.

두서없는 글 읽느라고 수고하셨습니다. MODBUS에 대해 더 알고 싶으면 다음을 참고하시기 바랍니다.
Wikipedia

댓글 없음:

댓글 쓰기