Designing the software data logger for MASTECH MS8229 part2

Making DMM
Making DMM

In this third and last article of this series we will add two libraries in our Lazarus project and the event handling.
The compiled project can be found at TrustFm website.
We are going to use the synaser library (part of synapse) for the serial communication and the PlotPanel in order to plot our real time graph.
For synaser we are going to add only the "synaser.pas" file into our project.

For the PlotPanel we need to add the "plotpanel.pas" file into our project.

More informations for synaser can be found here and for PlotPanel here

So we need to add to the uses the needed classes :

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, ComCtrls, Spin, Buttons,
  //Serial
  Synaser,
  //Plot
  Plotpanel;

For synaser we are going to define two global variables :
BlockSerial : TBlockSerial;
Timeout : integer; //in ms

DMM Data Logger
DMM Data Logger

 

The connection procedure is pretty self explanatory.
We are creating the object BlockSerial of the TBlockSerial class.
Now we can play around with the attributes of the BlockSerial object.
Notice that we are using the values found at the official documentation.
The IsConnected is a global boolean as well.

procedure TFormMain.Connect(ComPort:string);
begin
  Blockserial:=TBlockserial.Create;
  BlockSerial.RaiseExcept:=true;
  try
    BlockSerial.Connect(ComPort);
    BlockSerial.Config(2400,8,'N',0,false,false);  //These values work with the DMM MS8229
    IsConnected := true;
    StatusBar.Panels.Items[0].Text:='Status : CONNECTED';
  except
     on E : Exception do begin
       ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
       IsConnected := false;
       StatusBar.Panels.Items[0].Text:='Status : CONNECTION ERROR';
     end;
  end;
end;

Time for the disconnection procedure :

procedure TFormMain.Disconnect();
begin
  BlockSerial.Purge;
  BlockSerial.Free;
  IsConnected := false;
  StatusBar.Panels.Items[0].Text:='Status : DISCONNECTED';
end;

Now it is time to implement the GetCode procedure.
We are going to read byte by byte using the BlockSerial.RecvByte command.
Once we read one byte the first thing to do is to calculate it's segment number :

segment := TempByte shr 4; // //XXXXYYYY->0000XXXX get the segment number

Then if the segment number is 1 we are good to go and we read the rest 13 bytes byte by byte using BlockSerial.RecvByte.
If the segment is between 2 and 14 then we need to ignore 14-segment number bytes in order to find the starting byte (segment 1).

procedure TFormMain.GetCode();
var TempByte: byte;
    segment: integer;
    i:integer;
    ignorebytes:integer;
begin
  if (BlockSerial.LastError <> 0) then Exit;
  if BlockSerial.CanRead(Timeout) then begin

    TempByte := BlockSerial.RecvByte(Timeout);
    segment := TempByte shr 4; //XXXXYYYY->0000XXXX get the segment number
    if segment = 1 then begin
      My_Multimeter.Code.Value[0] := TempByte;
      for i:=1 to 13 do begin //read the rest 13 bytes
        My_Multimeter.Code.Value[i] := BlockSerial.RecvByte(Timeout);
      end;
    end else begin

      if (segment > 1) and (segment <= 14) then begin

        ignorebytes:=14-segment;
        if ignorebytes>0 then begin
          for i:=1 to ignorebytes do begin
            BlockSerial.RecvByte(Timeout); //ignore 14-segment bytes
          end;
        end;

        TempByte := BlockSerial.RecvByte(Timeout); //try again to read the segment 1 
        segment := TempByte shr 4; //XXXXYYYY->0000XXXX get the segment number
        if segment = 1 then begin
          My_Multimeter.Code.Value[0] := TempByte;
          for i:=1 to 13 do begin //read the rest 13 bytes
            My_Multimeter.Code.Value[i] := BlockSerial.RecvByte(Timeout);
          end;
        end;

      end;

    end;
  end;
end;

I hope that this reading method is clear enough. Of course you can use your reading method as well.