Skip to content

Commit

Permalink
Moved to sharp serial and single net4x target.
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelventura committed Apr 17, 2020
1 parent 8987f81 commit 854bdb2
Show file tree
Hide file tree
Showing 12 changed files with 251 additions and 72 deletions.
33 changes: 25 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,28 @@ C# Modbus Tools
## Quick Start

```csharp
//Modbus RTU over serial
var master = ModbusMaster.RTU(new SerialPort()
var settings = new SerialSettings()
{
PortName = "COM10",
PortName = "COM3",
BaudRate = 57600,
});
master.WriteCoil(1, 3000, false);
};
//Modbus RTU over serial
using (var master = ModbusMaster.RTU(settings))
{
master.WriteCoil(1, 3000, false);
master.WriteCoils(1, 3001, false, true);
}
//Modbus RTU over isolated serial
using (var master = ModbusMaster.IsolatedRTU(settings))
{
master.WriteCoil(1, 3000, false);
master.WriteCoils(1, 3001, false, true);
}
//Modbus TCP over socket
var master = ModbusMaster.TCP("10.77.0.2", 502);
master.WriteCoils(1, 4, new bool[] { false, true });
using (var master = ModbusMaster.TCP("10.77.0.2", 502))
{
master.WriteCoils(1, 4, false, true);
}
```

## Documentation
Expand All @@ -28,7 +40,12 @@ No documentation yet. Resort to tests at SharpModbus.Test and SharpModbus.Test.S
- Windows 10 Pro 64x (Windows only)
- VS Code (bash terminal from Git4Win)
- Net Core SDK 3.1.201
- dotnet CLI
- com0com-2.2.2.0-x64-fre-signed COM98/99
- For Comfile Modport Test
- FTDI USB-RS485-WE-1800-BT COM3
- Comfile MD-H485+MD-DOSO8+5SlotBoard
- CUI SWI25-24-N-P5
- B&B BB-UH401

## Development CLI

Expand Down
69 changes: 60 additions & 9 deletions SharpModbus.Test.Special/Com0ComSlaveTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.IO.Ports;
using NUnit.Framework;

namespace SharpModbus.Test.Special
Expand All @@ -15,10 +14,22 @@ public void TcpOverSerialTest()
var model = new ModbusModel();
var scanner = new ModbusTCPScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var serial = new SerialPort(MasterCOM))
using (var stream = new ModbusSerialStream(new SerialSettings(MasterCOM), 400))
{
var master = new ModbusMaster(stream, new ModbusTCPProtocol());
//race condition avoided by access order
H.SharedSlaveTest(model, master);
}
}

[Test]
public void TcpOverIsolatedTest()
{
var model = new ModbusModel();
var scanner = new ModbusTCPScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var stream = new ModbusIsolatedStream(new SerialSettings(MasterCOM), 400))
{
serial.Open();
var stream = new ModbusSerialStream(serial, 400);
var master = new ModbusMaster(stream, new ModbusTCPProtocol());
//race condition avoided by access order
H.SharedSlaveTest(model, master);
Expand All @@ -31,7 +42,20 @@ public void RtuOverSerialTest()
var model = new ModbusModel();
var scanner = new ModbusRTUScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var master = ModbusMaster.RTU(new SerialPort(MasterCOM)))
using (var master = ModbusMaster.RTU(new SerialSettings(MasterCOM)))
{
//race condition avoided by access order
H.SharedSlaveTest(model, master);
}
}

[Test]
public void RtuOverIsolatedTest()
{
var model = new ModbusModel();
var scanner = new ModbusRTUScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var master = ModbusMaster.IsolatedRTU(new SerialSettings(MasterCOM)))
{
//race condition avoided by access order
H.SharedSlaveTest(model, master);
Expand All @@ -44,10 +68,23 @@ public void TcpExceptionOverSerialTest()
var model = new ModbusModel();
var scanner = new ModbusTCPScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var serial = new SerialPort(MasterCOM))
using (var stream = new ModbusSerialStream(new SerialSettings(MasterCOM), 400))
{
var master = new ModbusMaster(stream, new ModbusTCPProtocol());
var ex = Assert.Throws<ModbusException>(() => H.SharedExceptionTest(master));
Assert.AreEqual("Modbus exception 2", ex.Message);
Assert.AreEqual(2, ex.Code);
}
}

[Test]
public void TcpExceptionOverIsolatedTest()
{
var model = new ModbusModel();
var scanner = new ModbusTCPScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var stream = new ModbusIsolatedStream(new SerialSettings(MasterCOM), 400))
{
serial.Open();
var stream = new ModbusSerialStream(serial, 400);
var master = new ModbusMaster(stream, new ModbusTCPProtocol());
var ex = Assert.Throws<ModbusException>(() => H.SharedExceptionTest(master));
Assert.AreEqual("Modbus exception 2", ex.Message);
Expand All @@ -61,7 +98,21 @@ public void RtuExceptionOverSerialTest()
var model = new ModbusModel();
var scanner = new ModbusRTUScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var master = ModbusMaster.RTU(new SerialPort(MasterCOM)))
using (var master = ModbusMaster.RTU(new SerialSettings(MasterCOM)))
{
var ex = Assert.Throws<ModbusException>(() => H.SharedExceptionTest(master));
Assert.AreEqual("Modbus exception 2", ex.Message);
Assert.AreEqual(2, ex.Code);
}
}

[Test]
public void RtuExceptionOverIsolatedTest()
{
var model = new ModbusModel();
var scanner = new ModbusRTUScanner();
using (var server = new SerialModel(SlaveCOM, model, scanner))
using (var master = ModbusMaster.IsolatedRTU(new SerialSettings(MasterCOM)))
{
var ex = Assert.Throws<ModbusException>(() => H.SharedExceptionTest(master));
Assert.AreEqual("Modbus exception 2", ex.Message);
Expand Down
81 changes: 70 additions & 11 deletions SharpModbus.Test.Special/ComfileModportTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.IO.Ports;
using System.Threading;
using NUnit.Framework;

Expand All @@ -14,22 +13,82 @@ public void ModportSweepTest()
//m0 - MD-DIDC8 8 digital input
//m1 - MD-DOSO8 8 digital output
//all outputs wired to corresponding inputs
var serial = new SerialPort()
var settings = new SerialSettings()
{
PortName = "COM10",
PortName = "COM3",
BaudRate = 57600,
};
using (var master = ModbusMaster.RTU(serial))
using (var master = ModbusMaster.RTU(settings))
{
master.WriteCoil(1, 3000, false);
master.WriteCoil(1, 3001, true);
master.WriteCoil(1, 3002, true);
master.WriteCoil(1, 3003, false);
testMaster(master);
}
Thread.Sleep(200);
using (var master = ModbusMaster.IsolatedRTU(settings))
{
testMaster(master);
}
}

private void testMaster(ModbusMaster master)
{
for (var i = 0; i < 4; i++)
{
master.WriteCoil(1, us(3000 + i), false);
Thread.Sleep(50);
Assert.AreEqual(false, master.ReadCoil(1, 3000));
Assert.AreEqual(true, master.ReadCoil(1, 3001));
Assert.AreEqual(false, master.ReadCoil(1, us(3000 + i)));
master.WriteCoil(1, us(3000 + i), true);
Thread.Sleep(50);
Assert.AreEqual(new bool[] { false, true, true, false }, master.ReadCoils(1, 3000, 4));
Assert.AreEqual(true, master.ReadCoil(1, us(3000 + i)));
}
var s0 = bs(false, false, false, false);
var s1 = bs(false, true, true, false);
var s2 = bs(true, false, false, true);
master.WriteCoils(1, 3000, s1);
Thread.Sleep(50);
Assert.AreEqual(s1, master.ReadCoils(1, 3000, 4));
Thread.Sleep(50);
master.WriteCoils(1, 3000, s2);
Thread.Sleep(50);
Assert.AreEqual(s2, master.ReadCoils(1, 3000, 4));
Thread.Sleep(50);
master.WriteCoils(1, 3000, s0);
Thread.Sleep(50);
Assert.AreEqual(s0, master.ReadCoils(1, 3000, 4));
}

private ushort us(int v)
{
return (ushort)v;
}

private bool[] bs(params bool[] args)
{
return args;
}

private void checkSampleCompiles()
{
var settings = new SerialSettings()
{
PortName = "COM3",
BaudRate = 57600,
};
//Modbus RTU over serial
using (var master = ModbusMaster.RTU(settings))
{
master.WriteCoil(1, 3000, false);
master.WriteCoils(1, 3001, false, true);
}
//Modbus RTU over isolated serial
using (var master = ModbusMaster.IsolatedRTU(settings))
{
master.WriteCoil(1, 3000, false);
master.WriteCoils(1, 3001, false, true);
}
//Modbus TCP over socket
using (var master = ModbusMaster.TCP("10.77.0.2", 502))
{
master.WriteCoils(1, 4, false, true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion SharpModbus.Test.Special/SharpModbus.Test.Special.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net462</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
2 changes: 1 addition & 1 deletion SharpModbus.Test/SharpModbus.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net462</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
4 changes: 2 additions & 2 deletions SharpModbus.Test/TestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ private void Process(TcpClient client)
//client.ReceiveTimeout = -1;
while (true)
{
var size = client.GetStream().Read(buffer);
var size = client.GetStream().Read(buffer, 0, buffer.Length);
if (size <= 0) break;
scanner.Append(buffer, 0, size);
var cmd = scanner.Scan();
Expand All @@ -123,7 +123,7 @@ private void Process(TcpClient client)
{
response = cmd.GetException(2);
}
client.GetStream().Write(response);
client.GetStream().Write(response, 0, response.Length);
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions SharpModbus/Helpers.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
using System;
using System.IO.Ports;
using System.Net.Sockets;

namespace SharpModbus
{
public class SerialSettings
{
public SerialSettings() { init(null); }
public SerialSettings(string portName) { init(portName); }
public string PortName { get; set; }
public int BaudRate { get; set; }
public int DataBits { get; set; }
public Parity Parity { get; set; }
public StopBits StopBits { get; set; }
public Handshake Handshake { get; set; }

private void init(string portName)
{
var sp = new SerialPort();
PortName = portName ?? sp.PortName;
BaudRate = sp.BaudRate;
DataBits = sp.DataBits;
Parity = sp.Parity;
StopBits = sp.StopBits;
Handshake = sp.Handshake;
}
}

static class Assert
{
public static void Equal(int a, int b, string format)
Expand Down
39 changes: 39 additions & 0 deletions SharpModbus/ModbusIsolatedStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using SharpSerial;

namespace SharpModbus
{
public class ModbusIsolatedStream : IModbusStream
{
private readonly Action<char, byte[], int> monitor;
private readonly SerialProcess serialProcess;
private readonly int timeout;

public ModbusIsolatedStream(object settings, int timeout, Action<char, byte[], int> monitor = null)
{
this.serialProcess = new SerialProcess(settings);
this.timeout = timeout;
this.monitor = monitor;
}

public void Dispose()
{
Disposer.Dispose(serialProcess);
}

public void Write(byte[] data)
{
if (monitor != null) monitor('>', data, data.Length);
serialProcess.Write(data);
}

public int Read(byte[] data)
{
var response = serialProcess.Read(data.Length, -1, timeout);
var count = response.Length;
for (var i = 0; i < count; i++) data[i] = response[i];
if (monitor != null) monitor('<', data, count);
return count;
}
}
}
Loading

0 comments on commit 854bdb2

Please sign in to comment.