사용자 도구

사이트 도구

English

cuwin:cuwin_modbus:index

CUWIN에서 MODBUS 사용하는 방법

모드버스 프로토콜을 이용해서 CUWIN과 CUBLOC을 서로 연결하는 방법에 대해서 알아보겠습니다. 아래 그림처럼 CUWIN은 모드버스의 마스터가 되고, CUBLOC은 모드버스 SLAVE가 됩니다.

큐블록 준비

일체형 모듈인 MSB612RA-DC을 사용하였습니다.

MSB LOGIC 프로그램을 이용해서 다음과 같이 셋팅후 다운로드하시면, CUBLOC쪽은 MODBUS SLAVE로 실행할 수 있는 모든 준비를 마치게 됩니다.

레더로직은 아무것도 없이 그냥 END명령 하나만 넣으시면 됩니다.

통신선 연결

CUWIN과 CUBLOC을 연결하는 방법입니다. CUWIN은 CWV-070BR을 사용했습니다.

CUWIN의 RS2323C COM1과 MSB의 RS232C 채널1을 다음과 같이 서로 연결합니다.

CUWIN 프로그래밍

MODBUS 프로토콜을 C#으로 일일이 구현하기에는 매우 번거로우므로, 공개된 라이브러리를 활용해서 MODBUS를 구현하도록 하겠습니다. google에서 NMODBUS를 검색하거나, https://code.google.com/p/nmodbus/ 로 이동하십시오.

보시는 것처럼 MODBUS 프로토콜을 다양한 언어환경에서 구현할 수 있도록 라이브러리를 공개하고 있는 사이트입니다.

다운로드탭을 누른뒤, 가장 최근버젼의 바이너리 파일을 다운로드 받으세요. 받은 파일의 압축을 풀고난뒤, netcf 폴더까지 이동을 하시면 아래처럼 4개의 파일이 보입니다. (netcf 는 .Net Compact Framework 라는 뜻입니다.)

이 4개 파일을 비주얼스튜디오의 솔루션탐색기에서 아래 화면처럼 "추가"하십시오.

참조에 해당 파일이 추가된 것을 확인할 수 있습니다.

C# 프로그래밍

이제 C#프로그램 쪽을 보도록 하겠습니다.

using Modbus.Device;

using 선언부에 위와 같은 문장을 삽입하세요.

사용할 RS232C포트를 오픈합니다.

_serialPort = new SerialPort("COM1", 115200);
_serialPort.Open();

그 다음 ModbusSerialMaster를 초기화 해주는 명령을 써줍니다.

_modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);
_modbusMaster.Transport.ReadTimeout = 500;
_modbusMaster.Transport.WriteTimeout = 500; 
_modbusMaster.Transport.Retries = 0;

이것으로 MODBUS를 사용할 준비는 끝난 것입니다. 이제 아래 메소드중 원하는 메소드를 불러서 사용하시면 됩니다. NMODBUS 에 대해서 구체적인 부분이 알고싶으시면 NMODBUS API 메뉴얼을 참조하세요.

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);
 

데모 프로그램

아래 데모 프로그램은 큐블록 MSB612RA-DC의 포트 하나를 ON 또는 OFF 하거나,A/D값을 읽어오는 예제입니다.

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Modbus.Device;
using System.IO.Ports;
 
namespace NModbusTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        ModbusSerialMaster _modbusMaster;
        SerialPort _serialPort;
        const int SLAVE_ADDRESS = 1;
 
        private void Form1_Load(object sender, EventArgs e)
        {
            _serialPort = new SerialPort("COM1", 115200);
            _serialPort.Open();
 
            _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);
            _modbusMaster.Transport.ReadTimeout = 500;
            _modbusMaster.Transport.WriteTimeout = 500;
            _modbusMaster.Transport.Retries = 0;
 
        }
 
        void ReportError(string s)
        {
            MessageBox.Show(s);
        }
 
        private void ReadADC()
        {
            try
            {
                ushort[] result = _modbusMaster.ReadInputRegisters(SLAVE_ADDRESS, 276, 1);
                _adcLabel.Text = result[0].ToString();
            }
            catch (Exception ex)
            {
                ReportError(ex.Message);
            }
        }
 
        private void ReadDigitalOutput()
        {
            try
            {
                bool[] result = _modbusMaster.ReadCoils(SLAVE_ADDRESS, 32, 1);
                if (result[0])
                {
                    _digitalOutLabel.Text = "ON";
                }
                else
                {
                    _digitalOutLabel.Text = "OFF";
                }
            }
            catch (Exception ex)
            {
                ReportError(ex.Message);
            }
        }
 
        private void WriteDigitalOutput(bool on)
        {
            try
            {
                _modbusMaster.WriteSingleCoil(SLAVE_ADDRESS, 32, on);
            }
            catch (Exception ex)
            {
                ReportError(ex.Message);
            }
        }
 
        private void _digitalOutReadButton_Click(object sender, EventArgs e)
        {
            ReadDigitalOutput();
        }
 
        private void _onButton_Click(object sender, EventArgs e)
        {
            WriteDigitalOutput(true);
        }
 
        private void _offButton_Click(object sender, EventArgs e)
        {
            WriteDigitalOutput(false);
        }
 
        private void _adcReadButton_Click(object sender, EventArgs e)
        {
            ReadADC();
        }
 
        private void Form1_Closing(object sender, CancelEventArgs e)
        {
            _modbusMaster.Dispose();
            _modbusMaster = null;
 
            _serialPort.Close();
            _serialPort.Dispose();
            _serialPort = null;
        }
    }
}

소스 다운받기

다음은 동작 동영상입니다. 프로토콜 아날라이저를 사용해서, CUWIN 과 CUBLOC간의 데이터 통신 상황을 모니터링 하고 있습니다.

MODBUS 어드레스

한가지 부연설명을 더 하자면, MODBUS 어드레스에 관한 것입니다.

 ushort[] result = _modbusMaster.ReadInputRegisters(SLAVE_ADDRESS, 276, 1);

이 메소드는 276번지에서 1 워드를 읽어오는 메소드입니다. MSB의 A/D 채널0의 결과를 저장하는 MODBUS 상의 어드레스가 276번지입니다.

MSB상의 모드버스 어드레스는 다음 표를 참고하세요. MSB LOGIC 사용설명서상에서 발췌한 내용입니다.

  • 8-o 저희 회사에서는 프로그램 개발과정에 관련된 어떠한 기술지원도 제공해드릴 수 없음을 양해바랍니다. 저희 회사에서는 하드웨어와 관련된 부분에 대해서만 기술 지원이 가능합니다. Visaul Studio 에서 코딩하다 발생된 문의는 Microsoft사로 직접 해주시기 바랍니다.

한단계 뒤로

cuwin/cuwin_modbus/index.txt · 마지막으로 수정됨: 2022/11/02 17:31 저자 Comfile Technology