Modbus libraries version 2 beta are out!

Today I published the version 2 (beta) of the Modbus libraries suite.
The most noticeable news is about the ordinary desktop .Net 4.5 support. This comes along a stunning Windows Store-like demo app for bidirectional testing with any Modbus-enabled Netduino.

demo0

demo1

demo2

demo3

This demo has been styled upon the brand-new Windows 8 “Modern-UI” rules, so that the incoming Windows RT libraries will feature a similar demo running on a tablet instead.

I also added the Windows Phone 8 support, but it looks exactly as the previous Windows Phone 7.5 release. I tested it only with the emulator not having any WP8-enabled phone.

Stay tuned!

Advertisements

Modbus-TCP library for Windows Phone

First of all, I apologize for messing up the source in the Codeplex repository. I started using (Tortoise) Git, and I didn’t realize that only some files were been updated on the server.

Introduction.

So, well…this is the third (and the last?) part of the “Modbus saga” around Netduino, and the Micro Framework in general. I guess there’s enough stuffs to play with, at least for the moment.
This article is going to present the porting of the Modbus library for the Windows Phone platform. The MF library has been presented in my previous articles here and here.

The Windows Phone platform.

This is my very first application for Windows Phone. I’d say that I bought my new Nokia Lumia 800, just for experimentation other than for calling. I really can’t compare with any other phone, simply because I have no experience. By the way, it’s a very amazing machine, and if you look for genuine developing fun, that’s really satisfying.
Note that if I own a Windows Phone now, it’s because the great Paolo Patierno, giving me an excellent description of the framework/device. I was unsure, but he gave me several reasons for choosing a WP: thanks again Paolo for the good tip!
Porting the library written for the .Net MF to the Windows Phone (Mango) platform, was as easy as a walk in the park. By the way, I have a strong WPF knowledge because is my daily job, so the impact was almost insignificant. However, there are several considerations to keep in mind, because a phone is very different from a normal PC.

Probably you won’t believe me, but the most complex task was about the deployment. On a PC is trivial (especially using ClickOnce), but even on Netduino is very easy to upload an application to the board. For the Windows Phones is not so easy, instead.
To access your phone you must subscribe to the App Hub, which requires a fee yearly. Then, you have full access to upload any your app on your phone. I mean just for testing on your own device, not for distribute!. To take part of the Windows Marketplace, your app has to be certified. It’s a pretty complex task, and I still haven’t try, but I would try it.

The demo application.

The demo is very simple, yet straightforward to use.
It’s based on the raw I/Os exposed by the Netduino. It must considered the “Plus” version just because the Ethernet connection is required by the Modbus-TCP protocol.
The hardware bench can be set up in minutes. The first 8 I/Os (D0..D7) are supposed to be always inputs, while the remaining 6 I/Os of the row (D8..D13) are supposed to be always outputs. The analog inputs (A0..A5), of course, are meant as they actually are.
I have connected only 4 push-buttons for driving the inputs, and 4 leds for watching the output states. I also used a couple of trimpots for generating a variable voltage to feed two analogs. That’s enough for a small demo.

Note. The trimpots I’ve used are over 20 years old, and are clearly dirty, and full of dust. On the video below you can laugh by seeing the “effort” I’ve made to turn them.

Of course in the Netduino board I have uploaded the already known Modbus-TCP server library. So, the small board is waiting for incoming connection on the TCP port 502, as the Modbus specs suggest.
On the phone, the app firstly asks for the target host. It should asks for the Modbus address as well, but due the simplicity of the program I’ve skipped this kind of parameters. The address has been fixed to “1”, as in the Netduino is.
After the successful connection, a “panorama-page” presents the three-sections of the exposed I/Os: boolean inputs, boolean outputs (i.e. coils), and analog inputs. A clipped picture of the board helps to recognize easily the pins.

What else? The application explains by itself what to do: by pressing a button by the Netduino, the related “led” (simulated) is lighting up. Similarly, when you mark any of the outputs checkboxes, the related led will do also. For the analogs, there are three kinds of representation of the real-time value: the raw value (i.e. the ADC word read), the related voltage converted, and a percentage level bar.

The software.

Nothing much to say, other than I’ve used the new “async” features of the incoming .Net 4.5.
The application acts as a state machine, polling sequentially the input ports, then the output ports, then the analog ports, and start again. The phone framework does not allow any “synchronous” operation (I’d say also “fortunately”). That’s because the UI must be totally free from any hangs due to tight loops, or unexpected long processing. Instead, everything is async-based, and here the “async-await” pattern comes easy to help the development.
For example, the boolean inputs request can be written as follows:

        private async void QueryDiscretes()
        {
            await TaskEx.Run(() =>
            {
                //compose the Modbus command to be submitted
                var command = new ModbusCommand(ModbusCommand.FuncReadInputDiscretes);
                command.Offset = 0;
                command.Count = InputCount;

                //execute the command synchronously
                CommResponse result = App.Modbus
                    .ExecuteGeneric(App.Client, command);

                if (result.Status == CommResponse.Ack)
                {
                    //command successfully
                    Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        for (int i = 0; i < command.Count; i++)
                        {
                            var input = this._inputs[i];
                            input.Value = command.Data[input.Offset] == 0;
                        }
                    }));
                }
                else
                {
                    //some error

                }

                this._status = MachineState.CoilRequest;
            });
        }

Note the “async” modifier immediately before the routine declaration, as well as the “await” heading the “Task.Run” action.

The nice thing is that you can write “synchronous-like” a piece of code which will be executed “asynchronously”. That’s made by the “magic” pattern “async-await”, and some other simple considerations.
The only annoying thing is that the “real” code will run on a separate thread than the UI’s, thus any direct interaction with the UI must be dispatched to the main thread. If you don’t do that, you’ll get an exception.
Note that I’ve used the MVVM approach to write the app, so the interaction is made with the viewmodel, on which the “real” UI is bound. Any modification to the viewmodel is immediately reflected to the UI.

The demo video.

Okay, here is a short video about the phone-Netduino interaction via Modbus-TCP. Despite the awkward phonemes coming out my mouth, I hope it’s clear enough from the technical perspective!

Conclusions.

I hope this small demo app might be useful for someone, at least as base for something “concrete”.
I guess this experience could be tried on the Fez board, because it seems that the library has been tested successfully. About Gadgeteers or Netduino Go!, I think should be working, but any TCP/IP connection must be available.
As usual, the full sources are hosted in the Codeplex repository: http://cetdevelop.codeplex.com/

Modbus-RTU added to the Cet Open Toolbox

I should say that the spring is in the air, but honestly the weather here was never so strange.
As the sun gets the weekend warmer, I’d love to ride with my bicycle to the big park near my home. However, since this Easter has been pretty cloudy, I took advantage to add a missing piece to the Modbus library presented last time.

Modbus-RTU support.

First of all, I’d like to say that the library has been tested on the Fez board. Many thanks to the user offering his code, and his time for this project.
After this good news, I’d like to introduce the new kind of support for the library: the Modbus-RTU. In my past article I promised to make an attempt to interface the RS-485 to the Netduino, but I was unsure about it. That’s essentially because the RS-485 interface requires a particular driver, which is not easy to realize with the managed code.
What is the difference from the shown Modbus-TCP/UDP?
The very first edition of the Modbus protocol was targeted for the serial port (i.e. UART or USART), just because the Ethernet or any other “complex” transport was available about thirty years ago. So, the communication was based on a simple cable pair, and relying on a very easy-to-implement protocol.
By the way, since the Modbus is typically used in industrial automation, a requirement was the good noise immunity, as well as the relative ability to create long distances. That’s not achievable by simply wiring the microcontroller’s logic, nor using the well-known RS-232 protocol.

The EIA-485 (a.k.a. RS-485) protocol fits perfectly this needing:

  • a simple cable pair is enough, although for long distances a shielded twisted pair is required;
  • distance up to 1200 meters (0.75 miles);
  • differential line, on 120 Ohms of impedance;
  • offers several dozen of devices connected on the same cable;
  • many more features yielding a very good solution for long distance cable communication.

The transmit mode.

The RS-485 protocol allows a master-slave architecture, using the network as a half-duplex. So, only one device can issue its data over the whole network, and this task can be achieved by enabling the “transmission mode”.
The “transmission mode” is very similar to the “Slave-select” of the SPI, but it’s not the same thing. Basically the device has to enable its physical RS-485 driver just before issuing the outgoing data. Since this “enabling” covers any other device, the “transmission mode” must be cleared immediately after the outgoing data has been issued.

The differential signal on the RS-485 line (source Wikipedia)

For instance, consider a basic master-slave handshake for a simple command:

  • the master enables its “transmission mode” (TXDE hereinafter), so that it takes the complete control of the cabled network;
  • sooner, the outgoing stream begins, and continues up to the end;
  • the master, switches its TXDE off, so that any other device (the addressed one) can be place its answer;
  • the addressed slave device, once recognized the request, places its TXDE on;
  • the answer’s outgoing stream begins, up to the completion;
  • the slave device disables its TXDE off, thus another query can be initiated.

So, the problem is how to control this TXDE signal, considering the short timing involved in the handshake. To give an idea about the timing, consider that the TXDE should be disabled within one-two byte period immediately after the end of the outgoing stream. If you think to a 9600 bps, one byte takes about 1 ms to run, and that’s really hard to control with the Netduino.
You know, I’m hating C/C++, and I’d never want to hack the firmware of the board. Most of the times, an hardware solution could be simpler than hacking a complex framework. That is the occasion, once again.

The TXDE circuit.

Here is not included the small module used for the RS-485 physical driver. I’ve used one of our production, which offers an embedded opto-isolation, and it seems perfectly tailored for the Netduino. It requires two kinds of supplies, +3.3V and +5V, and it supports up to 32 devices on the same line.

This module requires a low-level on the TXDE pin, for placing the driver in the “transmission mode”. The extra circuit should only “generate” this signal from the only useful signal available outgoing the Netduino, which is the TXD (serial data out).
The trick is somewhat trivial. The circuit acts a monostable flip-flop, which is re-triggered on any low-level of the TXD. Since any UART protocol must include a “start bit”, which is signed as low, this is enough to re-trigger the flip-flop on every byte issued by the UART. Of course, there are many more “low-bits” in a byte, but it should be considered the worst case, when all of the bit are high.
The problem is much easier than expected. I’ve tested the circuit over two different baud-rates, 9600 and 38400 bps, and it’s not critical at all. However, it’s not a “professional” way to solve such a problem, but just an hack. For a small home-automation, whereas the distances are shorter than 100 meters, and there’s no so many noises, of sure is acceptable.

How is it working?
You should bear in mind how a capacitor behaves, because that’s the key of the circuit.
A capacitor could be dualized as a tank, and the current as the water. Finally, the voltage across the capacitor could be thought as the water level.
When the tank is filled, it keeps the water level until some pipe extract the fluid from within. Now, suppose that this “pipe” is a resistor in parallel to the cap. At this point the water level decrease, as fast as big is the pipe. Thus, the higher is the current through the resistor, the faster will decrease the voltage across the capacitor.
Let’s take a look at the circuit.
When a low-level signal is issued on the TXD, an inverter (74HC14) reverse this level bringing high its output. In this case, the diode is forward-polarized and a lot of current will flow into the capacitor, charging it in a very short time. The “short time” is due to the diode, which is almost a short.
As soon the TXD will go high back, the inverter outputs a low-level, and the diode acts as it were an open circuit. In this case the capacitor is losing its change through the resistor. This evolution take a certain time, so that this “delay” is used to generate the TXDE signal.

The software.

The library was almost inline with the Modbus-RTU protocol. That’s the heavy decoupling benefit!
The “bigger” modification was about the name of the classes involving the Modbus codec. In the initial release of the library, I did not care about the RTU possibility. This time the RTU support has been taken place, and most of the classes could be shared. That’s a great satisfaction!
Another interesting addition is the CRC-16 calculation. I’ve found a C routine, which looked very simple, yet performing fast.
Here is a preview of the algorithm:

        /// <summary>
        /// Define the look-up table for calculating the CRC16 algorithm
        /// </summary>
        private static readonly ushort[] CrcTable = new ushort[256]
        {
            0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
            // ...
            0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 
        };


        /// <summary>
        /// Calculate the CRC16 over a byte-array segment
        /// </summary>
        /// <param name="buffer">The source byte-array</param>
        /// <param name="offset">The index of the first byte to be considered</param>
        /// <param name="count">The number of the bytes to be considered</param>
        /// <returns>The resulting CRC16 value</returns>
        /// <remarks>
        /// Ported from plain-C source found here: http://www.modbustools.com/modbus_crc16.htm
        /// </remarks>
        public static ushort CalcCRC16(
            byte[] buffer,
            int offset,
            int count)
        {
            ushort result = 0xFFFF;

            while (count-- > 0)
            {
                var temp = (byte)(buffer[offset++] ^ result);
                result >>= 8;
                result ^= CrcTable[temp];
            }

            return result;
        }

Conclusions.

With the support of the Modbus-RTU, this library could be considered complete. It’s not a full-featured library as it could be a desktop version, but of sure can solve several small projects we all dealing with.

The software is hosted in the Codeplex repository here.

Modbus-TCP library for Netduino

Here we go, after a long delay, full of promises for releasing this software earlier. My apologies on that.

Introduction.

My job is developing software for industrial applications. In such a field, the typical machine is a PLC, and the data-center is a PC/Server. However, there are thousands of small applications where a PLC+PC is just an overkill, either from the cost perspective, but yet from the complexity.

A small board like Netduino is a concrete way to fit these applications with easiness at a decent cost. The quality isn’t comparable, of course, but not always we’re asking for aerospace-safety when the controlled target is our garden sprinkler. An heating regulation, a small supervisory control, and many other ideas can effectively be realized with just this small board.

I believed on a small yet versatile library of some common protocol. Who’s working in such a field, also knows that Modbus is one of the most used worldwide. It’s primitive, poor, but really simple to implement. That was the main reason for the Modbus success. So I’ve written this piece of software because there are people asking for small solutions, and here is another one.

This library is targeted for the .Net Micro Framework (.Net MF), and in particular for the Netduino. I’d say for the Plus version only, because the only feasible implementation is based on IP. The Ethernet way comes easy to use, and offers advantages in terms of diffusion. There would be a serial RS-485 solution (Modbus-RTU), but I’m not sure to make it working with the Netduino.

Please, have a look here about the Modbus protocol variants.

Introducing the library.

As describe further in this article, the library has been designed to be enough flexible, as well as scalable.
Features:

  • Support for Modbus-TCP and UDP;
  • Support for Class 0 and Class 1 commands;
  • Both Master and Slave, even together on the same application;
  • Multi-threaded management for multiple sessions;
  • Pluggable architecture, so that new commands can be added without polluting the main code;
  • Allows the implementation of other protocols, even packed-oriented;
  • Very easy to use;
  • Totally open-source, under the Apache 2.0 license;

Limitations/known problems:

  • There’s few checking on the data incoming/outgoing. That’s for avoiding ton of code whereas not strictly necessary. These controls could be added easily, though.
  • The main limitation is on the available memory. There’s no check/bound on the incoming/outgoing data, thus the number of the I/O could be virtually as the protocol specifications say. By the way, since the Netduino has limited resources, it should be considered a small number of I/Os;
  • I tested the library using the latest official firmware (4.1.0.6), which is known having some trouble with the network layer.

The first attempt.

Although at the moment of writing this post the library seems to be the first complete Modbus implementation on top of the .Net MF ever made, the result is actually my second attempt. The first attempt was porting the excellent NModbus library to the Netduino, but it was an overkill. The conversion of a full-featured project for the standard .Net Framework is often a nightmare. The major problems aren’t the missing language features, nor the limited libraries. Instead, the real challenge is fit everything the user wants in some KB, and also consuming few RAM.
Indeed, the RAM is much like the gold using Netduino: there’s few, and you should use carefully. So, the game is a continuous balance of good-practice software patterns, and tricks to save memory. While in the ordinary framework you’re invited to always more powerful and bullet-proof languages (e.g. functional-like), here you should preserve an old-stylish way of programming, as it were an “elegant C++”.
But I hate C and C++, because they lead easily to errors. And I don’t want to spend my time catching errors, but rather targeting the application being in my mind.

Rewritten from scratch.

The second (i.e. the current) attempt has dramatically changed the library, and the original NModbus project has been dropped.

I started from the source we’re using for our professional systems, and that was much easier to adapt. That because, yes, it’s also .Net framework, but we’re using to implement the software taking care to the scalability. Most of the time we have both PC and small devices exchanging data each other, and that’s usually an hard, yet delicate task to manage.
This approach is pretty costly of design time, but it returns lot of benefits in term of portability.

The library is not just a Modbus protocol driver, rather a small platform which offers several components to combine each other. There’s a section about the available ports that can be used to physically transfer the data. Another section is related to the protocols: here is only the Modbus, but others could be added easily.

Basically there’s an abstraction over the available ports (Socket, SerialPort, etc), which make it comfortable to use always as it were the same port. The only differentiation is done about the behavior of the port, that is Client or Server.
The Client behavior sends a request, then waits for a response. The Server behavior waits for an incoming request, then elaborates it, then returns a response. Since these behaviors are very different, even on the threading usage, there are two different implementations.

Client port diagram

Server port diagram

The user application uses a certain port over a well defined protocol. In the case of the Modbus protocol, the client application should create a command, and submit to the server via the chosen port. However, the submitted command has to be properly encoded upon the Modbus specification, so that the request will flow through the port as a byte stream. Similarly, when the response originated by the server is incoming from the port as a byte stream, has to be decoded back. At this point the client application has its response ready to be used. This process of encoding/decoding is performed by the protocol layer, which is logically pipelined as the data flow perspective.

The bridge pattern gives the decoupling benefits as soon you are facing the problem to use the same protocol on different ports. For better clarifying the problem, let’s consider the “classic” Modbus protocol (Modbus-RTU), which is originally targeted for serial ports. This protocol has a different encoding than the Modbus-TCP, which relies on the intrinsic reliability of the TCP/IP transport. By the way, there is a particular “derivation” of the Modbus, which is called “Modbus over TCP”. It’s basically the same encoding of the RTU, but using the TCP/IP as transport layer. If you wish to have the ability to use the same Modbus encoding, using either the serial port or the socket, then the bridge pattern solves this problem perfectly.

The protocol diagram

The same consideration is about the “codec“, which stands for “COder+DECoder”. Basically the component that has to encode/decode the user’s command upon the protocol specification. The bridge approach has been used for the codec as well. That gives the ability to change the kind of encoding/decoding without changing either the user’a application, nor the port section.
The Modbus codec diagram

The Modbus specifications define a series of generic commands, which have been subdivided in “classes” of importance.
The first two classes of commands should cover most of the applications, but it’s easy to add any other command, as well as replace an existent implementation. That’s because there are many different custom extensions, details and something like that, created along the experience of the big-Co’s working with Modbus. So that I wanted to favor the “pluggability” of the commands, instead of the compactness of the code.

The Modbus commands are part of the Modbus codec, and they are offered as the “Command” behavioral pattern. They’re basically an array of a Modbus command abstraction. Since every command function is identified by a well precise code, the proper command handler should be placed in the right cell.

The test bench.

At the moment, the library is still under development, and under test. Thus, it might be some bug or improvement.
Anyway, there are several tests to be performed: both for the master/client way and for the slave/server way.
The Netduino itself sees a very little hardware connected: just four push-buttons, and four leds. A button simulates an input to be read by the Netduino application, while a led yields the symmetric information: an output driven by the same application.

The Netduino Plus test bench

Here is all about the hardware configuration of the Netduino:

    public class Program
    {
        private static InputPort[] _inputs = new InputPort[4];
        private static OutputPort[] _coils = new OutputPort[4];


        public static void Main()
        {
            //setup the board IP
            NetworkInterface.GetAllNetworkInterfaces()[0]
                .EnableStaticIP("192.168.0.99", "255.255.255.0", "192.168.0.1");

            string localip = NetworkInterface.GetAllNetworkInterfaces()[0]
                .IPAddress;

            Debug.Print("The local IP address of your Netduino Plus is " + localip);

            //define coils and inputs
            _inputs[0] = new InputPort(Pins.GPIO_PIN_D0, true, Port.ResistorMode.PullUp);
            _inputs[1] = new InputPort(Pins.GPIO_PIN_D1, true, Port.ResistorMode.PullUp);
            _inputs[2] = new InputPort(Pins.GPIO_PIN_D2, true, Port.ResistorMode.PullUp);
            _inputs[3] = new InputPort(Pins.GPIO_PIN_D3, true, Port.ResistorMode.PullUp);

            _coils[0] = new OutputPort(Pins.GPIO_PIN_D4, false);
            _coils[1] = new OutputPort(Pins.GPIO_PIN_D5, false);
            _coils[2] = new OutputPort(Pins.GPIO_PIN_D6, false);
            _coils[3] = new OutputPort(Pins.GPIO_PIN_D7, false);

            // ...

        }

As stated from the beginning, the library offers at the moment only the Modbus-IP (TCP and UDP) version, thus there is an Ethernet cable connected to the board, toward my home ADSL modem-router. My PC is also connected to the same router.

I could have used my own PC as Modbus-slave, running any simulator application. However, I wanted do more realistic the test, by using a real hardware. In the following picture there is the complete hardware bench used for the Master-TCP/UDP test.
The actual target I/O device is one of our’s production models. It offers many I/Os, both discrete and analog, and embeds several complex functions (not involved in this test, though). It’s targeted for heavy/hard working environments, and high reliability. It can communicate via RS485 using Modbus-RTU.

The complete test bench, together with the I/O device used as slave

Since at the moment there’s no support for the RS485 by the Netduino, there’s a Modbus gateway which acts as a bridge between the Ethernet (Modbus-TCP/UDP) and the RS485 (Modbus-RTU). The small display/keypad wired to the gateway is needed for its configuration, such as the IP.

Further details in the specific test sections.

Testing the Netduino as Modbus master.

In this case, the Netduino hosts a small application which posts a command cyclically, and waits for the response.

In the following snippet, there’s the source code of the client/Master-TCP application. In this example the Netduino cyclically reads its push-buttons state, and sends them as “Write Multiple Registers” command. The particular I/O device being used drives its outputs by writing on certain registers. Thus, the effect is activating an output of the device by pressing a push-button.

            //create a TCP socket
            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                //refine the socket settings
                socket.SetSocketOption(
                    SocketOptionLevel.Tcp,
                    SocketOptionName.NoDelay,
                    true
                    );

                socket.SendTimeout = 2000;
                socket.ReceiveTimeout = 2000;

                //try the connection against the remote device
                var remoteip = new byte[4] { 192, 168, 0, 60 };
                var ipaddr = new IPAddress(remoteip);
                var ept = new IPEndPoint(ipaddr, 502);
                socket.Connect(ept);

                //create a wrapper around the socket
                ICommClient portClient = socket.GetClient();

                //create a client driver
                var driver = new ModbusClient(new ModbusTcpCodec());
                driver.Address = 1;

                while (true)
                {
                    //compose the Modbus command to be submitted
                    var command = new ModbusCommand(ModbusCommand.FuncWriteMultipleRegisters);
                    command.Offset = 49;
                    command.Count = 4;

                    //attach the Netduino's input values as data
                    command.Data = new ushort[4];
                    for (int i = 0; i < 4; i++)
                        command.Data[i] = (ushort)(_inputs[i].Read() ? 0 : 1);

                    //execute the command synchronously
                    CommResponse result = driver
                        .ExecuteGeneric(portClient, command);

                    if (result.Status == CommResponse.Ack)
                    {
                        //command successfully
                    }
                    else
                    {
                        //some error
                        Debug.Print("Error=" + command.ExceptionCode);
                    }

                    //just a small delay
                    Thread.Sleep(1000);
                }
            }

It may be noticed that the socket connection is trivial, and supposed to be working at startup. A more reliable way should loop over a failed connection, then perform another attempt.

For the client/Master-UDP application, the source code is pretty similar. I changed the kind of command just to test something different. Here the Netduino application asks cyclically for a bunch of registers, then displays their content.

            //create a UDP socket
            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                //try the connection against the remote device
                var remoteip = new byte[4] { 192, 168, 0, 60 };
                var ipaddr = new IPAddress(remoteip);
                var ept = new IPEndPoint(ipaddr, 502);
                socket.Connect(ept);

                //create a wrapper around the socket
                ICommClient portClient = socket.GetClient();

                //create a client driver
                var driver = new ModbusClient(new ModbusTcpCodec());
                driver.Address = 1;

                while (true)
                {
                    //compose the Modbus command to be submitted
                    var command = new ModbusCommand(ModbusCommand.FuncReadMultipleRegisters);
                    command.Offset = 0;
                    command.Count = 16;

                    //execute the command synchronously
                    CommResponse result = driver
                        .ExecuteGeneric(portClient, command);

                    if (result.Status == CommResponse.Ack)
                    {
                        //command successfully
                        Debug.Print("Success!");
                        for (int i = 0; i < command.Count; i++)
                            Debug.Print("Reg#" + i + "=" + command.Data[i]);
                    }
                    else
                    {
                        //some error
                        Debug.Print("Error=" + command.ExceptionCode);
                    }

                    //just a small delay
                    Thread.Sleep(1000);
                }
            }

Same as the TCP way: the example program won’t make any further attempt in case of connection dropped. My deal was just to test the protocol library, not the host application.

Testing the Netduino as Modbus slave.

In this case I had no concrete hardware for the simulation, thus I used a specific software running in my PC.
I must confess that there are several software for the simulation, but either they are not free, or they are pretty limited on their functionality. For testing our devices we needed something pretty easy to work on, yet enough flexible as functionality. For instance, most of the simulators consider the TCP transport only, or a limited set of commands. So, we built our own application for testing most of the Modbus stuffs.

The Modbus master simulator

The application code for making the Netduino as Modbus-TCP server is much shorter than the master way.

            //create a TCP socket
            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                //place it as listener on the port 502 (standard Modbus)
                var ept = new IPEndPoint(IPAddress.Any, 502);
                socket.Listen(10);

                //create a server driver
                var server = new ModbusServer(new ModbusTcpCodec());
                server.Address = 1;

                while (true)
                {
                    //wait for an incoming connection
                    var listener = socket.GetTcpListener(server);
                    listener.ServeCommand += new ServeCommandHandler(listener_ServeCommand);
                    listener.Start();

                    Thread.Sleep(1);
                }
            }

It worth to be noticed that each connection creates a secondary socket (similarly as in a web server), and the process of listening to incoming data is performed on a separate thread. Until there are incoming requests, the thread is kept running, as well as the socket connection. Once a timeout expires after a silent/idle period, the socket will be closed, and the thread will die.

Here follows the UDP-slave version, which is slightly different, mainly because there’s no connection in the UDP technique. Instead, the listener should be only one (for each port), and the listening session is held running endlessly.

            //create a UDP socket
            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                //bind it to the port 502 (standard Modbus)
                var ept = new IPEndPoint(IPAddress.Any, 502);
                socket.Bind(ept);

                //create a server driver
                var server = new ModbusServer(new ModbusTcpCodec());
                server.Address = 1;

                //listen for an incoming request
                var listener = socket.GetUdpListener(server);
                listener.ServeCommand += new ServeCommandHandler(listener_ServeCommand);
                listener.Start();

                Thread.Sleep(Timeout.Infinite);
            }

Both in the TCP and UDP slave examples, there’s no an explicit control over the session abortion. As stated, the host application could close anytime the listening session. However, this functionality is not shown despite its availability.

Demo of the test.

Coming soon.

Conclusions.

Netduino is a small board tailored mainly for simple projects, whereas the reliability over the environment is not an issue. Adding the Modbus protocol might sound odd, because that’s a protocol for professional/industrial systems. However, my goal is not to get the Netduino into the high-end world. Rather, is adding a convenient interface for plugging a variety of smart sensors commonly found in the market. In this case the Modbus library gives you an help more.

The software is hosted in the Codeplex repository here.