C# NET 을 위한 Modbus Library 에 대한 간단한 고찰

2021. 8. 5. 09:29·일상다반사/개발
이 글에서 나오는 소스코드는 읽는이의 이해를 돕기 위해 필자가 직접 작성한 "손코딩" 이므로, 동작을 보장하지 않습니다.
net452 를 대상으로 하는 SerialPort(RTU) 를 통한 모드버스 통신을 다음과 같은 라이브러리로 구현을 진행하였습니다.

EasyModbus

EasyModbus 는 간결하게 코드를 작성할 수 있도록 도와주고 있습니다.

public class Modbus_Example {
    public Modbus_Example() {
        try {
            ModbusClient modbusClient = new ModbusClient("COM1");
            modbusClient.UnitIdentifier = 2;
            modbusClient.Baudrate = 9600;
            modbusClient.Parity = System.IO.Ports.Parity.None;
            modbusClient.StopBits = System.IO.Ports.StopBits.One;
            modbusClient.ConnectionTimeout = 500;
            modbusClient.Connect();

            if (modbusClient.Connected) {
                int[] response_data = modbusClient.ReadHoldingRegisters(0, 0x24);
                // 관련 동작 ~~
            } else {
            	// 관련 동작 ~~
            }
        } catch (Exception ex) {
            // 예외처리
        }
    }
}

 

대체적으로 이런 느낌입니다.

 

이 라이브러리를 가지고 2개 이상의 SerialPort, 2개 이상의 SlaveAddress(ID) 를 통신해야 했었는데,

한번 ReadHoldingRegisters 를 사용한 뒤에 다른 장치의 데이터를 가져오기 위해 finally 에 modbusClient.Disconnect() 를 항상 사용하여 구현을 진행했었습니다. (좀 모시깽 함)

 

그리고 Connect() 를 시도할 때 발생하는 것인지 new ModbusClient() 를 시도할 때 발생하는 것인지

라이브러리를 사용할 때마다 Output 창에 4줄 정도 되는 문구가 나타나, 상당히 로그를 보기 까다롭더라구요..

 

NModbus4

Nuget Package Manager

 

설명에서 보다시피 NModbus 는 RTU 를 지원하지 않아서 사용할 수 없었습니다.

NModbus4 를 이용하여 개발한 예제

public class Modbus_Example {
    public Modbus_Example() {
    	serialPorts = new SerialPort[2];
        modbusSerialMasters = new ModbusSerialMaster[2];
        
        try {
            for (int i = 0; i < 2; i++) {
              try {
                serialPorts[i] = new SerialPort(COMM[i], 9600);
                serialPorts[i].Parity = Parity.None;
                serialPorts[i].StopBits = StopBits.One;
                serialPorts[i].ReadTimeout = 100;
                serialPorts[i].WriteTimeout = 100;
                serialPorts[i].Open();

                modbusSerialMasters[i] = ModbusSerialMaster.CreateRtu(serialPorts[i]);
              } catch (Exception ex) {
                  // 예외처리
              }
            }

            if (modbusClient.Connected) {
                int[] response_data = modbusClient.ReadHoldingRegisters(0, 0x24);
                // 관련 동작 ~~
            } else {
                // 관련 동작 ~~
            }
        } catch (Exception ex) {
            // 예외처리
        }
    }
    
    public void run() {
    	while (true) {
        	int currentPortIndex = ~~~
            if (serialPorts[currentPortIndex].IsOpen) {
                try {
                    ushort[] response_data = modbusSerialMasters[currentPortIndex].ReadHoldingRegisters(#SlaveAddress#, 0, 19);
                    // 관련 동작 ~~
                } catch (Exception ex) {
                    // 예외처리
                }
            } else {
                serialPorts[currentPortIndex].Open();
                if (serialPorts[currentPortIndex].IsOpen)
              	    modbusSerialMasters[currentPortIndex] = ModbusSerialMaster.CreateRtu(serialPorts[currentPortIndex]);
            }
        }
        Thread.Sleep(500);
    }
    
    protected SerialPort[] serialPorts;
    protected ModbusSerialMaster[] modbusSerialMasters;
}

 

대략적인 차이는 다음과 같습니다.

  • NModbus4 는 RTU 통신에서 System.IO.Ports 의 SerialPort 를 사용합니다.
  • NModbus4 는 ModbusSerialMaster.CreateRtu(System.IO.Ports.SerialPort) 메서드에서 SerialPort 인자를 요구하며 ModbusSerialMaster 로 리턴합니다.
  • NModbus4 는 ReadHoldingRegister() 메서드에서 SlaveAddress 를 지정할 수 있습니다.
    EasyModbus 는 new ModbusClient() 에서 SlaveAddress 를 지정했었습니다.
    이제 따로 Disconnect 할 필요 없이 한 SerialPort 에서 여러 SlaveAddress 에 있는 데이터를 자유롭게 요청할 수 있게 되었습니다.
  • EasyModbus 는 int[] 로, NModbus4 는 ushort[] 로 리턴합니다.

필자는 처음에 EasyModbus 를 이용해 온도센서 통신을 구현하였었는데요,

이후에 다른 모듈과 통신하기 위해 EasyModbus 를 이용하여 테스트 중에 문제가 발생했었고

해당 문제는 "값이 잘 들어오다가 갑자기 마이너스 값이 들어오는 문제" 였습니다.

 

확인 끝에 unsigned 를 사용해야 한다는 것을 알게 되었고, 해당 라이브러리는 사용이 불가능했습니다.

그래서 다른 라이브러리를 모색하던 중 NModbus4 를 알게 되었고 EasyModbus 보다 더욱 잘 활용하고 있습니다.

 

사실 맨 처음 Modbus Library 를 찾을 때에는 NModbus4 를 먼저 찾았었으나

EasyModbus 를 선택한 이유는 예제와 공식 사이트 등에서 자료가 많았기 때문이었던 것 같습니다 :)

 

위에서 언급된 각 라이브러리에 대한 Github 주소목록

EasyModBus : https://github.com/rossmann-engineering/EasyModbusTCP.NET

NModbus4 : https://github.com/NModbus4/NModbus4

NModbus : https://github.com/NModbus/NModbus

반응형
저작자표시 비영리 (새창열림)
'일상다반사/개발' 카테고리의 다른 글
  • 갤럭시 S22+ 삼성단독 컬러 사전구매가 너무 하고 싶었던 개발자의 개발
  • 정규 표현식(RegEx/RegExp) 를 쉽고 빠르게 배울 수 있는 사이트
  • Simplify Conditional Expression for return to bool
  • 첫 PR merge 완료 !
Kua
Kua
정보 공유, 개인 정리 공간 입니다.
  • Kua
    Kua's Miscellaneous
    Kua
    • 분류 전체보기 (185)
      • 대문 (2)
      • Tips (25)
        • Chrome (2)
        • Windows (4)
        • IDE (3)
        • 기타 (16)
      • CodingTest (44)
      • Language (20)
        • PHP (5)
        • C# (7)
        • Java (1)
        • Kotlin (7)
      • Framework & Runtime (16)
        • SpringBoot (12)
        • Node.js (2)
        • Vue.js (1)
        • Gradle (1)
      • DevOps (13)
        • Linux (1)
        • Docker (4)
        • Kubernetes (2)
        • Apache Kafka (1)
        • AWS (1)
      • 일상다반사 (53)
        • 도서 (1)
        • 개발 (8)
        • 후기 - IT (7)
        • 후기 - 일상 (13)
        • 차가리 (4)
        • 방송통신대학교 (4)
        • 음식 (2)
      • Games (12)
        • Minecraft (7)
        • VR (2)
        • 그외 (3)
  • 최근 글

  • 인기 글

  • 태그

    Plugin
    Windows
    Kotlin
    갤럭시
    codingtest
    백준
    Algorithm
    c#
    bronze1
    error
    Spring Boot
    bronze2
    알고리즘
    후기
    Silver5
    github
    spring
    java
    minecraft
    코딩테스트
  • 전체
    오늘
    어제
  • hELLO· Designed By정상우.v4.10.0
Kua
C# NET 을 위한 Modbus Library 에 대한 간단한 고찰
상단으로

티스토리툴바