医疗器械c#上位机开发指引教程
此教程面向的读者:对医疗器械上位机编程有兴趣,或者急需了解医疗器械(尿常规、血液分析、生化、心电、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