將溫度值讀出來。
首先它的連接參數如下:
Baud Rate : 9600 , N , 8 , 1
需要設定啟用以下設定,否則會一直發送卻沒有人回你。
DTR – Data Terminal Ready
RTS – Request To Send
接下來說明Command
RS232 command
|
Function
|
Remarks
|
K(ASC 4BH)
|
Ask for model No.
|
Return 4 bytes
|
A(ASC 41H)
|
Inquire all encoded data
|
Return encoded 10 byte
|
H(ASC 48H)
|
Hold button
| |
M(ASC 4DH)
|
MAX/MIN button
| |
N(ASC 4EH)
|
Exit MAX/MIN mode
| |
T(ASC 52H)
|
TIME button
| |
C(ASC 43H)
|
C/F button
| |
U(ASC 55H)
|
Dump all memory of thermometer
|
return 32768 bytes
|
P(ASC 50H)
|
Load recorded data
|
主要會用到2個,一個是K,一個是A。
K是會回傳型號,例如'3' '0' '6' ASCII(13) ,'3' '0' '1' ASCII(13) 。
而A則是溫度資訊,其他的功能本次沒有實作。
301和306在溫度的回傳的資料,有差一個byte,在實作時要注意。
我有一組306的回傳值,共九個BYTE。
02 80 00 B2 29 BB 00 B2 28 03
只會用到其中5個byte
第2個byte的第1個bit和第4個bit (由0開始計算)表示T1和T2是否為負值(1為負值)。
例如目前為00, 則T1和T2都是正值。
第3~4個BYTE代表T1的溫度值,B2 29 --> 022.9 ℃
第7~8個BYTE代表T2的溫度值,B2 28 --->022.8 ℃
一開始我是把B給濾掉,但後來發現降到9.8℃ 時,會出現BB.98 ,才推測B是0 。
以下是我的程式碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO.Ports; using System.Collections; namespace TEST { class Center_306 { private SerialPort port; private Test.Form1.MyDelegate md; public Center_306(String comport, TH300Monitor.Form1.MyDelegate md) { this.md = md; port = new SerialPort(comport, 9600, Parity.None, 8, StopBits.One); // Enable DTR bool s = port.DtrEnable = true; port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); } public void QueryTemp() { port.Write(new char[] { 'A' }, 0, 1); } private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { int bytes = port.BytesToRead; byte[] comBuffer = new byte[bytes]; port.Read(comBuffer, 0, bytes); if (bytes == 9) { byte[] t1 = new byte[2]; byte[] t2 = new byte[2]; bool t1_sign = (comBuffer[2] & (1 << 1)) != 0; bool t2_sign = (comBuffer[2] & (1 << 4)) != 0; Array.Copy(comBuffer, 3, t1, 0, 2); Array.Copy(comBuffer, 7, t2, 0, 2); string hex1=BitConverter.ToString(t1); string hex2 = BitConverter.ToString(t2); hex1 = hex1.Replace("-", "").Replace("B", "0"); hex2 = hex2.Replace("-", "").Replace("B", "0"); double temp1 = Double.Parse(hex1) / 10.0; double temp2 = Double.Parse(hex2) / 10.0; if (t1_sign == true) { temp1 = temp1 * -1; } if (t2_sign == true) { temp2 = temp2 * -1; } Console.WriteLine(temp1 + " " + temp2); md.Invoke(temp1, temp2); } } public void Open() { port.Open(); } public void Close() { port.Close(); } } }
呼叫方式如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using TH300; using System.IO.Ports; namespace TH300Monitor { public partial class Form1 : Form { //add for Center 306 public delegate void MyDelegate(double temp1, double temp2); Center_306 c306; MyDelegate oMyDel; bool isConnect=false; public Form1() { InitializeComponent(); } private void btnConn_Click(object sender, EventArgs e) { TimerRead.Enabled = true; //add center 306 oMyDel = new MyDelegate(Show); c306 = new Center_306(C306_com.Text, oMyDel); c306.Open(); } //for center 306 display MyDelegate uu; public void Show(double temp1, double temp2) { if (this.InvokeRequired) { uu = new MyDelegate(Show); this.Invoke(uu, temp1, temp2); } else { c306_temp1.Text = temp1.ToString(); c306_temp2.Text = temp2.ToString(); } } private void btnDisconn_Click(object sender, EventArgs e) { TimerRead.Stop(); System.Threading.Thread.Sleep(1000); //ad for center 306 c306.Close(); } private void btnStop_Click(object sender, EventArgs e) { TimerRead.Stop(); } /// <summary> /// Read data per sec /// </summary> private void TimerRead_Tick(object sender, EventArgs e) { //add for c306 c306.QueryTemp(); } private void Form1_Load(object sender, EventArgs e) { // Set Timer TimerRead.Interval = 1000; } } }
當有回傳值時,會自動顯示在c306_temp1及c306_temp2 二個Lable上
參考資料
C306
https://www.instrumart.com/assets/MARTEL306_manual.pdf
C301差異截圖