Modbus TCP/RTU 드라이버 가이드
Caffeine Framework v2.0.4에서 제공하는 Caffeine.Drivers.ModbusTcp 및 Caffeine.Drivers.ModbusRtu 패키지 사용 가이드입니다.
개요
Modbus는 산업 자동화에서 가장 널리 사용되는 프로토콜입니다. v2.0.4부터 Caffeine은 FluentModbus 기반의 공식 드라이버 패키지를 제공합니다.
학습 시간: 30분
난이도: ⭐⭐ 중급
NuGet: NEXCODE.Caffeine.Drivers.ModbusTcp, NEXCODE.Caffeine.Drivers.ModbusRtu
Modbus 프로토콜 이해
Function Codes
| Code | 이름 | 주소 접두어 | 설명 |
|---|---|---|---|
| 03 | Read Holding Registers | HR: | 레지스터 읽기 (AO) |
| 01 | Read Coils | C: | 코일 상태 읽기 (DO) |
| 02 | Read Discrete Inputs | DI: | 입력 상태 읽기 |
| 04 | Read Input Registers | IR: | 입력 레지스터 읽기 (AI) |
| 16 | Write Multiple Registers | HR: | 레지스터 쓰기 |
주소 형식 (ModbusAddress)
Caffeine Modbus 드라이버는 "FC:주소번호" 형식의 주소 문자열을 사용합니다:
HR:100 → Holding Register 100번
C:0 → Coil 0번
DI:5 → Discrete Input 5번
IR:200 → Input Register 200번
100 → (접두어 없음) Holding Register 100번 (기본값)
Modbus TCP 드라이버
Caffeine.Drivers.ModbusTcp 패키지를 사용하여 Modbus TCP 장치에 연결합니다.
DriverDefinition 설정
DriverDefinition.Options 딕셔너리에서 연결 설정을 읽습니다:
| 옵션 키 | 타입 | 기본값 | 설명 |
|---|---|---|---|
IpAddress | string | — | 장비 IP 주소 (필수) |
Port | int | 502 | Modbus TCP 포트 |
UnitId | byte | 1 | Modbus Unit ID (슬레이브 주소) |
사용 예시
using Caffeine.Core.Abstractions.Drivers;
using Caffeine.Drivers.ModbusTcp;
using Microsoft.Extensions.Logging;
// DriverDefinition 구성
var def = new DriverDefinition
{
Identifier = "modbus-tcp-01",
DriverType = "ModbusTcp",
Options = new Dictionary<string, string>
{
["IpAddress"] = "192.168.1.100",
["Port"] = "502",
["UnitId"] = "1"
}
};
// 드라이버 생성 및 초기화
await using var driver = new ModbusTcpDriver(def, logger);
await driver.InitializeAsync();
// 레지스터 읽기 (HR:100 → Holding Register 100번, 4바이트 = short 2개)
var buffer = new byte[4];
await driver.ReadBytesAsync("HR:100", buffer, CancellationToken.None);
// 레지스터 쓰기
await driver.WriteTagAsync("HR:100", (short)1234, CancellationToken.None);
IDriverCapabilities 확인
if (driver is IDriverCapabilities caps)
{
// ["ModbusTCP"]
Console.WriteLine(string.Join(", ", caps.SupportedProtocols));
// 100 (초당 최대 100 메시지)
Console.WriteLine(caps.MaxMessagesPerSecond);
// true
Console.WriteLine(caps.SupportsBidirectional);
}
Modbus RTU 드라이버
Caffeine.Drivers.ModbusRtu 패키지를 사용하여 RS-485 시리얼 Modbus RTU 장치에 연결합니다.
DriverDefinition 설정
| 옵션 키 | 타입 | 기본값 | 설명 |
|---|---|---|---|
PortName | string | COM1 | 시리얼 포트 이름 (예: COM3, /dev/ttyUSB0) |
BaudRate | int | 9600 | 통신 속도 |
SlaveAddress | byte | 1 | Modbus 슬레이브 주소 |
Parity | string | None | 패리티 (None / Even / Odd) |
StopBits | string | One | 스톱 비트 (None / One / Two / OnePointFive) |
사용 예시
using Caffeine.Drivers.ModbusRtu;
var def = new DriverDefinition
{
Identifier = "rtu-01",
DriverType = "ModbusRtu",
Options = new Dictionary<string, string>
{
["PortName"] = "COM3",
["BaudRate"] = "9600",
["SlaveAddress"] = "1",
["Parity"] = "None",
["StopBits"] = "One"
}
};
await using var driver = new ModbusRtuDriver(def, logger);
await driver.InitializeAsync(); // SerialPort 연결
// 레지스터 읽기
var buffer = new byte[4];
await driver.ReadBytesAsync("HR:100", buffer, CancellationToken.None);
MaxMessagesPerSecond = 20: RS-485 시리얼 대역폭 제한으로 TCP(100)보다 낮게 설정됩니다.
Bridge.Host 설정
driver_settings.json에 Modbus 드라이버를 등록합니다:
{
"Drivers": [
{
"Identifier": "modbus-tcp-01",
"DriverType": "ModbusTcp",
"Options": {
"IpAddress": "192.168.1.100",
"Port": "502",
"UnitId": "1"
}
},
{
"Identifier": "modbus-rtu-01",
"DriverType": "ModbusRtu",
"Options": {
"PortName": "COM3",
"BaudRate": "9600",
"SlaveAddress": "1"
}
}
]
}
지원 데이터 타입 (WriteTagAsync)
WriteTagAsync는 다음 타입의 값을 레지스터에 기록할 수 있습니다:
| .NET 타입 | 크기 | 설명 |
|---|---|---|
short / ushort | 2 bytes | 단일 레지스터 |
int / uint | 4 bytes | 32비트 값 |
float | 4 bytes | 부동소수 |
double | 8 bytes | 64비트 부동소수 |
bool | 2 bytes | 0 또는 1 |
byte[] | N bytes | 원시 바이트 |
테스트
단위 테스트 패턴
[Fact]
public void ModbusAddress_Should_ParseHoldingRegister()
{
var addr = ModbusAddress.Parse("HR:100");
Assert.Equal(ModbusRegisterType.HoldingRegister, addr.RegisterType);
Assert.Equal(100, addr.Address);
}
[Fact]
public void ModbusTcpDriver_Should_HaveCorrectCapabilities()
{
var def = new DriverDefinition
{
Identifier = "test",
DriverType = "ModbusTcp",
Options = new Dictionary<string, string> { ["IpAddress"] = "127.0.0.1" }
};
var driver = new ModbusTcpDriver(def, NullLogger<ModbusTcpDriver>.Instance);
var caps = (IDriverCapabilities)driver;
Assert.Contains("ModbusTCP", caps.SupportedProtocols);
Assert.Equal(100, caps.MaxMessagesPerSecond);
Assert.True(caps.SupportsBidirectional);
}
Modbus 시뮬레이터
실제 장비 없이 테스트하려면 다음 도구를 사용합니다:
- diagslave (Linux/macOS/Windows)
- ModRSsim2 (Windows GUI)
- ModbusPal (Java 기반 크로스 플랫폼)
# diagslave — Modbus TCP 서버 (포트 502)
diagslave -m tcp -p 502
# diagslave — Modbus RTU (COM 포트 시뮬레이션)
diagslave -m rtu /dev/ttyUSB0
관련 문서
작성일: 2026-02-28 버전: 2.0.4 (FluentModbus 기반으로 전면 재작성)