這樣暑假又可以忙推甄的事情,源碼部份有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