將溫度值讀出來。
首先它的連接參數如下:
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差異截圖






































