7 Replies - 20700 Views - Last Post: 31 May 2011 - 08:51 AM Rate Topic: -----

#1 greyEd  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 25-March 11

Modbus serial communication using Nmodbus

Posted 20 May 2011 - 08:55 AM

Hi all,

I have been researching for days and still not come up with a solution, so help would be extremely appreciated!

I am trying to use the modbus protocol to ping a meter connected on a serial port. Modbus, C# and 3rd party libraries are new to me, but I have to dive in head first.

I found the library NModbus here. Examples here.

I have added the entire folder to my project folder and added the main dlls modbus.dll and log4net.dll, as suggested on the google code site, as references for the project. I seem to have a successful build with my sample code, but all I get is a blank console window. Could anyone suggest where I might be going wrong? Is this the correct way to attempt a connection via modbus? Any help, much appreciated!

My code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using Modbus.Data;
using Modbus.Device;
using Modbus.Utility;




namespace NModbus
{
    class SerialMaster
    {
        static void Main(string[] args)
        {
            ModbusSerialAsciiMasterReadRegisters();
        }

        public static void ModbusSerialAsciiMasterReadRegisters()
        {
            using (SerialPort port = new SerialPort("COM1"))
            {
                // configure serial port
                port.BaudRate = 9600;
                port.DataBits = 8;
                port.Parity = Parity.None;
                port.StopBits = StopBits.One;
                port.Open();

                // create modbus master
                IModbusSerialMaster master = ModbusSerialMaster.CreateAscii(port);

                byte slaveId = 1;
                ushort startAddress = 50536;
                ushort numRegisters = 5;

                // read five registers       
                ushort[] registers = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);

                for (int i = 0; i < numRegisters; i++)
                    Console.WriteLine("Register {0}={1}", startAddress + i, registers[i]);
                    Console.ReadLine();
            }

            // output:
            // Register 1=0
            // Register 2=0
            // Register 3=0
            // Register 4=0
            // Register 5=0
        }
    }
}



Is This A Good Question/Topic? 0
  • +

Replies To: Modbus serial communication using Nmodbus

#2 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 9366
  • View blog
  • Posts: 35,187
  • Joined: 12-June 08

Re: Modbus serial communication using Nmodbus

Posted 20 May 2011 - 09:14 AM

No idea about this mobius business, but have you slapped a breakpoint right before your for-loop to see what is going on with your variables?
Was This Post Helpful? 0
  • +
  • -

#3 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 9366
  • View blog
  • Posts: 35,187
  • Joined: 12-June 08

Re: Modbus serial communication using Nmodbus

Posted 20 May 2011 - 09:21 AM

Debugging Tutorial
http://www.dreaminco...4249-debugging/
Was This Post Helpful? 0
  • +
  • -

#4 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5571
  • View blog
  • Posts: 11,908
  • Joined: 02-June 10

Re: Modbus serial communication using Nmodbus

Posted 20 May 2011 - 11:41 AM

First: Modi123_1 is completely right about the breakpoint and learning good debugging skills. Its a lot faster to be able to debug than to write questions and ask others for their guesses.


Debugging tutorial
Debugging tips
Great debugging tips
It still doesn't work, article

Second: When you say "all I get is a blank console window", let's be very clear that you mean you get NO output to the console. Nothing. This line never executes and never puts anything in your console:
Console.WriteLine("Register {0}={1}", startAddress + i, registers[i]);
If that is the case, then you know you had a failure in one of the lines above. When you run this with the F5 key, do you get any exception messages in the Output pallet? Again, a breakpoint point at line 27 followed by walking through one line at a time with the Autos and Locals pallets open would allow you to view the execution and see the values of each variable.

I've noticed you're hardcoded to COM1. Perhaps that's not the port you are really connected to.

I also noticed you are not checking to see if you are successful at opening the port. You issue a command to open, but you don't check to see if that failed.

using (SerialPort port = new SerialPort("COM1"))
            {
                // configure serial port
                port.BaudRate = 9600;
                port.DataBits = 8;
                port.Parity = Parity.None;
                port.StopBits = StopBits.One;
                port.Open();



Are you sure about that starting address and slave ID?
byte slaveId = 1;
ushort startAddress = 50536;

Most collections in C# start at 0. Element 1 is at location 0. Element 2 at location 1. So if this is your first slave is it possible the ID is 0? Memory addresses are usually referred to in hex: 0x00ea for example. Does the documentation for the board really say 50536 or does it give a hex address that you could have mis-translated?

Also, the sample code you pointed us all to has the starting address at 100, not 50536 - So I am left wondering why your code is a direct copy/paste from the sample except for the starting address.

This post has been edited by tlhIn`toq: 20 May 2011 - 11:42 AM

Was This Post Helpful? 1
  • +
  • -

#5 greyEd  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 25-March 11

Re: Modbus serial communication using Nmodbus

Posted 23 May 2011 - 08:56 AM

Sorry for the late reply, no access to my computer over the weekend.

First of all, thank you for your reply, It was very helpful, much appreciated!

My problems were that I needed an RTU configured master for the meter I am using, and also, I needed a valid value register address. The slave address was correct, as was the COM port... I printed this out to be sure.

Unfortunately, getting a valid address is a bit tricky. The address specified earlier (50536) was in the manual as-is, and also in hex form. Does it matter which I use? This address is not valid, that is, if my program works correctly :P A lot of the addresses listed do not return values. I have guessed other values and gotten results back. Some googling has lead me to believe that the Socomec documentation may indeed be wrong/out of date...

My linkhttp://groups.google.com/group/nmodbus-discuss/browse_thread/thread/a8bf4baff21230f1/ed65e512e8e4358f?hl=en&lnk=gst&q=registers#ed65e512e8e4358f

Would you have any idea if I am entering these address values incorrectly, is there a format I am unaware of? I will email Socomec and ask them also. Examples of the addresses are as follows:

50544 C570
50546 C572
50548 C574

Updated code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using FtdAdapter;
using Modbus.Data;
using Modbus.Device;
using Modbus.Utility;




namespace NModbus
{
    class SerialMaster
    {
      
        static void Main(string[] args)
        {

            printPorts();
            ModbusSerialRtuMasterReadRegisters();

        }

        public static void printPorts()
        {
            var portNames = SerialPort.GetPortNames();

            foreach(var p in portNames)
            {
                Console.WriteLine(p);
            }
        }

        public static void ModbusSerialRtuMasterReadRegisters()
        {
            using (SerialPort port = new SerialPort("COM1"))
            {
                // configure serial port

                port.BaudRate = 9600;
                port.DataBits = 8;
                port.Parity = Parity.None;
                port.StopBits = StopBits.One;

                try
                {
                    port.Open();
                    Console.WriteLine("port " + port.PortName + " open: " + port.IsOpen + "\n");
                }
                catch(Exception ex)
                {
                    Console.WriteLine("Unable to open port: " + ex);
                }

                // create modbus master
                IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port);

                byte slaveId = 1;
                ushort startAddress = 1;
                ushort numRegisters = 5;
                ushort[] registers = new ushort[numRegisters];;

                // read registers
                try
                {
                    registers = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
                    for (int i = 0; i < numRegisters; i++)
                        Console.WriteLine("Register {0}={1}", startAddress + i, registers[i]);
                }
                catch (Modbus.SlaveException se)
                {
                    Console.WriteLine("Could not find register... \n \n" + se);
                }

                try
                {
                    port.Close();
                    Console.WriteLine("\nport " + port.PortName + " open: " + port.IsOpen + "\n");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Unable to close port: " + ex);
                }
            }

            // output:
            // Register 1=0
            // Register 2=0
            // Register 3=0
            // Register 4=0
            // Register 5=0
        }
    }
}



Apologies for not debugging properly intially and having almost verbatim code, but I am new to C# and was slightly intimidated :D getting the hang of the debugger atm.
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5571
  • View blog
  • Posts: 11,908
  • Joined: 02-June 10

Re: Modbus serial communication using Nmodbus

Posted 23 May 2011 - 09:47 AM

View PostgreyEd, on 23 May 2011 - 09:56 AM, said:

Would you have any idea if I am entering these address values incorrectly, is there a format I am unaware of? I will email Socomec and ask them also. Examples of the addresses are as follows:

50544 C570
50546 C572
50548 C574


Base 10 numbers (decimal) are assigned as you would expect:
int Yogi = 50544;

Base 8 numbers (hex) are assigned like so:
int Yogi = 0xc570;


It really doesn't matter which format you prefer. In the end the variable will be assigned the identical value.

Beyond that, I think the group you found with others using the same board is going to be your best resource. Its just a very specialized device. Unless someone here just happens to also play with this same device, things like the correct memory address and so on are specific to the device and not common C# or Windows programming.

This post has been edited by tlhIn`toq: 23 May 2011 - 09:48 AM

Was This Post Helpful? 1
  • +
  • -

#7 greyEd  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 25-March 11

Re: Modbus serial communication using Nmodbus

Posted 23 May 2011 - 10:03 AM

Yeah, this is true, I will keep checking there. Thanks for your help.

This post has been edited by Curtis Rutland: 23 May 2011 - 10:05 AM

Was This Post Helpful? 0
  • +
  • -

#8 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5571
  • View blog
  • Posts: 11,908
  • Joined: 02-June 10

Re: Modbus serial communication using Nmodbus

Posted 31 May 2011 - 08:51 AM

This is the board that a buddy of mine uses for reading inputs and triggering devices. Hope it helps.
http://www.sparkfun....w&what=products
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1