智能电表数据读写心得

1、布线方面

    智能电表采用的是485通讯。如果单位的局域网布置得比较完整的话,建议使用串口转以太网模块,将数据接入以太网。这样做的好处是可以利用现有的网络布线,不用再重复布线。若是使用串口转以太网模块的话,那就需要在上位机上安装一个名为《虚拟VSPM虚拟串口服务器》的软件,它的功能是在将远端的TCP服务器虚拟成一个串口,这样一来,数据的读写跟使用485串口通讯是一样的。

    虚拟VSPM虚拟串口服务器的下载地地址:

     http://www.kinghwawin.com/DownloadShow.asp?ID=40

    串口转以太网络模块的地址:

     http://item.taobao.com/item.htm?spm=a1z09.2.9.66.LxUUjT&id=10248910782&_u=rlmt59h151e

 

2、程序方面

    智能电表的数据读写需要遵循相应的通讯协议,这些通讯协议已经被列入了国家标准。目前比较常用的有两个标准:一是2007版本的,全称是《中华人民共和国电力行业标准 DLT645-2007多功能电能表通信协议》,一个是1997版本的。本文使用的是2007版本的通讯协议。   

    下面的代码的GetPowerConsumption()函数演示了如何读取总电量。

using System;

using System.Collections.Generic;



using System.Text;

using System.IO.Ports;

using System.Windows.Forms;

using System.Diagnostics;





public class ElectricityMeter

{





    //****************************************************** 字 段 ************************************************************************** 

    SerialPort _serialPort = new SerialPort();

    Form _frm;



    private static readonly ElectricityMeter _instance = new ElectricityMeter();



    //*****************************************************  事 件 ***************************************************************************





    //****************************************************** 属 性 *************************************************************************** 





    //****************************************************** 构造函数  ******************************************************************* 



    /// <summary>

    /// 私有构造函数,防止类被实例化

    /// </summary>

    private ElectricityMeter()

    {



    }



    //****************************************************** 方 法  ******************************************************************* 







    /// <summary>

    /// 只能通过CreateInstance方法来创建类的实例。单例模式

    /// </summary>

    public static ElectricityMeter CreateInstance()

    {

        return _instance;

    }









    /// <summary>

    /// 打开设备

    /// </summary>

    /// <param name="portName">串口号</param>

    /// <param name="frm">调用这个类的窗体。</param>

    public void Open( string portName, Form frm )

    {

        try

        {

            // 初始化窗体对象

            _frm = frm;

            _frm.FormClosing += new FormClosingEventHandler( _frm_FormClosing );

            //初始化SerialPort对象

            _serialPort.PortName = portName;

            _serialPort.BaudRate = 2400; // 请将设备的波特率设置为此。

            _serialPort.DataBits = 8;

            _serialPort.StopBits = StopBits.One;

            _serialPort.Parity = Parity.Even;

            _serialPort.Open();

        }

        catch( Exception e )

        {

            MessageBox.Show( e.Message );

        }

    }











    /// <summary>

    /// 关闭设备。

    /// </summary>

    public void Close()

    {

        if( _serialPort.IsOpen == true )

        {

            _serialPort.Close();

            _serialPort.Dispose();

        }

    }





    /// <summary>

    /// 获取耗电量

    /// </summary>

    public Decimal GetPowerConsumption()

    {

        if( _serialPort.IsOpen == true )

        {

            // 十六进制的命令字符串

            string strCmd = "68 AA AA AA AA AA AA 68 11 04 33 33 33 33 AD 16";

            // 转换为十六进制的字节数组

            string[] strs = strCmd.Split( new char[] { ' ' } ); // 空格分组



            byte[] cmdBytes = new byte[ strs.Length ];



            //  转换为十进制的字节数组

            for( int i = 0; i < cmdBytes.Length; i++ )

            {

                cmdBytes[ i ] = Convert.ToByte( strs[ i ], 16 ); // 16进制转换为10进制

            }



            _serialPort.Write( cmdBytes, 0, cmdBytes.Length );



            System.Threading.Thread.Sleep( 500 );  // 500ms内应当有响应



            byte[] resultBytes = new byte[ 21 ]; // 容量为21的字节数组

            _serialPort.Read( resultBytes, 0, resultBytes.Length );



            string n1 = Convert.ToString( resultBytes[ 18 ] - 51, 16 ); // 将十进制转成16进制的字符串

            string n2 = Convert.ToString( resultBytes[ 17 ] - 51, 16 ); // 将十进制转成16进制的字符串

            string n3 = Convert.ToString( resultBytes[ 16 ] - 51, 16 ); // 将十进制转成16进制的字符串

            string n4 = Convert.ToString( resultBytes[ 15 ] - 51, 16 ); // 将十进制转成16进制的字符串

            string resultString = n1 + n2 + n3 + "." + n4;



            return Decimal.Parse( resultString );

        }

        else

        {

            throw new Exception( "串口没有打开" );

        }

    }







    /// <summary>

    /// 在窗体关闭的时候关闭串口连接。

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    void _frm_FormClosing( object sender, FormClosingEventArgs e )

    {

        this.Close();

    }







}
View Code

 

    2007版标准的下载地址:

    http://wenku.baidu.com/view/b5e3e9d776a20029bd642d6d.html

 

你可能感兴趣的:(数据)