본문 바로가기
HW SW 개발

✍️ C#으로 Modbus/RS-485 마스터(Master) 통신 정복하기 (3/3)

by 아이텍 2025. 12. 3.
반응형

 

 

Modbus RTU 데이터 쓰기 및 예외 처리 (Write & Error Handling) ✍️

안녕하세요. 드디어 C# Modbus RTU 마스터 통신 연재의 마지막 시간입니다.

지난 2회차까지 데이터를 읽는(Read) 방법을 완벽히 이해했다면, 이제 장치에 명령을 내려 상태나 설정 값을 변경하는 쓰기(Write) 연산을 구현할 차례입니다. 또한, 실제 통신 환경에서 필수적인 예외 처리 방법을 다루며 연재를 마무리하겠습니다.


1. Modbus 데이터 쓰기 함수 코드 (Function Code)

데이터 쓰기 작업에 사용되는 주요 함수 코드(FC)는 다음과 같습니다. 쓰기 작업은 단일 값(Single)을 쓰느냐, 여러 값(Multiple)을 한 번에 쓰느냐에 따라 나뉩니다.

함수 코드 (FC) 설명 데이터 타입 NModbus 메서드 (예시)
05 (Write Single Coil) 단일 Coil의 상태 (ON/OFF) 쓰기 1비트 WriteSingleCoil
06 (Write Single Register) 단일 Holding Register의 값 쓰기 16비트 WriteSingleRegister
15 (Write Multiple Coils) 여러 Coil의 상태를 한 번에 쓰기 1비트 WriteMultipleCoils
16 (Write Multiple Registers) 여러 Holding Register의 값을 한 번에 쓰기 16비트 WriteMultipleRegisters

2. C# NModbus로 단일 데이터 쓰기 구현 (FC 06)

가장 기본이 되는 단일 Holding Register (FC 06) 값을 쓰는 코드를 구현해 보겠습니다. 이 기능은 장치의 온도 설정값이나 PID 제어 파라미터를 변경할 때 유용합니다.

📝 예제 코드: 단일 Holding Register 값 쓰기

/// <summary>
/// Modbus Holding Register에 단일 값을 쓰는 함수
/// </summary>
/// <param name="slaveId">데이터를 쓸 슬레이브 장치의 ID</param>
/// <param name="registerAddress">값을 쓸 레지스터 주소</param>
/// <param name="value">레지스터에 쓸 16비트 값</param>
public void WriteSingleRegister(byte slaveId, ushort registerAddress, ushort value)
{
    try
    {
        // 1. Modbus 마스터를 이용해 WriteSingleRegister 호출 (FC 06)
        // 응답 값 없이 성공하면 메서드가 완료됩니다.
        master.WriteSingleRegister(slaveId, registerAddress, value);

        Console.WriteLine($"[성공] Slave ID {slaveId}의 레지스터 {registerAddress}에 값 {value} 쓰기 완료.");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"[오류] Modbus 쓰기 실패: {ex.Message}");
    }
}

// 실제 호출 예시:
// ID가 2인 슬레이브 장치의 50번지 레지스터에 3500 이라는 값을 씀.
// WriteSingleRegister(2, 50, 3500);

 

💡 Coil 상태 제어 (FC 05)

장치의 ON/OFF 상태를 제어하는 Coil 쓰기도 매우 간단합니다.

// ID 1의 10번지 Coil을 켜기 (true)
master.WriteSingleCoil(1, 10, true);

// ID 1의 10번지 Coil을 끄기 (false)
master.WriteSingleCoil(1, 10, false);

 

 

3. 안정성을 위한 예외 처리 (Error Handling)

산업용 통신은 노이즈, 케이블 문제, 장치 미응답 등 다양한 이유로 실패할 수 있습니다. 마스터 프로그램의 안정적인 운영을 위해서는 예외 처리(Exception Handling)가 필수적입니다.

NModbus는 통신 과정에서 발생할 수 있는 여러 오류를 .NET 표준 Exception 객체로 던져주기 때문에, 이를 try-catch 블록으로 안전하게 처리해야 합니다.

📝 예제 코드: 통신 오류 처리

using Modbus.Exceptions;
// ... (클래스 내부)

public void RobustReadRegisters(byte slaveId, ushort startAddress, ushort numRegisters)
{
    try
    {
        master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
        // ... (성공 시 로직)
    }
    catch (TimeoutException)
    {
        // 1. 통신 시간 초과 (가장 흔한 오류)
        Console.WriteLine("[Critical] 장치로부터 정해진 시간 내에 응답을 받지 못했습니다. (Timeout)");
    }
    catch (ModbusException mex)
    {
        // 2. 슬레이브가 응답은 했으나, 요청을 처리할 수 없다고 응답한 경우
        // 예: 존재하지 않는 주소를 요청했거나, 읽기 전용 레지스터에 쓰기를 시도한 경우
        Console.WriteLine($"[Modbus Exception] 슬레이브 오류: {mex.Message}");
    }
    catch (System.IO.IOException ioex)
    {
        // 3. 시리얼 포트 자체 문제 (COM 포트가 닫혔거나, 케이블 연결이 끊김)
        Console.WriteLine($"[IO Exception] 시리얼 포트 문제: {ioex.Message}");
    }
    catch (Exception ex)
    {
        // 4. 그 외 예측 불가능한 모든 예외
        Console.WriteLine($"[Unknown Exception] 일반 오류 발생: {ex.Message}");
    }
}

 

 

 

🔍 주요 Modbus 오류 상황

  1. TimeoutException: 마스터가 요청을 보냈지만, 슬레이브 장치가 아예 응답하지 않거나 너무 늦게 응답했을 때 발생합니다. (하드웨어/배선 문제, 슬레이브 장치 전원 OFF 등)
  2. ModbusException: 슬레이브가 응답은 했으나, 응답 패킷에 **예외 코드(Exception Code)**를 포함했을 때 발생합니다. 이는 보통 잘못된 주소를 요청하거나, 함수 코드를 지원하지 않을 때 나타납니다.

 

4. 마무리 및 다음 단계

이로써 C# NModbus 라이브러리를 사용한 Modbus RTU 마스터 통신 연재를 모두 마쳤습니다.

우리는 3회에 걸쳐 통신의 기본 원리부터 시작해, 데이터 읽기와 쓰기, 그리고 안정적인 운영을 위한 예외 처리까지 구현해 보았습니다.

📌 요약 및 다음 단계

회차 주요 학습 내용
1회차 Modbus/RS-485 기본 개념, NModbus 환경 설정, Serial Port 초기화.
2회차 Modbus 4가지 데이터 모델 이해, 데이터 읽기 (FC 03/04), 16비트 $\rightarrow$ 32비트 데이터 변환.
3회차 데이터 쓰기 (FC 05/06/15/16), try-catch를 이용한 통신 예외 처리.

이 코드를 바탕으로 여러분의 산업용 장치와 통신을 시작해 보세요. 실제 필드 장치와 연결하여 발생할 수 있는 통신 문제를 해결해 나가는 것이 이 분야의 숙련도를 높이는 핵심입니다.

 

 

 

🚀 C#으로 Modbus/RS-485 마스터(Master) 통신 정복하기

Modbus와 RS-485, 그리고 C# 환경 준비 ⚙️ 안녕하세요, 산업 자동화와 데이터 수집에 관심 있는 C# 개발자 여러분!이번 연재에서는 C# .NET 환경에서 Modbus RTU 프로토콜을 사용하여 RS-485 통신 기반의

moneygeneration.tistory.com

 

 

💾 C#으로 Modbus/RS-485 마스터(Master) 통신 정복하기 (2/3)

Modbus RTU 데이터 읽기 (Read Operations) 💾안녕하세요. 지난 1회차에서는 Modbus RTU와 RS-485의 기본을 알아보고, NModbus 라이브러리를 설치하여 마스터 통신 환경을 준비했습니다.이번 2회차에서는 실제

moneygeneration.tistory.com

 

반응형