From 96a0378fff25197804e54faf591d80502b00f643 Mon Sep 17 00:00:00 2001 From: Samuel Ventura Date: Sat, 4 Mar 2017 10:43:20 -0600 Subject: [PATCH] SharpModbus-RELEASE-1.0.5.0 Improved CRC endianess handling. Maintenance release. Does not add or break any functionality. --- SharpModbus/ModbusHelper.cs | 17 +++++++++-------- SharpModbus/ModbusRTUProtocol.cs | 3 ++- SharpModbus/ModbusRTUWrapper.cs | 11 ++++++----- SharpModbus/package.nuspec | 2 +- SharpModbusTest/MasterTest.cs | 25 +++++++++++++++++++++++++ SharpModbusTest/SlaveTest.cs | 4 ++-- 6 files changed, 45 insertions(+), 17 deletions(-) diff --git a/SharpModbus/ModbusHelper.cs b/SharpModbus/ModbusHelper.cs index f328b7b..d4c87d4 100644 --- a/SharpModbus/ModbusHelper.cs +++ b/SharpModbus/ModbusHelper.cs @@ -17,7 +17,7 @@ public static ushort CRC16(byte[] bytes, int offset, int count) crc >>= 1; } } - return (ushort)((crc >> 8) & 0x00ff | (crc << 8) & 0xff00); + return crc; } public static byte EncodeBool(bool value) @@ -108,13 +108,6 @@ public static byte Low(int value) { return (byte)((value >> 0) & 0xff); } - /* - public static void Set(byte[] bytes, int offset, ushort value) - { - bytes[offset + 0] = (byte)((value >> 8) & 0xff); - bytes[offset + 1] = (byte)((value >> 0) & 0xff); - } - */ public static ushort GetUShort(byte bh, byte bl) { @@ -132,6 +125,14 @@ public static ushort GetUShort(byte[] bytes, int offset) ); } + public static ushort GetUShortLittleEndian(byte[] bytes, int offset) + { + return (ushort)( + ((bytes[offset + 1] << 8) & 0xFF00) + | (bytes[offset + 0] & 0xff) + ); + } + public static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count) { for (var i = 0; i < count; i++) diff --git a/SharpModbus/ModbusRTUProtocol.cs b/SharpModbus/ModbusRTUProtocol.cs index 6929192..0adb97a 100644 --- a/SharpModbus/ModbusRTUProtocol.cs +++ b/SharpModbus/ModbusRTUProtocol.cs @@ -13,7 +13,8 @@ public IModbusWrapper Parse(byte[] request, int offset) { var wrapped = ModbusParser.Parse(request, offset); var crc = ModbusHelper.CRC16(request, offset, wrapped.RequestLength); - Assert.Equal(crc, ModbusHelper.GetUShort(request, offset + wrapped.RequestLength), "CRC mismatch {0:X} expected:{1:X}"); + Assert.Equal(crc, ModbusHelper.GetUShortLittleEndian(request, offset + wrapped.RequestLength), + "CRC mismatch {0:X4} expected {1:X4}"); return new ModbusRTUWrapper(wrapped); } } diff --git a/SharpModbus/ModbusRTUWrapper.cs b/SharpModbus/ModbusRTUWrapper.cs index f618445..8b5e9d0 100644 --- a/SharpModbus/ModbusRTUWrapper.cs +++ b/SharpModbus/ModbusRTUWrapper.cs @@ -19,14 +19,15 @@ public void FillRequest(byte[] request, int offset) { wrapped.FillRequest(request, offset); var crc = ModbusHelper.CRC16(request, offset, wrapped.RequestLength); - request[offset + wrapped.RequestLength + 0] = ModbusHelper.High(crc); - request[offset + wrapped.RequestLength + 1] = ModbusHelper.Low(crc); + request[offset + wrapped.RequestLength + 0] = ModbusHelper.Low(crc); + request[offset + wrapped.RequestLength + 1] = ModbusHelper.High(crc); } public object ParseResponse(byte[] response, int offset) { var crc1 = ModbusHelper.CRC16(response, offset, wrapped.ResponseLength); - var crc2 = ModbusHelper.GetUShort(response, offset + wrapped.ResponseLength); + //crc is little endian page 13 http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf + var crc2 = ModbusHelper.GetUShortLittleEndian(response, offset + wrapped.ResponseLength); Assert.Equal(crc2, crc1, "CRC mismatch {0} {1}"); return wrapped.ParseResponse(response, offset); } @@ -40,8 +41,8 @@ public void FillResponse(byte[] response, int offset, object value) { wrapped.FillResponse(response, offset, value); var crc = ModbusHelper.CRC16(response, offset, wrapped.ResponseLength); - response[offset + wrapped.ResponseLength + 0] = ModbusHelper.High(crc); - response[offset + wrapped.ResponseLength + 1] = ModbusHelper.Low(crc); + response[offset + wrapped.ResponseLength + 0] = ModbusHelper.Low(crc); + response[offset + wrapped.ResponseLength + 1] = ModbusHelper.High(crc); } public override string ToString() diff --git a/SharpModbus/package.nuspec b/SharpModbus/package.nuspec index 85896bf..8e14822 100644 --- a/SharpModbus/package.nuspec +++ b/SharpModbus/package.nuspec @@ -2,7 +2,7 @@ SharpModbus - 1.0.4.0 + 1.0.5.0 Samuel Ventura C# Modbus Tools https://github.com/samuelventura/SharpModbus diff --git a/SharpModbusTest/MasterTest.cs b/SharpModbusTest/MasterTest.cs index 2ff9584..e4e8807 100644 --- a/SharpModbusTest/MasterTest.cs +++ b/SharpModbusTest/MasterTest.cs @@ -1,4 +1,5 @@ using System; +using System.IO.Ports; using System.Net.Sockets; using System.Threading; using NUnit.Framework; @@ -16,6 +17,30 @@ private bool[] Bools(int count, bool value) bools[i] = value; return bools; } + + [Test] + 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("COM10"); + serial.BaudRate = 57600; + serial.Open(); + var stream = new ModbusSerialStream(serial, 400); + var protocol = new ModbusRTUProtocol(); + var master = new ModbusMaster(stream, protocol); + + master.WriteCoil(1, 3000, false); + master.WriteCoil(1, 3001, true); + master.WriteCoil(1, 3002, true); + master.WriteCoil(1, 3003, false); + Thread.Sleep(50); + Assert.AreEqual(false, master.ReadCoil(1, 3000)); + Assert.AreEqual(true, master.ReadCoil(1, 3001)); + Thread.Sleep(50); + Assert.AreEqual(new bool[]{false, true, true, false}, master.ReadCoils(1, 3000, 4)); + } [Test] public void RackSweepTest() diff --git a/SharpModbusTest/SlaveTest.cs b/SharpModbusTest/SlaveTest.cs index b9e0b72..f00830e 100644 --- a/SharpModbusTest/SlaveTest.cs +++ b/SharpModbusTest/SlaveTest.cs @@ -9,7 +9,7 @@ namespace SharpModbusTest public class SlaveTest { [Test] - public void RtuSlaveMethod() + public void RtuSlaveTest() { var model = new ModbusModel(); var stream = new ModelStream(model, new ModbusRTUScanner()); @@ -18,7 +18,7 @@ public void RtuSlaveMethod() } [Test] - public void TcpSlaveMethod() + public void TcpSlaveTest() { var model = new ModbusModel(); var stream = new ModelStream(model, new ModbusTCPScanner());