此教程面向的讀者:對醫療器械上位機編程有興趣,或者急需了解醫療器械(尿常規、血液分析、生化、心電、B超等醫療下位儀器)的編程流程、編程細節的程序員。
1、得到儀器協議
當我們需要與醫療器械等下位機數據交互時,我們需要知道它用的是哪種協議,這樣才能得到我們想要的數據。當然,沒有協議,我們也能解析,在此步驟的弟三段中我將提到。得到協議后,我們將得到重要的幾樣東西,比如波特率、數據位、停止位等連接參數,是單工通信還是雙工通信,以及數據傳輸協議,是否需要上位機響應才發送有效數據,現在一般機器使用HL7協議,但也有廠家自己定義的協議,比如普康協議。
當我們得到協議,儀器傳過來的數據是我們想要的數據。比如尿液分析儀,我們一般需要尿膽原、潛血、膽紅素、酮體等數據,儀器傳過來的數據中已經包含了這些數據(當然,尿液分析儀一般也沒有工作台),那我們就可以開始步驟3、,開始測試連接階段了。但如果我們需要的不是儀器傳過來的數據,比如B超,就算對接了儀器,得到的也只是圖像,而我們需要的是是否正常、是否有某些疾病的數據,這就要開始步驟2、,從工作台中得到數據。
如果盡力后還是沒有得到協議,可以從網上搜索此種型號儀器的連接參數與協議,實在都得不到,就只能自己觀察返回的數據,取得自己想要的數據了。當然如果工作台提供lis接口(比如很多生化設備工作台都提供lis接口),我們就可以直接從工作台中取數據。還有一種需要使用工作台的情況是,當從儀器中取回的數據不是自己想要的東西時(比如B超),我們就需要用到工作台了。
2、工作台
1、當儀器工作台提供lis接口時,寫個服務,服務的內容就是解析得到的數據與其它需要的操作。服務放在哪里視自己具體的業務需求而定。
2、當儀器返回的數據不是自己所需,工作台也沒提供lis接口時,可從工作台的數據庫取自己所需的數據,如果工作台的數據庫沒有或只包含一部分數據,則可根據工作台的工作機制取需要的數據。比如某B超工作台,儀器返回的信息不是我們所需要的,其access中的數據並沒有包含醫技輸入的B超診察結果,診查結果被保存為一個word文檔——當醫技每保存一個被診查者的信息時,工作台同時保存信息到數據庫與創建名字為數據庫id同名的文件夾,文件夾下的診查結果word文檔。根據其工作機制,我們可以在工作台設備上作一個監聽程序,監聽是否有新文件夾的產生。當有新文件夾產生時,讀取其下的word文檔結果,與讀取數據庫用戶表與文件夾同名的id,則取出我們所有需要的信息。
補充:監聽類: FileSystemWatcher 命名空間: System.IO
3、測試連接
在開始編碼之前,我們需要將rs232線從儀器連接到我們編程的電腦。並下載串口數據調試器,波特率等我們第一步了解到的參數,測試數據是否順利從儀器過來,排除代碼外的出錯信息。然后我們就可以從醫療器械那里傳數據過來了。一些儀器傳輸數據的方法集成到了打印中去,這些熟悉以后自己可以推理出怎么傳輸,但剛開始的時候需要做第一步,得到傳輸的方式。如果下位機需要上位機發送確認字符響應才繼續發送有效數據,
4、編碼階段
.NET Framework中提供了SerialPort 類進行串口操作,所在命名空間: System.IO.Ports,程序集: System(位於 System.dll)
有興趣的朋友可以去看看它的底層實現,微軟已經將實現SerialPort 類的代碼開源到: https://referencesource.microsoft.com/#System/sys/system/io/ports/SerialPort.cs,ae0a3218c6c9f7fe
我們可以將公共部分定義為一個父類PortOperate,繼承此類即不用干復制粘貼等勞力活,將精力集中在解析數據上
,
public class PortOperate
{
protected readonly SerialPort spReceive = new SerialPort(); /// <summary> /// 默認端口號 /// </summary> protected string com = "COM1"; /// <summary> /// 接收串口的緩存 /// </summary> public string ReceivedMsg { get; set; } /// <summary> /// 加載配置文件XML的串口 /// </summary> public PortOperate(string port) { com = port; spReceive.PortName = com; } /// <summary> /// 是否存在端口 /// </summary> /// <returns></returns> public bool IsPost() { //獲取串口端口名稱數組 string[] ports = SerialPort.GetPortNames(); //是否發現端口 bool findPort = false; foreach (string port in ports) { if (port.ToUpper() == com) { findPort = true; break; } } return findPort; } /// <summary> /// 打開端口 /// </summary> /// <returns></returns> public bool Open() { try { if (spReceive == null) { //處理代碼 } if (spReceive.IsOpen) { spReceive.Close(); } spReceive.Open(); return true; } catch (Exception ex) { //處理代碼 return false; } } /// <summary> /// 關閉端口 /// </summary> /// <returns></returns> public bool Close() { try { if (spReceive.IsOpen) { spReceive.Close(); } return true; } catch (Exception) { return false; } } protected abstract void SendMessage();
}
子類繼承父類實現代碼
protected override void SendMsg() { if (Open()) { spReceive.DataReceived += spReceive_DataReceived; } } private void spReceive_DataReceived(object sender, SerialDataReceivedEventArgs e) { bool AllowReceive = true; if (AllowReceive == true) { byte[] ReDatas = new byte[spReceive.BytesToRead]; spReceive.Write(new byte[] { 0x06 }, 0, 1); Thread.Sleep(300); spReceive.Read(ReDatas, 0, ReDatas.Length);//讀取數據 BindData(ReDatas); } else { spReceive.DiscardInBuffer(); } }
查看連接的端口可在我的電腦->設備管理器中查看,也可用代碼實現,查看連接rsr232線的端口都是哪些端口號
public List<string> GetAllPorts() { List<String> allPorts = new List<String>(); foreach (String portName in System.IO.Ports.SerialPort.GetPortNames()) { allPorts.Add(portName); } return allPorts; }
5、測試
當解析醫療儀器項目寫好后,下一步當然是測試,測試數據有沒有被正確解析,有沒有按我們想象中那樣運行。窗體程序或控制台程序調試簡單,斷點即可。但服務項目怎么調試呢?服務項目.net framework提供了installutil.exe調試,我們可以利用它來調試
首先我們需要開啟服務,開啟服務批處理
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe 你的服務項目可執行文件路徑 Net Start ServiceTest //serverinstaller設置的服務名字 sc config ServerTest start= auto pause
批處理執行成功后在vs中依次點擊、調試->附加到進程,附加到批處理對應的exe進程,即可對服務進行調試。
如果不需要服務則可卸載服務,卸載服務批處理:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u 你的服務項目可執行文件路徑
pause