智能電表數據讀寫心得


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM