当前位置: 首页 > article >正文

一个串口通讯的例子(ABX PENTRA 120)

先看通讯数据解析后的内容

这是 ABX PENTRA  120 血球仪的通讯数据,这个数据是通过RS232和设备通讯得到的。通讯协议? 木有,这是法国的一个设备,通讯协议不公开。其实很多设备的通讯都是靠逆向,做LIS,俺至少逆向了 20种设备的协议。下面一个通讯的数据的例子:

这个通讯数据的部分的数据都一眼能看出来。唯一麻烦的就是下面这个图的解析。

这个图的数据来自 

但是 颜色的处理却来自上面的一个数组。

                if pos(strCanal, strPCanalList) > 0 then
                  begin

                    strV := lines[i + 5];
                    strV := copy(strV, 2, length(strV) - 1);

                    for m := 1 to 15 do
                      begin
                        XorY[m] := strtoint(copy(strV, 4 * (m - 1) + 1, 4));
                      end;

                    for m := 1 to 6 do
                      begin
                        ArrRgn1[m].X := XorY[rgnP1[m, 1]];
                        ArrRgn1[m].y := 128 - XorY[rgnP1[m, 2]];
                      end;
                    DeleteObject(myRGN1);
                    myRGN1 := CreatePolygonRgn(ArrRgn1, 6, ALTERNATE);

                    for m := 1 to 6 do
                      begin
                        ArrRgn2[m].X := XorY[rgnP2[m, 1]];
                        ArrRgn2[m].y := 128 - XorY[rgnP2[m, 2]];
                      end;
                    DeleteObject(myRGN2);
                    myRGN2 := CreatePolygonRgn(ArrRgn2, 6, ALTERNATE);

                    for m := 1 to 4 do
                      begin
                        ArrRgn3[m].X := XorY[rgnP3[m, 1]];
                        ArrRgn3[m].y := 128 - XorY[rgnP3[m, 2]];
                      end;
                    DeleteObject(myRGN3);
                    myRGN3 := CreatePolygonRgn(ArrRgn3, 4, ALTERNATE);


                    setlength(binbuf, 1);

                    strV := copy(line, 3, 4096);
                    mybmp := TBitmap.Create;
                    mybmp.HandleType := bmDIB;
                    mybmp.Width := 128;
                    mybmp.Height := 128;
                    mybmp.Canvas.pen.Color := 0;


                    mybmp.Canvas.Brush.Color := clwhite;

                    mybmp.Transparent := true;

                    for j := 0 to 127 do //行
                      for k := 0 to 15 do //列
                        begin
                          str := copy(strV, 32 * j + 2 * k + 1, 2);
                          hextobin(pchar(str), pchar(binbuf), 2);
                          c := byte(binbuf[1]);
                          for m := 0 to 7 do
                            begin
                              b := byte(#128);
                              b := b shr m;
                              b := b and c;
                              if integer(b) <> 0 then
                                begin
                                  if PtInRegion(myRGN1, k * 8 + m, j) then
                                    mybmp.Canvas.Pixels[k * 8 + m, j] := clred
                                  else
                                    if PtInRegion(myRGN2, k * 8 + m, j) then
                                      mybmp.Canvas.Pixels[k * 8 + m, j] := clgreen
                                    else
                                      if PtInRegion(myRGN3, k * 8 + m, j) then
                                        mybmp.Canvas.Pixels[k * 8 + m, j] := clblue
                                      else
                                        mybmp.Canvas.Pixels[k * 8 + m, j] := 0;
                                end;
                            end;
                        end;
                    mybmp.Canvas.TextOut(4, 4, 'LMNE');

                    mybmp.Canvas.MoveTo(0, 0);
                    mybmp.Canvas.lineTo(0, 127);
                    mybmp.Canvas.lineTo(127, 127);
                    mybmp.Canvas.lineTo(127, 0);
                    mybmp.Canvas.lineTo(0, 0);

                    for m := 1 to 10 do
                      begin
                        mybmp.Canvas.MoveTo(XorY[LineSeting1[m, 1]], 128 - XorY[LineSeting1[m, 2]]);
                        mybmp.Canvas.LineTo(XorY[LineSeting1[m, 3]], 128 - XorY[LineSeting1[m, 4]]);
                      end;
                    mybmp.Canvas.pen.Style := psDot;

                    for m := 1 to 3 do
                      begin
                        mybmp.Canvas.MoveTo(XorY[LineSeting2[m, 1]], 128 - XorY[LineSeting2[m, 2]]);
                        mybmp.Canvas.LineTo(XorY[LineSeting2[m, 3]], 128 - XorY[LineSeting2[m, 4]]);
                      end;

               { mybmp.Canvas.Brush.Color := clred;
                FrameRgn(mybmp.Canvas.Handle, myRGN1, mybmp.Canvas.Brush.Handle, 1, 1);

                mybmp.Canvas.Brush.Color := clgreen;
                FrameRgn(mybmp.Canvas.Handle, myRGN2, mybmp.Canvas.Brush.Handle, 1, 1);

                mybmp.Canvas.Brush.Color := clBlue;
                FrameRgn(mybmp.Canvas.Handle, myRGN3, mybmp.Canvas.Brush.Handle, 1, 1);
                }
                    strV := '';
                    MemStr := TMemoryStream.Create;
                    mybmp.PixelFormat := pf4bit;
                    mybmp.SaveToStream(MemStr);
                    mybmp.Free;
                    m := MemStr.Size;
                    setlength(strV, m);
                    MemStr.Seek(0, soBeginning);
                    MemStr.ReadBuffer(Pointer(strV)^, m);
                    Bk.AddItem('LMNE', '', 'P', strV);
                    MemStr.Free;
                    DeleteObject(myRGN1);
                    DeleteObject(myRGN2);
                  end;

              end;

全部代码

library PENTRA120;

uses
  Windows,
  SysUtils,
  Classes,
  Graphics,
  BlockModule in 'BlockModule.pas';

{
    Interval=-1 立即发
    Interval=0 不发
    interval>0 重发
}
var
  in_debug: boolean = false;
  BlockData: string;
  XorY: array[0..16] of integer =
  (
    0,
    22,
    025,
    048,
    035,
    118,
    030,
    068,
    078,
    090,
    070,
    090,
    118,
    029,
    074,
    051,
    128
    );
  LineSeting1: array[1..10, 1..4] of integer =
  ((1, 0, 1, 13), (2, 13, 2, 14), (3, 14, 3, 16), (12, 0, 12, 15), (5, 15, 5, 14), (8, 13, 9, 0), (10, 13, 11, 15), (2, 14, 16, 14), (11, 15, 12, 15), (1, 13, 8, 13));
  LineSeting2: array[1..3, 1..4] of integer =
  ((6, 0, 6, 13), (7, 0, 7, 13), (4, 13, 4, 14));
  rgnP1: array[1..6, 1..2] of integer =
  ((2, 13), (2, 14), (5, 14), (5, 15), (11, 15), (10, 13));
  rgnP2: array[1..6, 1..2] of integer =
  ((8, 13), (10, 13), (9, 15), (12, 15), (12, 0), (11, 0));
  rgnP3: array[1..4, 1..2] of integer =
  ((1, 0), (1, 13), (8, 13), (9, 0));

procedure WriteToFile(Buffer: Pointer; BufferLength: Word; DevName: string; OutFileName: string; var Interval: integer; var SendBuf: PChar);
const
  strACanalList = '!"#$%()*+,-./012345678@ABC';
  codeList: array[1..26] of string =
  ('WBC', 'LYM', 'LYM%', 'MON', 'MON%', 'NEU', 'NEU%', 'EOS', 'EOS%', 'BAS', 'BAS%', 'ALY', 'ALY%', 'LIC', 'LIC%'
    , 'RBC', 'HGB', 'HCT', 'MCV', 'MCH', 'MCHC', 'RDW', 'PLT', 'MPV', 'PCT', 'PDW');
  strGCanalList = 'XYZ';
  strPCanalList = '[';
var
  Bk: TBlock;
  Bks: TBlocks;
  str, strV, binbuf, strCode, strLineFlag: string;
  i, j, m, k, itemIDX: integer;
  line, strCanal, strTemp: string;
  d: tdatetime;
  lines: TStringList;
  a, b, c: byte;
  mybmp: TBitmap;
  MemStr: TMemoryStream;
  ArrRgn1: array[1..6] of TPoint;
  myRGN1: hrgn;
  ArrRgn2: array[1..6] of TPoint;
  myRGN2: hrgn;
  ArrRgn3: array[1..4] of TPoint;
  myRGN3: hrgn;
  debugPath, nowData: string;
  BKend, BKbegin: integer;
begin
  str := PChar(Buffer);

  if in_debug then
    begin
      debugPath := ExtractFilePath(OutFileName);
      if not (copy(debugPath, length(debugPath), 1) = '\') then
        debugPath := debugPath + '\';
      Debugtofile(debugPath, str);
    end;



  BlockData := BlockData + str;
  Bks := TBlocks.Create;


  BKend := pos('V2.6', BlockData);
  while BKend > 0 do
    begin
      nowData := copy(BlockData, 1, BKend);
      delete(BlockData, 1, BKend);
      BKend := pos('V2.6', BlockData);
      BKbegin := pos('RESULT', nowData);
      if BKbegin > 0 then
        begin
          try
            nowData := copy(nowData, BKbegin, length(nowData) - BKbegin);
            lines := TStringList.Create;
            lines.Text := nowData;


            Bk := TBlock.Create;
            Bk.Instrument := DevName;
            i := pos('end', nowData);
            str := copy(nowData, i, length(nowData) - i - 1);
            i := pos('s ', str);
            Bk.SampleID := inttostr(strtoint(trim(Copy(str, i + 2, 4))));
            Bk.SampleType := 'N';

            i := pos('q ', str);
            strV := trim(Copy(str, i + 1, 9));
            d := strtodate(copy(strv, 7, 2) + '-' + copy(strv, 4, 2) + '-' + copy(strv, 1, 2));
            Bk.ExamineDate := formatdatetime('yyyy-mm-dd', d);


            lines := TStringList.Create;
            lines.Text := nowData;
            for i := 0 to 46 do
              begin
                line := lines[i];
                strCanal := line[1];
                itemIDX := pos(strCanal, strACanalList);
                if itemIDX > 0 then
                  begin
                    strV := trim(Copy(line, 2, 7));
                    strTemp := '';
                    for m := 1 to length(StrV) do //本次循环将非'+','-','.',阿拉伯数字去掉
                      if (strV[m] in ['0'..'9']) or (strV[m] = '+') or (strV[m] = '-') or (strV[m] = '.') then
                        strTemp := strTemp + strV[m];
                    strV := strTemp;

                    Bk.AddItem(codeList[itemIDX], '', 'A', strV);
                  end;
                if pos(strCanal, strGCanalList) > 0 then
                  begin

                    if strCanal = 'W' then
                      begin
                        strCode := 'WBC';
                        strLineFlag := ']'
                      end;
                    if strCanal = 'X' then
                      begin
                        strCode := 'RBC';
                        strLineFlag := '^'
                      end;
                    if strCanal = 'Y' then
                      begin
                        strCode := 'PLT';
                        strLineFlag := '_'
                      end;
                    if strCanal = 'Z' then
                      begin
                        strCode := 'BAS';
                        strLineFlag := '`'
                      end;
                    strCanal := line[1];
                    mybmp := TBitmap.Create;
                    mybmp.HandleType := bmDIB;
                    mybmp.Width := 128;
                    mybmp.Height := 32;
                    mybmp.Canvas.moveto(0, 32);
                    mybmp.Canvas.pen.Color := 0;
                    mybmp.Canvas.Brush.Color := clwhite;
                    if pos(strCanal, strGCanalList) > 0 then
                      begin
                        strV := copy(line, 3, 128);


                        m := byte(#30);
                        for k := 10 to 100 do
                          begin
                            b := byte(strV[k]);
                            if integer(b) > integer(m) then m := b;
                          end;

                        a := byte(#32);
                        m := m - a;
                        mybmp.Canvas.moveto(0, 1);
                        mybmp.Canvas.lineto(0, 31);
                        mybmp.Canvas.lineto(127, 31);
                        mybmp.Canvas.moveto(0, 31);
                        for k := 1 to length(strV) do
                          begin
                            b := byte(strV[k]);
                            b := b - a;
                            mybmp.Canvas.LineTo(k, (32 - trunc(integer(b) * 31 / m)))
                          end;

                        mybmp.Canvas.TextOut(100, 2, strCode);

                        try

                          mybmp.Canvas.pen.Style := psDot;

                          strV := '';
                          for k := 35 to 46 do
                            if lines[k][1] = strLineFlag then
                              begin
                                strV := copy(lines[k], 2, length(lines[k]) - 1)
                              end;
                          while length(strv) >= 4 do
                            begin
                              m := strtoint(copy(strv, 1, 4));
                              delete(strv, 1, 4);
                              mybmp.Canvas.MoveTo(m + 1, 0);
                              mybmp.Canvas.lineTo(m + 1, mybmp.Height-1);
                            end;
                        except
                          ;
                        end;
                        MemStr := TMemoryStream.Create;
                        mybmp.PixelFormat := pf4bit;
                        mybmp.SaveToStream(MemStr);
                        mybmp.Free;
                        m := MemStr.Size;
                        setlength(strV, m);
                        MemStr.Seek(0, soBeginning);
                        MemStr.ReadBuffer(Pointer(strV)^, m);
                    //MemStr.SaveToFile('e:\1.bmp');
                        MemStr.Free;

                        Bk.AddItem(strCode, '', 'G', strV);
                      end;
                  end;
                if pos(strCanal, strPCanalList) > 0 then
                  begin

                    strV := lines[i + 5];
                    strV := copy(strV, 2, length(strV) - 1);

                    for m := 1 to 15 do
                      begin
                        XorY[m] := strtoint(copy(strV, 4 * (m - 1) + 1, 4));
                      end;

                    for m := 1 to 6 do
                      begin
                        ArrRgn1[m].X := XorY[rgnP1[m, 1]];
                        ArrRgn1[m].y := 128 - XorY[rgnP1[m, 2]];
                      end;
                    DeleteObject(myRGN1);
                    myRGN1 := CreatePolygonRgn(ArrRgn1, 6, ALTERNATE);

                    for m := 1 to 6 do
                      begin
                        ArrRgn2[m].X := XorY[rgnP2[m, 1]];
                        ArrRgn2[m].y := 128 - XorY[rgnP2[m, 2]];
                      end;
                    DeleteObject(myRGN2);
                    myRGN2 := CreatePolygonRgn(ArrRgn2, 6, ALTERNATE);

                    for m := 1 to 4 do
                      begin
                        ArrRgn3[m].X := XorY[rgnP3[m, 1]];
                        ArrRgn3[m].y := 128 - XorY[rgnP3[m, 2]];
                      end;
                    DeleteObject(myRGN3);
                    myRGN3 := CreatePolygonRgn(ArrRgn3, 4, ALTERNATE);


                    setlength(binbuf, 1);

                    strV := copy(line, 3, 4096);
                    mybmp := TBitmap.Create;
                    mybmp.HandleType := bmDIB;
                    mybmp.Width := 128;
                    mybmp.Height := 128;
                    mybmp.Canvas.pen.Color := 0;


                    mybmp.Canvas.Brush.Color := clwhite;

                    mybmp.Transparent := true;

                    for j := 0 to 127 do //行
                      for k := 0 to 15 do //列
                        begin
                          str := copy(strV, 32 * j + 2 * k + 1, 2);
                          hextobin(pchar(str), pchar(binbuf), 2);
                          c := byte(binbuf[1]);
                          for m := 0 to 7 do
                            begin
                              b := byte(#128);
                              b := b shr m;
                              b := b and c;
                              if integer(b) <> 0 then
                                begin
                                  if PtInRegion(myRGN1, k * 8 + m, j) then
                                    mybmp.Canvas.Pixels[k * 8 + m, j] := clred
                                  else
                                    if PtInRegion(myRGN2, k * 8 + m, j) then
                                      mybmp.Canvas.Pixels[k * 8 + m, j] := clgreen
                                    else
                                      if PtInRegion(myRGN3, k * 8 + m, j) then
                                        mybmp.Canvas.Pixels[k * 8 + m, j] := clblue
                                      else
                                        mybmp.Canvas.Pixels[k * 8 + m, j] := 0;
                                end;
                            end;
                        end;
                    mybmp.Canvas.TextOut(4, 4, 'LMNE');

                    mybmp.Canvas.MoveTo(0, 0);
                    mybmp.Canvas.lineTo(0, 127);
                    mybmp.Canvas.lineTo(127, 127);
                    mybmp.Canvas.lineTo(127, 0);
                    mybmp.Canvas.lineTo(0, 0);

                    for m := 1 to 10 do
                      begin
                        mybmp.Canvas.MoveTo(XorY[LineSeting1[m, 1]], 128 - XorY[LineSeting1[m, 2]]);
                        mybmp.Canvas.LineTo(XorY[LineSeting1[m, 3]], 128 - XorY[LineSeting1[m, 4]]);
                      end;
                    mybmp.Canvas.pen.Style := psDot;

                    for m := 1 to 3 do
                      begin
                        mybmp.Canvas.MoveTo(XorY[LineSeting2[m, 1]], 128 - XorY[LineSeting2[m, 2]]);
                        mybmp.Canvas.LineTo(XorY[LineSeting2[m, 3]], 128 - XorY[LineSeting2[m, 4]]);
                      end;

               { mybmp.Canvas.Brush.Color := clred;
                FrameRgn(mybmp.Canvas.Handle, myRGN1, mybmp.Canvas.Brush.Handle, 1, 1);

                mybmp.Canvas.Brush.Color := clgreen;
                FrameRgn(mybmp.Canvas.Handle, myRGN2, mybmp.Canvas.Brush.Handle, 1, 1);

                mybmp.Canvas.Brush.Color := clBlue;
                FrameRgn(mybmp.Canvas.Handle, myRGN3, mybmp.Canvas.Brush.Handle, 1, 1);
                }
                    strV := '';
                    MemStr := TMemoryStream.Create;
                    mybmp.PixelFormat := pf4bit;
                    mybmp.SaveToStream(MemStr);
                    mybmp.Free;
                    m := MemStr.Size;
                    setlength(strV, m);
                    MemStr.Seek(0, soBeginning);
                    MemStr.ReadBuffer(Pointer(strV)^, m);
                    Bk.AddItem('LMNE', '', 'P', strV);
                    MemStr.Free;
                    DeleteObject(myRGN1);
                    DeleteObject(myRGN2);
                  end;

              end;
            Bks.Add(Bk);

            lines.Free;
          except
            ;
          end;

        end;
    end;
  if Bks.Count > 0 then
    begin
      if in_debug then
        begin
          i := 0;
          while FileExists(debugPath + inttostr(i) + '.dug') do
            i := i + 1;
          Bks.WriteFile(debugPath + inttostr(i) + '.dug');
        end;

      Bks.WriteFile(OutFileName);
    end;
  Bks.Free;
end;

procedure DeviceInit(var interval: integer; var SendBuf: PChar);
begin
  interval := 0;
  SendBuf := '';
end;

function GetDllVersion(DllFile: string; DeviceName: string; Version: string): Boolean;
begin
  if ((DllFile = 'PENTRA120.DLL') and (DeviceName = 'PENTRA120') and (Version = '2.0')) then
    Result := True
  else Result := False;
end;

procedure setdebug(v: boolean);
begin
  in_debug := v;
end;

function getdebug: boolean;
begin
  result := in_debug;
end;
exports
  WriteToFile, DeviceInit, GetDllVersion, setdebug, getdebug;
begin

end.


http://www.kler.cn/a/440872.html

相关文章:

  • 第三篇:HTTP 的烦恼与进化史
  • 《解析 MXNet 的 C++版本在分布式训练中的机遇与挑战》
  • 用Disk Genius备份和还原硬盘
  • Git Bash Here 中文显示乱码的处理方法
  • springboot中——Logback介绍
  • Libevent实现TCP客户端服务器
  • 分布式链路追踪-02-Dapper 论文介绍
  • 《红队和蓝队在网络安全中的定义与分工》
  • HarmonyOS 非线性容器LightWeightMap 常用的几个方法
  • 学习笔记:Verilog连续赋值及在线仿真
  • React Native状态管理器Redux、MobX、Context API、useState
  • RPC 服务与 gRPC 的入门案例
  • Docker的存储卷
  • 鸿蒙Next MVVM思想总结
  • 渗透测试之js利用
  • Redis查询占用空间最大的10个key
  • 在pycharm2024.3.1中配置anaconda3-2024-06环境
  • 005 Qt常用控件Qwidget_下
  • 【研究趋势】Nips2024 多模态论文热点分析
  • Anaconda更改虚拟环境安装路径