3

I am trying to ping a Socomec meter using the Modbus protocol, having researched, I found NModbus, a C# library. I have never used libraries or C# before (normally Java), but I have to dive right in.

I set myself up with Visual Studio Express for C# and installed .Net. I have copied then contents of the NModbus file into my project folder and added the references to the two main DLLs. Its didn't work with .Net 4, but I retargeted to 3.5 (and removed the Microsoft.Csharp reference) and things seemed to compile.

I am using this sample, below, to attempt to connect to the slave device. When I run this, and set the startAdress variable to the desired one (found in Socomec documentation) however all I get is a blank console window.

In short, am I using the correct method/parameters, is my setup/code incorrect? How do I connect to this meter?

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
        }
    }
}
Sergei Danielian
  • 4,938
  • 4
  • 36
  • 58
marked
  • 589
  • 9
  • 24

2 Answers2

5

Why don't you use some Java MODBUS library when you are already familiar with Java? I haven't worked with Socomec meters, but in general for MODBUS devices you need to know the protocol and addresses you are interested in. Then try to read tags from the device with some tool that you know is working well, like MODPOLL. Then when you get usable values as expected, you go to programming the polling connection in any language you like. Otherwise, you risk to loose a lot of time wondering what's going on. One hint... From your code I see that you are acting as MODBUS ASCII serial master. Although such devices exist, 95% of RS232/RS485 devices I worked with were MODBUS RTU. Read specification if you don't know the difference.

avra
  • 3,690
  • 19
  • 19
  • I was initially using Jamod but was then told I needed to use a C varient so my code could run as a windows service/linux daemon. Could you tell me, is it possible to run c# as a linux daemon using something like mono? Or is it best to use a language like C++? Alternatively, I have found this: http://homepage.mac.com/ruske/ruske/C157541049/E1772200146/index.html It allows for java to be run as such services. You may not know it, but if you do, Is this practical? – marked May 24 '11 at 09:40
  • Regarding the orginal question... I managed to connect to the meter yesterday, you were dead on, I needed to use RTU and valid addresses. The problem now is, I dont know which addresses are valid, what theyre for. The documentation lists hundreds of registers but none of them work using my code or MODPOLL, I guess other values and get data (the same data in MODPOLL), but the ones I need dont work :/ Have you ever encountered such a problem before? I was wondering if the docs were out of date and have emailed socomec to ask. Sorry, long replies, thanks for your answers! and MODPOLL, great tool! – marked May 24 '11 at 09:51
  • I don't know anything about using C# or Java for linux services, sorry. Btw, when you accept someone's answer you should reward it with an upvote. That's the way this site works. ;-) – avra May 25 '11 at 00:14
  • It is very important to have exact adress list of all registers you need to access in a MODBUS device. If you trust your address list, then don't give up if data retreived looks wrong. It might be that your interpretation is wrong. Sometimes it may be that different endian is used (big/little vs little/big), or you are reading unsigned value when the device is delivering signed value, or you are asuming that float is packed in a register when it's really an integer, or few registers are combined to get Int64 or DOUBLE, or STRING or... You get the picture. – avra May 25 '11 at 00:14
  • This will take some analysis alright when I get to that point. I know MODBUS uses big-endian (at least it says that in the specification) and I will probably have to read in two registers for the one value. My problem is that I dont know how to use 6 digit addressing, which is what my addresses appear to be. I need to access address 50526, but I get an exception when attempting to do so. The library im using uses ushort addresses so I cannot use '450526', if that is the format. Any ideas? Perhaps in the spirit of organisation I should ask a new question :P – marked May 25 '11 at 09:39
  • Oh, I would have of course upvoted your answer if I had enough reputation to do so :D I need 15, ill come back when I do. Thanks for your help so far! – marked May 25 '11 at 09:42
1

You can run Java applications as a Windows service. There is a Tomcat Java service starter that I use with my company's Java application. You have create a method that will be called to stop the service, but that's just a method.

Here's the line I use to install my application as a service --

"%~dp0windows\tomcat6" //IS//%1 --DisplayName %1 --Description "gmServer for %1" ^ --JavaHome "%JAVA_HOME%" --Classpath "%PR_CLASSPATH%" --LogPrefix gmserver ^ --StartMode jvm --StopMode jvm --Jvm auto --StartPath "%~dp0." ^ --LogPath "%~dp0." --LogLevel debug --StdOutput %1.out --StdError %1.err ^ --StartClass greenMonitor.gmServer --StartParams -I#%I#-u#3600 ^ --StopMethod windowsService --StopParams stop --StopTimeout 10

The caret characters ("^") are line continuations characters in .BAT files. You should be able to find the meanings of the Tomcat command line options with the Tomcat documentation.

And for a Java-based Modbus library, complete with lots of handy programs you can use to test the connection, check out j2mod on Sourceforge. My company did a fork of jamod, along with a bunch of cleanups and that was the result.

Julie in Austin
  • 966
  • 5
  • 21