2016年12月6日 星期二

「分享」TH300 高低溫試驗箱控制

TH300 高低溫試驗箱,它透過RS232與PC連接,但其實它是轉換成RS485 ,

使用Modbus RTU協定。


預設的鮑率是38400  , N ,8, 1,必須透過RS232與它溝通 ,預設Slave ID 為1 。


首先介紹一下它的指令結構




























在這裡8位的意思表示8 bit ,也就是一個Byte。

機號:modbus中的slave都會有一個機號,它最後可以支援240個裝置,用機號來辨別

            要對誰做存取。

功能代碼: 通常我們用3和6就可以做基本的溫度、溼度、啟動/關閉功能的控制了。

傳送數據: 通常是要讀/寫的資料位置以及內容等設定。

CRC :校驗碼,以下為校驗碼計算方法

(VB.Net)


Public Function WriteCRC(ByRef cmdbyte As Byte())
        Dim cal As UInteger = "&HFFFF"
        Dim i As Integer
        For i = 0 To cmdbyte.Length - 3  '長度包含CHKSUM為cmdbyte.Length -3'            cal = cal Xor cmdbyte(i)
            For j = 0 To 7
                If (cal And "&H01") = 1 Then
                    cal = (cal >> 1) Xor "&HA001"
                Else
                    cal = cal >> 1
                End If
            Next
        Next
        cmdbyte(cmdbyte.Length - 1) = cal \ 256
        cmdbyte(cmdbyte.Length - 2) = cal Mod 256
        Return 1
    End Function

C#

class Crc16
    {
        private static ushort[] CrcTable = {
        0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
        0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
        0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
        0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
        0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
        0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
        0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
        0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
        0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
        0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
        0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
        0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
        0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
        0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
        0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
        0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
        0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
        0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
        0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
        0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
        0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
        0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
        0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
        0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
        0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
        0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
        0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
        0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
        0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
        0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
        0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
        0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };

        public static UInt16 ComputeCrc(byte[] data)
        {
            ushort crc = 0xFFFF;

            foreach (byte datum in data)
            {
                crc = (ushort)((crc >> 8) ^ CrcTable[(crc ^ datum) & 0xFF]);
            }

            return crc;
        }
    }



以下是廠商自訂的暫存器位址


only   for read





























溫度的部份有2個名詞要注意一下

SV是設定值(你想要升/降到幾度),PV則是當前實際測量的溫度



for read/write






























首先我們來一個啟動TH300的程式碼

控制碼的Function code為06  ,參考上表,Run/Stop的REG號為4001,長度為2 Byte

Public Sub StartTh300(ByVal AddressID As UShort)
        Dim cmdbyte(7) As Byte
        cmdbyte(0) = Convert.ToByte(AddressID) 'Slave Address(1~240)
        cmdbyte(1) = &H6 'write Function Code
        '
        Dim tempByte(1) As Byte
        tempByte = BitConverter.GetBytes(Convert.ToUInt16(40001))
        cmdbyte(2) = tempByte(1)
        cmdbyte(3) = tempByte(0)   '暫存器位址4001切成16進位
        '
        cmdbyte(4) = &H0
        cmdbyte(5) = &H1   '啟動為&H0 &H1
        WriteCRC(cmdbyte)   '寫入CRC
        SendCMD(cmdbyte)   '用RS232傳輸指令函式
        Dim Mycount As Integer = Conn.BytesToRead
        If Mycount = 0 Then
            Exit Sub
        End If
        Dim Readbyte(Mycount) As Byte
        Try
            ReadIncomBytes(Readbyte) '讀取RS232緩衝區資料函式
        Catch ex As Exception
            Exit Sub
        End Try
    End Sub

接下來是停止TH300的程式碼

Public Sub StopTH300(ByVal AddressID As UShort)
        Dim cmdbyte(7) As Byte
        cmdbyte(0) = Convert.ToByte(AddressID) 'Slave    Address
        cmdbyte(1) = &H6 ' write Function Code
        '
        Dim tempByte(1) As Byte
        tempByte = BitConverter.GetBytes(Convert.ToUInt16(40001))
        cmdbyte(2) = tempByte(1)
        cmdbyte(3) = tempByte(0)   '4001位址轉成16進位
        '
        cmdbyte(4) = &H0
        cmdbyte(5) = &H0   '停止為 &H0 &H0
        WriteCRC(cmdbyte) '寫入CRC
        SendCMD(cmdbyte) 'RS232傳送指令函式
        Dim Mycount As Integer = Conn.BytesToRead
        If Mycount = 0 Then
            Exit Sub
        End If
        Dim Readbyte(Mycount) As Byte
        Try
            ReadIncomBytes(Readbyte) '讀取RS232緩衝區資料函式
        Catch ex As Exception
            Exit Sub
        End Try
    End Sub

讀取目前溫溼度

Public Function MeasureTHValue(ByRef ReadArray() As Short, ByVal AddressID As UShort) As Boolean
        Dim cmdbyte(7) As Byte
        cmdbyte(0) = Convert.ToByte(AddressID) 'Slave Address
        cmdbyte(1) = &H3 ' Read Function Code
        cmdbyte(2) = &H75
        cmdbyte(3) = &H95   '30101 位址16進位
        cmdbyte(4) = &H0
        cmdbyte(5) = &H6   '讀取6個Byte
        WriteCRC(cmdbyte) '寫入CRC
        SendCMD(cmdbyte) 'RS232傳送指令函式
        Dim Mycount As Integer = Conn.BytesToRead
        If Mycount = 0 Then
            Return False
            Exit Function
        End If
        Dim Readbyte(Mycount) As Byte 
        Try
            ReadIncomBytes(Readbyte)
            Dim StartIndex As Integer = 3
            Dim ValueByte(1) As Byte
            For i = 0 To 5   '讀取回傳值
                ValueByte(0) = Readbyte(StartIndex + 1)
                ValueByte(1) = Readbyte(StartIndex)
                ReadArray(i) = BitConverter.ToInt16(ValueByte, 0)
                StartIndex = StartIndex + 2
            Next
        Catch ex As Exception
            Return False
            Exit Function
        End Try
        Return True
    End Function
------------------------------------------------------------------
'讀取溫度函式呼叫方式
 Dim MeasArray(5) As Short
 MeasureTHValue(MeasArray, Maddr)
'PV 目前TH300實際溫度
 mTempPV.Text = (MeasArray(1) / 100) - 100
'目標溫度(你想要升到幾度)
 mTempSV.Text = (MeasArray(0) / 100) - 100
'目前TH300溼度
 mHumiSV.Text = (MeasArray(3) / 10).ToString
'目標溼度
 mHumiPV.Text = (MeasArray(4) / 10).ToString

設定目標溫度 ,目標溫度(SV)暫存器為40012

Public Sub SendToRegester(ByVal Reg As Integer, ByVal Value As Integer, ByVal AddressID As Integer)
        Dim cmdbyte(7) As Byte
        cmdbyte(0) = Convert.ToByte(AddressID) 'Slave    Address
        cmdbyte(1) = &H6 ' Write Function Code
        '
        Dim tempByte(1) As Byte
        tempByte = BitConverter.GetBytes(Convert.ToUInt16(Reg)) 
        cmdbyte(2) = tempByte(1)
        cmdbyte(3) = tempByte(0)   '暫存器位址轉16進位
        '
        tempByte = BitConverter.GetBytes(Convert.ToUInt16(Value))
        cmdbyte(4) = tempByte(1)
        cmdbyte(5) = tempByte(0)  '設定值轉16進位
        WriteCRC(cmdbyte)  '寫入CRC
        SendCMD(cmdbyte) 'RS232傳送指令函式
        Dim Mycount As Integer = Conn.BytesToRead
        If Mycount = 0 Then
            Exit Sub
        End If
        Dim Readbyte(Mycount) As Byte
        Dim ValueByte(1) As Byte
        Dim ValueRead As Integer
        Try
            ReadIncomBytes(Readbyte)  '讀取RS232緩衝區資料函式
            ValueByte(0) = Readbyte(4)
            ValueByte(1) = Readbyte(3)
            ValueRead = BitConverter.ToInt16(ValueByte, 0)
        Catch ex As Exception
            Exit Sub
        End Try
    End Sub

'設定溫度呼叫方式 , Temp.Value 為想要升/降的目標溫度,ex 75
SendToRegester(40012, (Temp.Value + 100) * 100, Maddr)

設定運轉模式,TH300有2種模式,定值模式與程式模式,如果想完全由自己寫的程式控制

TH300,建議使用定址模式,設定模式這裡有一個限制,必須在TH300 停止時才可以設定

否則設定無效。


Public Sub SendToRegester(ByVal Reg As Integer, ByVal Value As Integer, ByVal AddressID As Integer)
        Dim cmdbyte(7) As Byte
        cmdbyte(0) = Convert.ToByte(AddressID) 'Slave    Address
        cmdbyte(1) = &H6 ' Write Function Code
        '
        Dim tempByte(1) As Byte
        tempByte = BitConverter.GetBytes(Convert.ToUInt16(Reg)) 
        cmdbyte(2) = tempByte(1)
        cmdbyte(3) = tempByte(0)   '暫存器位址轉16進位
        '
        tempByte = BitConverter.GetBytes(Convert.ToUInt16(Value))
        cmdbyte(4) = tempByte(1)
        cmdbyte(5) = tempByte(0)  '設定值轉16進位
        WriteCRC(cmdbyte)  '寫入CRC
        SendCMD(cmdbyte) 'RS232傳送指令函式
        Dim Mycount As Integer = Conn.BytesToRead
        If Mycount = 0 Then
            Exit Sub
        End If
        Dim Readbyte(Mycount) As Byte
        Dim ValueByte(1) As Byte
        Dim ValueRead As Integer
        Try
            ReadIncomBytes(Readbyte)  '讀取RS232緩衝區資料函式
            ValueByte(0) = Readbyte(4)
            ValueByte(1) = Readbyte(3)
            ValueRead = BitConverter.ToInt16(ValueByte, 0)
        Catch ex As Exception
            Exit Sub
        End Try
    End Sub

'設定模式呼叫方式 , 1 為定址模式 ,0為程式模式
SendToRegester(40101, 1, Maddr)

參考來源:


TH300 TH500 Mobus 通訊http://www.accutherm.com.cn/files/TH300/TH300_TH500_Modbus.pdf

溫濕度程式控制器

http://42.96.162.177/files/TH300/TH300%E7%B3%BB%E7%B5%B1%E8%A8%AD%E5%AE%9A%E8%AA%AA%E6%98%8E%E6%9B%B8-20110801.pdf

menu4_6_7605_TH500com_protocolV200.xls
http://chn.hynux.com/sub02_04.php?down=menu4_6_7605_TH500com_protocolV200.xls&file_name=menu4_6_7605_TH500com_protocolV200.xls&size=235008&board_name=Bdatafile/Board_3

深入了解 Modbus 協定http://www.ni.com/white-paper/52134/zht/

沒有留言:

張貼留言