using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using AR; using Modbus; using Modbus.Device; namespace DigitalIndicator { public partial class Form1 : Form { ModbusSerialMaster modbus; System.IO.Ports.SerialPort dev; public Form1() { InitializeComponent(); dev = new System.IO.Ports.SerialPort(); } private void Form1_Load(object sender, EventArgs e) { string[] ports = GetAvailablePorts(); cmbIndiport.Items.Clear(); cmbIndiport.Items.AddRange(ports); timer1.Start(); } private static string[] GetAvailablePorts() { return SerialPort.GetPortNames(); } private void button1_Click(object sender, EventArgs e) { // 연결/끊기 if (cmbIndiport.Text.isEmpty()) { UTIL.MsgE("포트번호를 입력하세요"); return; } if (int.TryParse(tbbaud.Text, out int baud) == false) { UTIL.MsgE("baud rate 값을 입력하세요\n(기본:9600)"); return; } if (dev.IsOpen) { if (modbus != null) modbus.Dispose(); dev.Close(); UTIL.MsgI("연결이 종료되었습니다"); } else { dev.PortName = this.cmbIndiport.Text; dev.BaudRate = baud; dev.DataBits = 8; // 데이터 비트 dev.Parity = System.IO.Ports.Parity.None; dev.StopBits = System.IO.Ports.StopBits.One; dev.ReadTimeout = 2000; dev.WriteTimeout = 2000; try { dev.Open(); } catch (Exception ex) { UTIL.MsgE(ex.Message); return; } // Modbus 마스터 생성 modbus = ModbusSerialMaster.CreateRtu(dev); } } private void timer1_Tick(object sender, EventArgs e) { this.button1.Text = (this.dev?.IsOpen ?? false) ? "연결끊기" : "연결"; } private void button2_Click(object sender, EventArgs e) { // 쓰기 if (Int32.TryParse(this.textBox1.Text, out int value) == false) { UTIL.MsgE("숫자로 입력하세요"); return; } if (this.textBox1.TextLength > 5) { UTIL.MsgE("5자리를 초과할 수 없습니다"); return; } var valuebuffer = splitI32(value); var slave = (byte)numericUpDown1.Value; try { modbus.WriteMultipleRegisters(slave, 0, valuebuffer); //ADDRESS 0=40001 } catch (System.TimeoutException ex) { UTIL.MsgE(ex.Message); } } UInt16[] splitI32(Int32 value) // 0 ~ 65535 { // 32비트 정수(Int32) --> 2개(상위/하위)의 16비트 부호 없는 정수(UInt16)로 분할 var hValue = (UInt16)(value >> 16); // 오른쪽으로 16비트 시프트하여 상위 16비트를 추출 var lValue = (UInt16)(value & 0xFFFF); // (0xFFFF = 16비트의 모든 비트가 1인 값)와의 비트 AND 연산을 수행하여 하위 16비트를 추출 return new ushort[] { hValue, lValue }; // 16비트 부호없는 정수 배열을 반환 (UInt16 = ushort) } private void button3_Click(object sender, EventArgs e) { if (Int32.TryParse(this.textBox1.Text, out int value) == false) { UTIL.MsgE("숫자로 입력하세요"); return; } var valuebuffer = new ushort[20]; valuebuffer[0] = 100; for (int i = 1; i < valuebuffer.Length; i++) valuebuffer[i] = 0; var slave = (byte)numericUpDown1.Value; modbus.WriteMultipleRegisters(slave, 0, valuebuffer); //ADDRESS 0=40001 } } }