這樣暑假又可以忙推甄的事情,源碼部份有Delphi與C++,那當然先看最愛得C++ XDDD
源碼看似是C#.Net,實際上是『Managed Extensions for C++』,有興趣朋友可以點擊看一下
這個程式主要透過兩個執行緒再去跑,透過readThread去接收資料,檔案存在data.bin
Hardware是由某間公司生產?所以Protocol都是他們自己設計的,這個源碼也是該公司提供,還重金聘請...XDDDDDDD
就得照著該公司的規範,百思不得其解是因為列舉就可以解決的事情,卻要設計成好幾個十六進位才能使用,好奇?
static array<Byte>^ TryDetect = {0x00, 0x00, 0x00};
static array<Byte>^ setupRFDB = {0x0b, 0x08, 0xff, 0x00, 0x00};
static array<Byte>^ setupXMIT = {0x07, 0x80, 0x07, 0x01, 0xff, 0xff, 0x00, 0x14, 0x21};
static array<Byte>^ StpDetect = {0x22, 0x22, 0x22};
先設定_serialPort的資訊,一樣要照該公司的規範去設定
// Set the appropriate properties. _serialPort->PortName = SetPortName(_serialPort->PortName); _serialPort->BaudRate = 250000; _serialPort->Parity = Parity::None; _serialPort->DataBits = 8; _serialPort->StopBits = StopBits::One; _serialPort->Handshake = Handshake::None; // Set the read/write timeouts _serialPort->ReadTimeout = 500; _serialPort->WriteTimeout = 500;
接著去選擇COM Port
_serialPort->PortName = SetPortName(_serialPort->PortName);
接著Open _serialPort並且判斷是否成功開啟,開啟失敗就終止程式
if (_serialPort->IsOpen == true) {
Console::WriteLine("serialPort opened successfully!");
_continue = true;
}else {
Console::WriteLine("serialPort opened failed!");
message = Console::ReadLine();
_serialPort->Close();
fs->Close();
return;
}
就會開始持續讀取資料
readThread->Start();
除非使用者輸入quit,否則會持續運作直到沒電
while (_continue){
message = Console::ReadLine();
if (stringComparer->Equals("quit", message)){
_continue = false;
}
}
整體程式碼如下#using <System.dll>
using namespace System;
using namespace System::IO;
using namespace System::IO::Ports;
using namespace System::Threading;
public ref class PortChat
{
private:
static bool _continue;
static SerialPort^ _serialPort;
static FileStream^ fs = gcnew FileStream("data.bin", FileMode::Create);
static BinaryWriter^ w = gcnew BinaryWriter(fs);
static Byte onebyte;
static array<Byte>^ TryDetect = {0x00, 0x00, 0x00};
static array<Byte>^ setupRFDB = {0x0b, 0x08, 0xff, 0x00, 0x00};
static array<Byte>^ setupXMIT = {0x07, 0x80, 0x07, 0x01, 0xff, 0xff, 0x00, 0x14, 0x21};
static array<Byte>^ StpDetect = {0x22, 0x22, 0x22};
public:
static void Main()
{
String^ message;
StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;
Thread^ readThread = gcnew Thread(gcnew ThreadStart(PortChat::Read));
// Create a new SerialPort object with default settings.
_serialPort = gcnew SerialPort();
// Set the appropriate properties.
_serialPort->PortName = SetPortName(_serialPort->PortName);
_serialPort->BaudRate = 250000;
_serialPort->Parity = Parity::None;
_serialPort->DataBits = 8;
_serialPort->StopBits = StopBits::One;
_serialPort->Handshake = Handshake::None;
// Set the read/write timeouts
_serialPort->ReadTimeout = 500;
_serialPort->WriteTimeout = 500;
try{
_serialPort->Open();
}catch (IOException ^) {
Console::WriteLine("serialPort opened failed!");
message = Console::ReadLine();
fs->Close();
return;
}
if (_serialPort->IsOpen == true) {
Console::WriteLine("serialPort opened successfully!");
_continue = true;
}
else {
Console::WriteLine("serialPort opened failed!");
message = Console::ReadLine();
_serialPort->Close();
fs->Close();
return;
}
readThread->Start();
Console::WriteLine("Type quit to exit");
Console::WriteLine("Press Enter to Start to Receive...");
message = Console::ReadLine();
_serialPort->RtsEnable = true;
Thread::Sleep(1);
_serialPort->RtsEnable = false;
Thread::Sleep(500);
_serialPort->Write(TryDetect, 0, 1);
_serialPort->Write(TryDetect, 0, 1);
_serialPort->Write(setupRFDB, 0, setupRFDB->Length);
Thread::Sleep(10);
_serialPort->Write(setupXMIT, 0, setupXMIT->Length);
while (_continue)
{
message = Console::ReadLine();
if (stringComparer->Equals("quit", message))
{
_continue = false;
}
}
_serialPort->Write(TryDetect, 0, 1);
_serialPort->Write(TryDetect, 0, 1);
_serialPort->Write(TryDetect, 0, 1);
_serialPort->Write(StpDetect, 0, 1);
_serialPort->Write(StpDetect, 0, 1);
_serialPort->Write(StpDetect, 0, 1);
readThread->Join();
_serialPort->Close();
fs->Close();
}
static void Read()
{
while (_continue)
{
try{
int count = _serialPort->BytesToRead;
if (count > 0) {
array<Byte>^ Buffer = gcnew array<Byte>(count);
_serialPort->Read(Buffer, 0, count);
Console::WriteLine(L"\n{0} bytes received:", count);
for (int i=0; i<count; i++) {
w->Write(Buffer[i]);
Console::Write(L"{0} ", Buffer[i].ToString(L"X"));
}
}
} catch (TimeoutException ^) { }
}
}
static String^ SetPortName(String^ defaultPortName)
{
String^ portName;
Console::WriteLine("Available Ports:");
for each (String^ s in SerialPort::GetPortNames())
{
Console::WriteLine(" {0}", s);
}
Console::Write("COM port: ");
portName = Console::ReadLine();
if (portName == "")
{
portName = defaultPortName;
}
return portName;
}
};
int main()
{
PortChat::Main();
}
執行畫面喔…省了
看起來直接寫在C#.Net或是WPF就好了吧?
Delphi的源碼想到在分析,差異不大
參考資料:
http://msdn.microsoft.com/zh-tw/library/system.io.ports.serialport.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1
http://en.wikipedia.org/wiki/Heart_rate_variability
http://www.dotblogs.com.tw/billchung/archive/2012/01/04/64319.aspx