Giter Site home page Giter Site logo

nmodbus4's Introduction

NModbus4

Build Status Code Coverage
Mono Build Status
MS .NET Build status codecov.io

Join the chat at https://gitter.im/NModbus4/NModbus4

NModbus is a C# implementation of the Modbus protocol. Provides connectivity to Modbus slave compatible devices and applications. Supports serial ASCII, serial RTU, TCP, and UDP protocols. NModbus4 it's a fork of NModbus(https://code.google.com/p/nmodbus). NModbus4 differs from original NModbus in following:

  1. removed USB support(FtdAdapter.dll)
  2. removed log4net dependency
  3. removed Unme.Common.dll dependency
  4. assembly renamed to NModbus4.dll
  5. target framework changed to .NET 4

Install

To install NModbus4, run the following command in the Package Manager Console

PM> Install-Package NModbus4

Documentation

Documentation is available in chm format (NModbus.chm)

License

NModbus4 is licensed under the MIT license.

nmodbus4's People

Contributors

breyed avatar gitter-badger avatar groove81 avatar maxwe11 avatar richardlawley avatar shaggygi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nmodbus4's Issues

verify the address of write and read error

I got a project, used NModbus. When I write single coil, I always get error shows expected address in response is not equal to address written into master. But the fact the correct address was written. I dig into the code, and get the return value from TCPClient is not correct. The received address is always equal to half of expected address, such as i write to 913, and received 456.
1xu o pok 3xhhnr38q5 y

upgrading to VS 2013

NModbus setup...upgrading to VS 2013. I am having issues with incompatible files Can someone help me?

Enron Modbus Didn't Work.

Hello, I've been using modbus from when it's hosted on google code, and everything works great until my last project.

My last project uses Enron Modbus, And I've noticed that in Modbus.Extensions there is already a class to read single 32 bit register.

However, when I've used the extension procedure "ReadHoldingRegisters32", It didn't work.

Apparently "ReadHoldingRegisters32" uses the approach of just doing 2 request of 16 bit registers. Well, Enron Modbus doesn't work that way.

The returned response is a contiguous longer response for just one request.

I've debugged NModbus and found that the culprit is at

ModbusIpTransport.cs

internal static byte[] ReadRequestResponse(IStreamResource streamResource)

specifically the line

var frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(mbapHeader, 4));

it keep gives off framelength = 3 while after testing, I found out that the correct framelength is actually 7.

after some crude hacking, I've managed to get it to work, although I also have to change ValidateResponse (ReadHoldingInputRegistersRequest.cs) as well, because expectedbytecount also changes (from 2 to 4) and lastly PerformReadRegisters at ModbusMaster.cs so that I got 2 registers of ushort ( I resort to using just "ReadHoldingRegisters" requesting 1 point , instead of ReadHoldingRegisters32)

I know this is very crude hacking, so I'm sorry I can't submit my changes to this project. Just letting you know that there's an issue with enron modbus.

[TCP] Integration tests periodically fail

Discovering: NModbus4.IntegrationTests
Discovered:  NModbus4.IntegrationTests
Starting: NModbus4.IntegrationTests.DLL
System.ArgumentException: EndPoint 127.0.0.1:1060 cannot be removed, it does not exist.
   at Modbus.Device.ModbusTcpSlave.OnMasterConnectionClosedHandler(Object sender, TcpConnectionEventArgs e) in C:\projects\nmodbus4-ss8e4\NModbus4\Device\ModbusTcpSlave.cs:line 153
   at Modbus.Unme.Common.EventUtility.Raise[T](EventHandler`1 handler, Object sender, T e) in C:\projects\nmodbus4-ss8e4\NModbus4\Unme.Common\EventUtility.cs:line 24
   at Modbus.Device.ModbusMasterTcpConnection.<>c.<ReadHeaderCompleted>b__19_0(ModbusMasterTcpConnection thisRef, IAsyncResult asyncResult) in C:\projects\nmodbus4-ss8e4\NModbus4\Device\ModbusMasterTcpConnection.cs:line 88
   at Modbus.Device.ModbusMasterTcpConnection.CatchExceptionAndRemoveMasterEndPoint(IAsyncResult ar, Action`2 action, String endPoint) in C:\projects\nmodbus4-ss8e4\NModbus4\Device\ModbusMasterTcpConnection.cs:line 172
   at Modbus.Device.ModbusMasterTcpConnection.ReadHeaderCompleted(IAsyncResult ar) in C:\projects\nmodbus4-ss8e4\NModbus4\Device\ModbusMasterTcpConnection.cs:line 82
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.ContextAwareResult.CompleteCallback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.ContextAwareResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Command exited with code 1

https://ci.appveyor.com/project/Maxwe11/nmodbus4-ss8e4/build/portable-3.0-67

SerialRTU on Bluetooth

If I use the library with serial cable everything do work as expected, however if I move the communication via a high latency serial (in this case Bluetooth ) I have the following error:

The I/O operation has been aborted because of either a thread exit or an application request.

If I do have break-point in code sometime do work, sometime not.
This make me believe that library do not handle well asynchronous communication with latency on serial port.

Communication work well via Bluetooth with ModbusPoll

WriteSingleCoil

I'm working on Modbus/TCP Master/Slave, when I tries to write to single coil status register, I'm getting the exception like-Unexpected start address in response. Expected 1, received 0. even though it's successfully writes to coil address.

what's the exception says I'm not understanding??

SerialRTU Anomaly

When sending data manually to query a coil, I get the expected result, but from NModbus4 I get a 0x3F result:

Using serial port monitor:

[22/12/2015 12:11:33] - Open port COM5 (C:\Program Files\Eltima Software\Serial Port Monitor\SerialMonitor.exe) 

[22/12/2015 12:11:41] Written data (COM5) 
    03 01 00 00 00 01 fc 28                           ......ü(         
[22/12/2015 12:11:41] Read data (COM5) 
    03 01 01 01 91 f0                                 ....‘ð           
[22/12/2015 12:14:21] - Close port COM5 

Using NModbus4

[22/12/2015 12:14:25] - Open port COM5 (C:\Users\gavin\Source\Repos\HSPI_MODBUS\Modbus Plugin\ConsoleApplication1\bin\Debug\ModbusConsole.vshost.exe) 

[22/12/2015 12:14:25] Written data (COM5) 
    03 01 00 00 00 01 fc 28                           ......ü(         
[22/12/2015 12:14:25] Read data (COM5) 
    00 3f                                             .?               
[22/12/2015 12:14:28] - Close port COM5 

Code:

Dim port = New SerialPort("COM5", 19200, Parity.Even, 8, StopBits.One)
port.Open()
Dim master As ModbusSerialMaster = ModbusSerialMaster.CreateRtu(port)
master.Transport.Retries = 0
master.Transport.ReadTimeout = 3000
Dim coils() = master.ReadCoils(3, 0, 1)

COM port parameters identical. Any ideas?

Getting request and response messages without parsing

Hi! I have the project, where I need to develop something like modbus logger. It is necessary to get request and response messages from transport (particularly serial port) layer without parsing. Another words, I need messages with slave address, function code, data, crc code blocks. Is it real to make without modifying source code of framework?

Portable subset support

For making NModbus4 portable we should split up abstractions from transport implementation.
I'd suggest to split up on following packages:

  1. NModbus4.dll - portable abstractions
  2. NModbus4.TcpUdp.dll - portable Tcp/Udp transport implementation (depends NModbus4.dll)
  3. NModbus4.Serial.dll - non-portable serial transport implementation (depends NModbus4.dll)

These changes will require some breaking changes e.g. we will have to delete some factory methods like:

public static ModbusIpMaster CreateIp(TcpClient tcpClient)
public static ModbusIpMaster CreateIp(UdpClient udpClient)
public static ModbusIpMaster CreateIp(SerialPort serialPort)

since they require arguments of types that not supported in portable subset. And introduce new factory for creating masters/slaves with corresponded transport.
For making TCP/UDP transport portable we also will have to reimplement it to rely directly on Socket instead of TcpListener, TcpClient, UdpClient, etc.

/cc @breyed if you are interesting in, any thoughts?

Migrate to DNX project model

Switch to new project system - Class Library (Package) project template in VS 2015 RTM.
Root folder should be

/
    .nuget
    docs
    nuget
    src
    *.chm
    *.md

Read value from specific Modbus address using RTU

Hello,

I am working on a project in which I want to read value for particular Modbus address using RTU protocol. I have checked the code for NModbus 1.11.0.0 Source but did not find any method to read values using RTU. Does it support to read values? How can I read values?

Moreover, is there any latest version of Modbus?

Thanks,
ankita

Server Nmodbus4 don't send TCP FIN after client is disconnected

Hello ,
I have a problem with NModbus Library.

When my client is disconnected :

CLIENT           SERVER
FIN, ACK  ---->
          <----  ACK

and nothing else...!

The server don't send FIN to client.

After timeout, client send RST to server.

And when client try to reconnect, server send a bad SEQ number.

CLIENT           SERVER
SYN seq0  ---->
          <----  ACK seq1 (Wireshark said TCP ACKed unseen segment)
RST seq0  ---->

Result, just the first connection after the start of server is done.

Please, do you have any idea ?

My code

class ModbusServer
    {
        #region Variables
        private Sql sql;
        private int port;
        TcpListener tcp;
        ModbusSlave slave;

        #endregion


        #region Constructeur
        public ModbusServer(int port = 502)
        {
            this.port = port;

            IPHostEntry ipEntry = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress[] addr = ipEntry.AddressList;
            tcp = new TcpListener(addr[0], port);
            slave = ModbusTcpSlave.CreateTcp(255, tcp);
            slave.DataStore = DataStoreFactory.CreateDefaultDataStore();

            slave.DataStore.DataStoreWrittenTo += new EventHandler<DataStoreEventArgs>(DataStore_DataStoreWrittenTo);
        }


        #endregion


        #region Public
        public void start()
        {
            try
            {

                slave.Listen();
                Console.WriteLine("[MODBUS] Server started");
                Console.WriteLine("[MODBUS] Port " + port);

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

            }

        }
        #endregion


        #region Private
        private void DataStore_DataStoreWrittenTo(object sender, DataStoreEventArgs e)
        {
            Console.WriteLine("[MODBUS] Reception of values");


            int iAddress = e.StartAddress;
            List<ushort> data = new List<ushort>();

            if (e.ModbusDataType == ModbusDataType.HoldingRegister)
            {

                for (int i = 0; i < e.Data.B.Count; i++)
                {
                    data.Add(e.Data.B[i]);
                    Console.WriteLine("[" + i + "] " + e.Data.B[i]);
                }

            }
        }
        #endregion
    }

Thanks !
Aurélien
from France

Some tests with mocks fail

Test class name Test method name
ModbusAsciiTransportFixture ReadRequestResponseNotEnoughBytes
ModbusTransportFixture UnicastMessage_ErrorSlaveException

Migrate to xUnit

Rewrite existings tests with xUnit instead because NUnit no longer maintained.

Response code indication while using Modbus RTU

I am using Modbus RTU protocol to read data. I have Slave Id = 1 and Modbus Address = 40023. I am configuring Start Address = 22. Is it correct with my Modbus Address?

If I am configuring following details:
Slave Id= 1
Baud Rate = 115200
Stop Bits = 2
Data Bits = 8
Parity = None
Start Address = 22
I am reading data with following code

var master = ModbusSerialMaster.CreateRtu(port);
ushort[] registers = master.ReadHoldingRegisters(slaveId, startAddress, 2);  //2 is number of points

With these details I am getting this response in console:
INFO Modbus.IO.ModbusSerialTransport - TX: 1, 3, 0, 22, 0, 2, 37, 207
In above response I only know some of them what they indicate like first digit 1 indicate Slave Id, 3 indicate function Code, 22 indicate Start Address, 2 indicate number of points.

Can anyone please explain me remaining code? What they indicate?

Thanks,
Ankita

Endless loop in ReadRequestResponse

I have been using the original NModbus for years, until recently I ran into a prb where it did not return from reading and hat its thread at 100% running.
I used your version for debugging, as I found it and thought it might behave differently. But it was the same. The cause was that in ModbusIpTransport.ReadRequestResponse it ran into an endless loop for an invalid channel id.
The prb was that it first read 3 bytes of 7 to be read but then it returned 0 in subsequent looop.
I changed the code to (see below) and now it works.
I dont want to mess around with your code, but you might consider adopting these changes.
Stefan

    internal static byte[] ReadRequestResponse(IStreamResource streamResource) {
        // read header
        byte[] mbapHeader = new byte[6];
        int numBytesRead = 0;
        while (numBytesRead != 6) {
            int bRead = streamResource.Read(mbapHeader, numBytesRead, 6 - numBytesRead);
            if (bRead == 0)
                throw new IOException("Read resulted in 0 bytes returned.");
            numBytesRead += bRead;
        }
        Debug.WriteLine("MBAP header: {0}", mbapHeader.Join(", "));

        ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(mbapHeader, 4));
        Debug.WriteLine("{0} bytes in PDU.", frameLength);

        // read message
        byte[] messageFrame = new byte[frameLength];
        numBytesRead = 0;
        while (numBytesRead != frameLength) {
            int bRead = streamResource.Read(messageFrame, numBytesRead, frameLength - numBytesRead);
            if (bRead == 0) throw new IOException("Read resulted in 0 bytes returned.");
            numBytesRead += bRead;
        }
        Debug.WriteLine("PDU: {0}", frameLength);

        byte[] frame = mbapHeader.Concat(messageFrame).ToArray();
        Debug.WriteLine("RX: {0}", frame.Join(", "));

        return frame;
    }

Read/Write signed value

For my needs, i have to write/read signed values. But NModbus seems to only use ushort data type for input and output. Have to create a new branche ?

RtuTransport Assumes only master requests as slave

When using an RTU slave, it assumes that all activity on it's RX line will be from a master. However, not everyone will be using this in a single network. Currently, a response message from a slave is read in as a master request, parsed incorrectly, and throws.

TCP Connection to master not closing

I am working on my first application that is communicating with modbus devices. I am creating a slave (server) which will read and write some registry data to some maters(devices) via the TCP/IP.

For develop purposes I use this master emulator: http://www.plcsimulator.org/.
For getting/setting registry data I use following constructs:

using (var client = new TcpClient(_address, _port)) { using (var master = ModbusIpMaster.CreateIp(client)) { master.WriteMultipleRegisters(startAddress, value); } }

Because of the using block I am quite sure all disposable objects are correctly disposed. However the emulator still shows there are active connections until the timeout (approx. 20 seconds) exceeds.

Is itfeature or bug or is there some other way how to close the connection?

Refactor Async API

Objectives:

  • Current implementation CPU-bound, we should make it IO-bound.
  • Current implementation allocates a bunch of delegates and closures.

Steps:

  • Slave API
  • Master API

Make API independent from implementation details

Current Modbus API requires from user such implementation details as TcpClient, TcpListener, SerialPort. These implementation details should be hidden from user under abstractions. The goal of this change is making API more friendly. For example why current API is worst is that the only way to stop the slave listening is disposing TcpListener or closing SerialPort.

Wrong slave Holding Address

i want to insert address 3000 but must write 3002, why? With 3002 answers correct.

DataStore ds = DataStoreFactory.CreateDefaultDataStore();
ds.HoldingRegisters[3002] = 1111;

SerialPort sp = new SerialPort();
sp.BaudRate   = 9600;
sp.DataBits   = 8;
sp.StopBits   = StopBits.One;
sp.Parity     = Parity.None;
sp.Open();

ModbusSerialSlave slave1 = ModbusSerialSlave.CreateRtu(1, sp);
slave1.DataStore = ds;
slave1.Listen();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.