Tuesday, 28 February 2012

Read values from Iskraemeco Mt830 and Mt831 from Rs 485

I had to read values from  Iskraemeco Mt830 and Mt831 meters from the rs-485 interface provide by the MK-f38-3 module.

The protocol used is IEC 62056-21 mode C.

Here you can download a simple (and not optimal) Winform application useful to test the meter:
https://sites.google.com/site/walterslog/WinFormIskraMt831.zip?attredirects=0&d=1

Just insert the name of the rs-485 COM port (COM5 e.g.), the serial number of the meter, click 'Get data' and wait approximately 60 seconds.

Let's see the commands I used to get the data. Pay attention to the Thread.Sleep commands, they are used to send commands at the right time. The milliseconds I used are a mix from what I learnt from the IEC standard and what I found working well for this kind of meters.

First open the COM Port:

SerialPort Port = new SerialPort("COM5", 9600, Parity.Even, 7, StopBits.One);
Port.Open();

Then send the "wake-up" sequence, eight NULL chars, then wait 1600 milliseconds:

String NUL = Convert.ToChar(0x0).ToString();

for (int i = 0; i < 8; i++)
            {
                Port.Write(NUL);
                Thread.Sleep(50);
            }        


Thread.Sleep(1600);  


Send a command containg the Serial Number of the meter, then wait:

String SerialNumber = "56251230";
Port.Write("/?" +  SerialNumber   + "!\r\n");

Thread.Sleep(1600);

After this command the meter will reply with a message containing the model of the meter.

Send the command that will activate the "Readout mode":

String ACK = Convert.ToChar(0x06).ToString();
Port.Write(ACK + "050\r\n");


The two zeros in the "050" sequence set Readout mode, the five means the new baud rate (9600 bps) at which the COM Port will operate. With the rs-485 interface of the Iskraemeco meter the communication starts and ends at 9600 bps  but with the optical probe it starts with 300 bps and switches to 9600 bps.

Then the meter should reply with all the obis codes with their values in less than a minute.
You can read the data with this code (the "!" char indicates to the receiving unit where the reply ends) :

 String results = "";


 DateTime EndTime = DateTime.Now.AddSeconds(60);
       
 while (DateTime.Now <= EndTime && results.Contains("!")== false)
  {
        if (Port.BytesToRead == 0) continue;


        byte[] ResponseFrame = new byte[Port.BytesToRead];
                   
         Port.Read(ResponseFrame, 0, ResponseFrame.Length);


         results += FrameToString(ResponseFrame);                   
  }       

Then close the COM port:

Port.Close();

Surely you will notice that this code is awful :-)
Its only purpose is to show the right commands and timing and it's not suitable for production code.