사용자 도구

사이트 도구

English

comfilepi:nmodbus4_k:index

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
comfilepi:nmodbus4_k:index [2017/11/25 02:03]
Comfile Technology [- Example 2]
comfilepi:nmodbus4_k:index [2020/02/26 01:38] (현재)
Comfile Technology
줄 1: 줄 1:
 +====== NModbus4 사용법 ======
 +
 +산업현장에서 많이 사용하고 있는 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 }}  ^ {{ :​comfilepi:​nmodbus4_k:​msb_connection.png }}  ^
 +
 +※//PLC는 컴파일테크놀로지의 [[http://​www.comfile.co.kr/​shop/​goods/​goods_view.php?​goodsno=60&​category=005001|MSB612RA-DC]] 제품입니다. //
 +
 +
 +=====NModbus4 라이브러리 추가 =====
 +
 +NModbus4 라이브러리를 Visual Studio 2017에 추가하는 방법에 대해 알아보겠습니다.
 +
 +  * 1. 프로젝트를 만든 후 우측의 **"​솔루션 탐색기"​**의 **"​프로젝트(ModbusExample)"​**에 우클릭으로 **"​NuGet 패키지 관리(N).."​**를 선택 합니다.
 +{{ :​comfilepi:​nmodbus4_k:​nmodbus_1_a.png |}}
 +  * 2. **"​찾아보기"​** 선택 -> 검색창에 **"​NModbus"​** 검색 -> **"​NModbus4"​** 선택 -> **"​설치"​** 클릭
 +{{ :​comfilepi:​nmodbus4_k:​nmodbus_2_a.png |}}
 +  * 3. 출력창에서 NModbus4 라이브러리 설치 상태를 확인 할 수 있습니다.
 +{{ :​comfilepi:​nmodbus4_k:​nmodbus_3_a.png |}}
 +
 +===== Modbus 프로그래밍 =====
 +NModbus4의 Function(함수)와 Serial Port설정에 대해 알아 보겠습니다. ​
 +  * 1. Serial Port설정 : 데스크탑 PC의 Serial Port와 ComfilePi의 Serial Port는 다릅니다. 프로젝트 코드에 아래와 같이 SerialPort를 설정 해야합니다.
 +  * ※ ComfilePi의 **COM0**는 **"/​dev/​serial0"​**,​ **COM1**은 **"/​dev/​serial1"​**로 설정합니다.
 +<code xbasic>
 +string portName = Environment.OSVersion.Platform == PlatformID.Win32NT ? "​COM0"​ : "/​dev/​serial0";​
 +SerialPort port = new SerialPort(portName,​ 115200);
 +port.ReadTimeout = 100;
 +port.WriteTimeout = 100;
 +port.Open();​
 +</​code>​
 +  * 2. ComfilePi를 Master로 사용시 PLC의 상태를 읽어오고 제어할 수 있는 함수입니다.
 +  * ※ ModbusRTU Master는 **ModbusSerialMaster** 클래스를 사용합니다.
 +<code xbasic>
 +bool[] ReadCoils(byte slaveAddress,​ ushort startAddress,​ ushort numberOfPoints);​
 + 
 +ushort[] ReadHoldingRegisters(byte slaveAddress,​ ushort startAddress,​ ushort numberOfPoints);​
 + 
 +ushort[] ReadInputRegisters(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);
 + 
 +void WriteMultipleCoils(byte slaveAddress,​ ushort startAddress,​ bool[] data);
 + 
 +void WriteMultipleRegisters(byte slaveAddress,​ ushort startAddress,​ ushort[] data);
 + 
 +void WriteSingleCoil(byte slaveAddress,​ ushort coilAddress,​ bool value);
 + 
 +void WriteSingleRegister(byte slaveAddress,​ ushort registerAddress,​ ushort value);
 +
 +</​code>​
 +  * 3. NModbus4 라이브러를 이용해 만든 실행파일(.exe)을 ComfilePi에서 사용하려면 **실행파일(.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 |}}
 +<code xbasic>
 +using Modbus.Device;​
 +using System;
 +using System.IO.Ports;​
 +using System.Windows.Forms;​
 + 
 +namespace SimpleModbusExample
 +{
 +    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>​
 +
 +\\
 +
 +====- Example 2====
 +소스코드 다운로드 ☞ {{ :​comfilepi:​nmodbus4_k:​modbus_example.zip |}}
 +
 +{{ :​comfilepi:​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>​
 +
 +[[comfilepi:​index#​.NET_(닷넷)_개발환경|이전 페이지로 이동]]