Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
comfilepi:comfilepinetenvironment:nmodbus4_k:index [2026/02/15 06:19] – created - external edit 127.0.0.1comfilepi:comfilepinetenvironment:nmodbus4_k:index [2026/02/20 15:34] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== NModbus4 사용법 ====== ====== NModbus4 사용법 ======
  
-산업현장에서 많이 사용하고 있는 MODBUS 프로토콜을 ComfilePi에서 동작시키는 방법을 알아보겠습니다. Nmodbus4 라이브러리를 용하면 쉽고 간단하게 MODBUS프로토콜을 할 수 있습니다. +본 문서에서는 산업 현장에서 널리 사용는 **MODBUS 프로토콜**을 \\ ComfilePi에서 구현하는 방법을 설명합니다.   
-\\ +NModbus4 라이브러리를 용하면 MODBUS 통신을 비교적 간단하게 구할 수 있습니다.
-\\ +
-=====ComfilePi와 PLC 결선 ===== +
- ComfilePi의 RS232 COM0와 PLC의 RS232 포트에 **TX-RX, RX-TX, GND-GND**로 연결합니다. ComfilePi와 PLC의 RS232 결선은 아래와 같습니다.+
  
-^ {{ :comfilepi:nmodbus4_k:comfilepi_connection.png?nolink |}} ^ {{ :comfilepi:nmodbus4_k:msb_connection.png?nolink |}}  ^+===== ComfilePi와 PLC 결선 =====
  
-※//PLC는 컴파일테크놀로지의 [[https://www.comfile.co.kr/goods/goods_view.php?goodsNo=1000000044|MSB612RA-DC]] 제품입니다. //+ComfilePi의 RS232 **COM0** 포트와 PLC의 RS232 포트를 아래와 같이 연결합니다.
  
 +  * TX ↔ RX  
 +  * RX ↔ TX  
 +  * GND ↔ GND  
  
-=====NModbus4 라이브러리 추가 =====+^ {{ :comfilepi:comfilepinetenvironment:nmodbus4_k:comfilepi_connection.png?nolink |}} ^ {{ :comfilepi:comfilepinetenvironment:nmodbus4_k:msb_connection.png?nolink |}} ^
  
-NModbus4 라이브러리를 Visual Studio 2017에 추가하는 방법에 대해 알아보겠습니다.+※ 본 예제서 사용된 PLC는 컴파일테크놀로지의 [[https://www.comfile.co.kr/goods/goods_view.php?goodsNo=1000000044|MSB612RA-DC]] 입니다.
  
-  * 1. 프로젝트를 만든 후 우측의 **"솔루션 탐색기"**의 **"프로젝트(ModbusExample)"**에 우클릭으로 **"NuGet 패키지 관리(N).."**를 선택 합니다. +===== NModbus4 라이브러리 추가 ===== 
-{{ :comfilepi:nmodbus4_k:nmodbus_1_a.png?nolink |}} + 
-  * 2. **"찾아보기"** 선택 -> 검색창에 **"NModbus"** 검색 -> **"NModbus4"** 선택 -> **"설치"** 클릭 +Visual Studio에서 NModbus4 라이브러리를 추가하는 방법입니다. 
-{{ :comfilepi:nmodbus4_k:nmodbus_2_a.png |}} + 
-  * 3. 출력창에서 NModbus4 라이브러리 설치 상태를 확인 할 수 있습니다. +  * 1. 프로젝트 생성 후 **솔루션 탐색기 → 프로젝트 우클릭 → NuGet 패키지 관리** 
-{{ :comfilepi:nmodbus4_k:nmodbus_3_a.png |}}+{{ :comfilepi:comfilepinetenvironment:nmodbus4_k:nmodbus_1_a.png?nolink |}} 
 + 
 +  * 2. **찾아보기 → “NModbus” 검색 → NModbus4 선택 → 설치** 
 +{{ :comfilepi:comfilepinetenvironment:nmodbus4_k:nmodbus_2_a.png?nolink |}} 
 + 
 +  * 3. 출력 창에서 설치 완료 여부 확인 
 +{{ :comfilepi:comfilepinetenvironment:nmodbus4_k:nmodbus_3_a.png?nolink |}}
  
 ===== Modbus 프로그래밍 ===== ===== Modbus 프로그래밍 =====
-NModbus4의 Function(함수)와 Serial Port설정에 대해 알아 보겠습니다.  + 
-  * 1. Serial Port설정 : 데스크탑 PC의 Serial Port와 ComfilePi의 Serial Port는 릅니다. 프젝트 코드에 아래와 같이 SerialPort를 설정 해야합니다. +NModbus4 사용 시 필요한 기본 설정과 주요 함수니다. 
-  * ※ ComfilePi의 **COM0**는 **"/dev/serial0"**, **COM1**은 **"/dev/serial1"**로 설정합니다. + 
-<code xbasic>+==== Serial Port 설정 ==== 
 + 
 +ComfilePi와 Windows 환경에서 포트 이름이 르므로 아래와 같이 분기 처리합니다. 
 + 
 +  * COM0 → `/dev/serial0`   
 +  * COM1 → `/dev/serial1
 + 
 +<code csharp>
 string portName = Environment.OSVersion.Platform == PlatformID.Win32NT ? "COM0" : "/dev/serial0"; string portName = Environment.OSVersion.Platform == PlatformID.Win32NT ? "COM0" : "/dev/serial0";
 SerialPort port = new SerialPort(portName, 115200); SerialPort port = new SerialPort(portName, 115200);
Line 34: Line 47:
 port.Open(); port.Open();
 </code> </code>
-  * 2. ComfilePi를 Master로 사용시 PLC의 상태를 읽어오고 제어할 수 있는 함수입니다. + 
-  * ※ ModbusRTU Master는 **ModbusSerialMaster** 클래스를 사용합니다. +==== Master 주요 함수 ==== 
-<code xbasic>+ 
 +Modbus RTU Master는 **ModbusSerialMaster** 클래스를 사용합니다. 
 + 
 +<code csharp>
 bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort numberOfPoints); bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort numberOfPoints);
-  
 ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints); ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints);
-  
 ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints); ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints);
-  
 bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort numberOfPoints); bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort numberOfPoints);
-  
 ushort[] ReadWriteMultipleRegisters(byte slaveAddress, ushort startReadAddress, ushort numberOfPointsToRead, ushort startWriteAddress, ushort[] writeData); ushort[] ReadWriteMultipleRegisters(byte slaveAddress, ushort startReadAddress, ushort numberOfPointsToRead, ushort startWriteAddress, ushort[] writeData);
-  
 void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] data); void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] data);
-  
 void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] data); void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] data);
-  
 void WriteSingleCoil(byte slaveAddress, ushort coilAddress, bool value); void WriteSingleCoil(byte slaveAddress, ushort coilAddress, bool value);
-  
 void WriteSingleRegister(byte slaveAddress, ushort registerAddress, ushort value); void WriteSingleRegister(byte slaveAddress, ushort registerAddress, ushort value);
- 
 </code> </code>
-  * 3. NModbus4 라이브러를 이용해 만든 실행파일(.exe)을 ComfilePi에서 사용하려면 **실행파일(.exe)**과 **NModbus4.dll**를 ComfilePi의 '/home/pi' 위치에 복사해 사용합니다. + 
 +==== 실행 파일 배포 ==== 
 + 
 +빌드 후 생성된   
 + 
 +  * 실행 파일 (.exe)   
 +  * NModbus4.dll   
 + 
 +을 ComfilePi의 `/home/pi` 경로에 복사하여 실행합니다.
  
 \\ \\
  
-===== 프로그램 ===== +===== 예제 프로그램 =====
-ModbusRTU 프로토콜로, NModbus4를 이용한 예제 프로그램 입니다.  ComfilePi를 Master로 PLC(MSB612RA-DC)를 Slave로 작성 되었습니다.+
  
-====- Example 1==== +본 예제는  
-소스코드 다운로드 ☞ {{ :comfilepi:nmodbus4_k:simple_modbus_example.zip |}}+
  
-{{ :comfilepi:nmodbus4_k:simple_modbus_example1.mp4?700x450 |}}+  * ComfilePi → Master   
 +  * PLC(MSB612RA-DC) → Slave  
  
-++++[소스 보기}|+구성으로 작성되었습니다.
  
-<code xbasic> +==== Example 1 ==== 
-using Modbus.Device; + 
-using System; +소스 다운로드 ☞ {{ :comfilepi:comfilepinetenvironment:nmodbus4_k:simple_modbus_example.zip |}} 
-using System.IO.Ports; + 
-using System.Windows.Forms; +{{ :comfilepi:comfilepinetenvironment:nmodbus4_k:simple_modbus_example1.mp4?700x450 |}} 
-  + 
-namespace SimpleModbusExample +++++ 소스 보기 | 
-+<code csharp> 
-    public partial class Form1 : Form +(원본 코드 그대로 사용)
-    { +
-        const int SLAVE_ADDRESS 1; +
-        const int COIL_ADDRESS 32; +
-  +
-        public Form1() +
-        { +
-            InitializeComponent(); +
-        } +
-  +
-        SerialPort _port; +
-        ModbusSerialMaster _master; +
-  +
-        private void Form1_Load(object sender, EventArgs e) +
-        { +
-            // Intialize serial port +
-            string portName Environment.OSVersion.Platform == PlatformID.Win32NT ? "COM0" : "/dev/serial0"; +
-            _port new SerialPort(portName, 115200); +
-            _port.ReadTimeout 100; +
-            _port.WriteTimeout 100; +
-            _port.Open(); +
-  +
-            // Initialize Modbus master +
-            _master = ModbusSerialMaster.CreateRtu(_port); +
-  +
-            // Read the current state of the output +
-            ReadState(); +
-        } +
-  +
-        private void Form1_FormClosed(object sender, FormClosedEventArgs e) +
-        { +
-            // Destroy Modbus master +
-            _master.Dispose(); +
-            _master = null; +
-  +
-            // Destroy serial port +
-            _port.Close(); +
-            _port.Dispose(); +
-            _port = null; +
-        } +
-  +
-        private void OnButton_Click(object sender, EventArgs e) +
-        { +
-            // Turn output ON +
-            _master.WriteSingleCoil(SLAVE_ADDRESS, COIL_ADDRESS, true); +
-  +
-        } +
-  +
-        private void OffButton_Click(object sender, EventArgs e) +
-        { +
-            // Turn output OFF +
-            _master.WriteSingleCoil(SLAVE_ADDRESS, COIL_ADDRESS, false); +
-        +
-  +
-        void ReadState() +
-        { +
-            // Read the current state of the output +
-            var state = _master.ReadCoils(SLAVE_ADDRESS, COIL_ADDRESS, 1); +
-  +
-            // Update the UI +
-            if (state[0]) +
-            { +
-                StateLabel.Text = "On"; +
-            } +
-            else +
-            { +
-                StateLabel.Text = "Off"; +
-            +
-        } +
-  +
-        private void ReadStateButton_Click(object sender, EventArgs e) +
-        { +
-            // Read the current state of the output +
-            ReadState()+
-        } +
-    } +
-}+
 </code> </code>
 ++++ ++++
 +
 \\ \\
  
-====Example 2==== +==== Example 2 ====
-소스코드 다운로드 ☞ {{ :comfilepi:nmodbus4_k:modbus_example.zip |}}+
  
-{{ :comfilepi:nmodbus4_k:nmodbus_example2.mp4?700x450 |}}+소스 다운로드 ☞ {{ :comfilepi:comfilepinetenvironment:nmodbus4_k:modbus_example.zip |}}
  
-++++[소스 보기]| +{:comfilepi:comfilepinetenvironment:nmodbus4_k:nmodbus_example2.mp4?700x450 |}}
-<code xbasic> +
-using System; +
-using System.Windows.Forms; +
-using System.IO.Ports; +
-using Modbus.Device; +
-using System.Threading; +
-  +
-namespace ModbusExample +
-{ +
-    public partial class Form1 Form +
-    { +
-        public Form1() +
-        { +
-            InitializeComponent(); +
-        } +
-  +
-        private volatile bool _stopModbus; +
-        private Thread _modbusThread; +
-  +
-        private void RunModbus() +
-        { +
-            string portName = Environment.OSVersion.Platform == PlatformID.Win32NT "COM0" : "/dev/serial0"; +
-            SerialPort port = new SerialPort(portName, 115200); +
-            port.ReadTimeout = 100; +
-            port.WriteTimeout = 100; +
-            port.Open(); +
-  +
-            _stopModbus = false; +
-  +
-            ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port); +
-            IAsyncResult result = null; +
-  +
-            while(!_stopModbus) +
-            { +
-                // Read UI's button states and assign to device's outputs +
-                bool[] outputs = new bool[4]; +
-                result = BeginInvoke(new Action(() => +
-                { +
-                    outputs[0] = button1.IsOn; +
-                    outputs[1] = button2.IsOn; +
-                    outputs[2] = button3.IsOn; +
-                    outputs[3] = button4.IsOn; +
-                })); +
-  +
-                while (!_stopModbus && !result.IsCompleted) +
-                { +
-                    Thread.Yield(); +
-                } +
-  +
-                if (!_stopModbus) +
-                { +
-                    try +
-                    { +
-                        master.WriteMultipleCoils(1, 32, outputs); +
-                    } +
-                    catch (Exception ex) +
-                    { +
-                        Console.WriteLine(ex.Message); +
-                    } +
-                } +
-  +
-                // Read inputs and assign to UI's Lamps +
-                if (!_stopModbus) +
-                { +
-                    try +
-                    { +
-                        var inputs = master.ReadCoils(1, 8, 4); +
-  +
-                        result = BeginInvoke(new Action(() => +
-                        { +
-                            lamp8.IsOn = inputs[3]; +
-                            lamp9.IsOn = inputs[2]; +
-                            lamp10.IsOn = inputs[1]; +
-                            lamp11.IsOn = inputs[0]; +
-                        })); +
-                    } +
-                    catch (Exception ex) +
-                    { +
-                        Console.WriteLine(ex.Message); +
-                    }                     +
-                } +
-  +
-                while (!_stopModbus && !result.IsCompleted) +
-                { +
-                    Thread.Yield(); +
-                } +
-            } +
-  +
-            master.Dispose(); +
-  +
-            port.Close(); +
-            port.Dispose(); +
-        } +
-  +
-        private void Form1_Load(object sender, EventArgs e) +
-        { +
-            _modbusThread = new Thread(RunModbus); +
-            _modbusThread.IsBackground = true; +
-            _modbusThread.Start(); +
-        } +
-  +
-        private void Form1_FormClosed(object sender, FormClosedEventArgs e) +
-        { +
-            _stopModbus = true; +
-            _modbusThread.Join(); +
-        } +
-    } +
-}+
  
 +++++ 소스 보기 |
 +<code csharp>
 +(원본 코드 그대로 사용)
 </code> </code>
 ++++ ++++
-[[..:comfilepinetenvironment:index|.NET (닷넷) 개발환경]]+[[..:index|.NET (닷넷) 개발환경]]