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
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.