Skip to content

Designing the software data logger for MASTECH MS8229

As we said a digit can be translated into a byte like this :
X,a5,a6,a1,a4,a3,a7,a2 [X we ignore it. It is the negative sign or the point]
Notice that the $X in pascal are values in hex

{
The order of the segments is defined like this :
We define digit like this : X,a5,a6,a1,a4,a3,a7,a2 [X we ignore it is negative sign or the point]
////s1////
//      //
s6      s2
//      //
////s7////
//      //
s5      s3
//      //
////s4////
}
function TFormMain.SevenSegmentsToChar(digit:byte) : char;
begin

  if digit=$0 then result := ' '       //00000000->' '
  else if digit=$5 then result := '1'  //00000101->'1'
  else if digit=$5B then result := '2' //01011011->'2'
  else if digit=$1F then result := '3' //00011111->'3'
  else if digit=$27 then result := '4' //00100111->'4'
  else if digit=$3E then result := '5' //00111110->'5'
  else if digit=$7E then result := '6' //01111110->'6'
  else if digit=$15 then result := '7' //00010101->'7'
  else if digit=$7F then result := '8' //01111111->'8'
  else if digit=$3F then result := '9' //00111111->'9'
  else if digit=$7D then result := '0' //01111101->'0'
  else if digit=$68 then result := 'L' //01101000->'L'
  else if digit=$60 then result := 'I' //01100000->'I'
  else if digit=$4E then result := 'o' //01001110->'o'
  else if digit=$72 then result := 'F' //01110010->'F'
  else if digit=$7A then result := 'E' //01111010->'E'
  else result := 'X';

end;

With the help of the masking technique (bitwise AND) the parsing function looks like this :

procedure TFormMain.ParseStatus();
var res : integer;
    digit : byte; // we define digit like this : X,a5,a6,a1,a4,a3,a7,a2 [X we ignore it is negative sign or the point]
    y:double;
begin

  //FIRST SEGMENT
  //Parse the IsRS232
  res := My_Multimeter.Code.Value[0] and $1;  //bitwise operation : masking technique XXXXXXXX AND 00000001 give as 0000000X
  if res = $1 then
    My_Multimeter.Status.IsRS232:=true
  else
    My_Multimeter.Status.IsRS232:=false;

  //Parse the IsAuto
  res := My_Multimeter.Code.Value[0] and $2; //bitwise operation : masking technique XXXXXXXX AND 00000010 give as 000000X0
  if res = $2 then //10 in binary
    My_Multimeter.Status.IsAuto:=true
  else
    My_Multimeter.Status.IsAuto:=false;

  //Parse the AC_DC_None
  res := My_Multimeter.Code.Value[0] and $4; //bitwise operation : masking technique XXXXXXXX AND 00000100 give as 00000X00
  if res = $4 then begin // 100 in binary
    My_Multimeter.Status.AC_DC_None:=DC;
  end else begin //is not DC let's see if it is AC else is NONE
    res := My_Multimeter.Code.Value[0] and $8; //bitwise operation : masking technique XXXXXXXX AND 00001000 give as 0000X000
    if res = $8 then // 1000 in binary
      My_Multimeter.Status.AC_DC_None:=AC
    else
      My_Multimeter.Status.AC_DC_None:=None;
  end;

  //////////////////////////////////////////////////////////////////////////////
  //SECOND+THIRD SEGMENT
  //Parse negative sign
  res := My_Multimeter.Code.Value[1] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
  if res = $8 then // 1000 in binary
    My_Multimeter.Status.ValuePrefix:='-'
  else
  My_Multimeter.Status.ValuePrefix:='';

  //Parse the first digit
  res := My_Multimeter.Code.Value[1] and $7; // XXXXXXXX AND 00000111  give as 00000XXX
  digit := res shl 4;  //00000XXX -> 0XXX0000
  res := My_Multimeter.Code.Value[2] and $F; // YYYYYYYY AND 00001111  give as 0000YYYY
  digit := digit + res; //0XXX0000 + 0000YYYY -> 0XXXYYYY
  My_Multimeter.Status.ValuePrefix += SevenSegmentsToChar(digit);

  //////////////////////////////////////////////////////////////////////////////
  //forth+fifth SEGMENT
  //Parse the .
  res := My_Multimeter.Code.Value[3] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
  if res = $8 then // 1000 in binary
    My_Multimeter.Status.ValuePrefix+='.'
  else
  My_Multimeter.Status.ValuePrefix+='';

  //Parse the second digit
  res := My_Multimeter.Code.Value[3] and $7; // XXXXXXXX AND 00000111  give as 00000XXX
  digit := res shl 4;  //00000XXX -> 0XXX0000
  res := My_Multimeter.Code.Value[4] and $F; // YYYYYYYY AND 00001111  give as 0000YYYY
  digit := digit + res; //0XXX0000 + 0000YYYY -> 0XXXYYYY
  My_Multimeter.Status.ValuePrefix += SevenSegmentsToChar(digit);

  //////////////////////////////////////////////////////////////////////////////
  //sixth+seventh SEGMENT
  //Parse the .
  res := My_Multimeter.Code.Value[5] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
  if res = $8 then // 1000 in binary
    My_Multimeter.Status.ValuePrefix+='.'
  else
  My_Multimeter.Status.ValuePrefix+='';

  //Parse the third digit
  res := My_Multimeter.Code.Value[5] and $7; // XXXXXXXX AND 00000111  give as 00000XXX
  digit := res shl 4;  //00000XXX -> 0XXX0000
  res := My_Multimeter.Code.Value[6] and $F; // YYYYYYYY AND 00001111  give as 0000YYYY
  digit := digit + res; //0XXX0000 + 0000YYYY -> 0XXXYYYY
  My_Multimeter.Status.ValuePrefix += SevenSegmentsToChar(digit);

  //////////////////////////////////////////////////////////////////////////////
  //eight+ninth SEGMENT
  //Parse the .
  res := My_Multimeter.Code.Value[7] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
  if res = $8 then // 1000 in binary
    My_Multimeter.Status.ValuePrefix+='.'
  else
  My_Multimeter.Status.ValuePrefix+='';

  //Parse the forth digit
  res := My_Multimeter.Code.Value[7] and $7; // XXXXXXXX AND 00000111  give as 00000XXX
  digit := res shl 4;  //00000XXX -> 0XXX0000
  res := My_Multimeter.Code.Value[8] and $F; // YYYYYYYY AND 00001111  give as 0000YYYY
  digit := digit + res; //0XXX0000 + 0000YYYY -> 0XXXYYYY
  My_Multimeter.Status.ValuePrefix += SevenSegmentsToChar(digit);

  //10-13 segment
  //Parse the IsDiode
  res := My_Multimeter.Code.Value[9] and $1;  //bitwise operation : masking technique XXXXXXXX AND 00000001 give as 0000000X
  if res = $1 then
    My_Multimeter.Status.IsDiode:=true
  else
    My_Multimeter.Status.IsDiode:=false;

  //Parse the IsSound
  res := My_Multimeter.Code.Value[10] and $1;  //bitwise operation : masking technique XXXXXXXX AND 00000001 give as 0000000X
  if res = $1 then
    My_Multimeter.Status.IsSound:=true
  else
    My_Multimeter.Status.IsSound:=false;

  //Parse the IsHold
  res := My_Multimeter.Code.Value[11] and $1;  //bitwise operation : masking technique XXXXXXXX AND 00000001 give as 0000000X
  if res = $1 then
    My_Multimeter.Status.IsHold:=true
  else
    My_Multimeter.Status.IsHold:=false;

  //Parse the IsRelative
  res := My_Multimeter.Code.Value[11] and $2; //bitwise operation : masking technique XXXXXXXX AND 00000010 give as 000000X0
  if res = $2 then //10 in binary
    My_Multimeter.Status.IsRelative:=true
  else
    My_Multimeter.Status.IsRelative:=false;

  //Parse the IsBattery
  res := My_Multimeter.Code.Value[12] and $1;  //bitwise operation : masking technique XXXXXXXX AND 00000001 give as 0000000X
  if res = $1 then
    My_Multimeter.Status.IsBattery:=true
  else
    My_Multimeter.Status.IsBattery:=false;

  //Parse the unit prefix  K/M/n/u/m (Kilo-,Mega-,nano-,micro-,milli-)
  My_Multimeter.Status.UnitPrefix:='';
  if ComboBoxUnitValue.Text = 'x10Lux' then begin
    My_Multimeter.Status.UnitPrefix:='x10';
  end else if ComboBoxUnitValue.Text = 'AUTO' then begin
    //Parse the Kilo
    res := My_Multimeter.Code.Value[9] and $2; //bitwise operation : masking technique XXXXXXXX AND 00000010 give as 000000X0
    if res = $2 then //10 in binary
      My_Multimeter.Status.UnitPrefix:='K';

    //Parse the Mega
    res := My_Multimeter.Code.Value[10] and $2; //bitwise operation : masking technique XXXXXXXX AND 00000010 give as 000000X0
    if res = $2 then //10 in binary
      My_Multimeter.Status.UnitPrefix:='M';

    //Parse the nano
    res := My_Multimeter.Code.Value[9] and $4; //bitwise operation : masking technique XXXXXXXX AND 00000100 give as 00000X00
    if res = $4 then // 100 in binary
      My_Multimeter.Status.UnitPrefix:='n';

    //Parse the micro
    res := My_Multimeter.Code.Value[9] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
    if res = $8 then // 1000 in binary
      My_Multimeter.Status.UnitPrefix:='u';

    //Parse the milli
    res := My_Multimeter.Code.Value[10] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
    if res = $8 then // 1000 in binary
      My_Multimeter.Status.UnitPrefix:='m';

  end;

  //Parse unitvalue Ohm Hz V A F %
  if ComboBoxUnitValue.Text = 'AUTO' then begin

    //Inizialize....
    My_Multimeter.Status.UnitValue:='';

    //Parse the Hz
    res := My_Multimeter.Code.Value[12] and $2; //bitwise operation : masking technique XXXXXXXX AND 00000010 give as 000000X0
    if res = $2 then //10 in binary
      My_Multimeter.Status.UnitValue:='Hz';

    //Parse the %
    res := My_Multimeter.Code.Value[10] and $4; //bitwise operation : masking technique XXXXXXXX AND 00000100 give as 00000X00
    if res = $4 then  // 100 in binary
      My_Multimeter.Status.UnitValue:='%';

    //Parse the Ohm
    res := My_Multimeter.Code.Value[11] and $4; //bitwise operation : masking technique XXXXXXXX AND 00000100 give as 00000X00
    if res = $4 then // 100 in binary
      My_Multimeter.Status.UnitValue:='Ohm';

    //Parse the Volt
    res := My_Multimeter.Code.Value[12] and $4; //bitwise operation : masking technique XXXXXXXX AND 00000100 give as 00000X00
    if res = $4 then // 100 in binary
      My_Multimeter.Status.UnitValue:='V';

    //Parse the Farad
    res := My_Multimeter.Code.Value[11] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
    if res = $8 then // 1000 in binary
      My_Multimeter.Status.UnitValue:='F';

    //Parse the Ampere
    res := My_Multimeter.Code.Value[12] and $8; // masking technique XXXXXXXX AND 00001000 give as 0000X000
    if res = $8 then // 1000 in binary
      My_Multimeter.Status.UnitValue:='A';

  end else begin //The unitvalue does not included in the code so i have to put it manually
    My_Multimeter.Status.UnitValue:=ComboBoxUnitValue.Text;
  end;

  //calulate value without prefix
  if TryStrToFloat(My_Multimeter.Status.ValuePrefix, y) then begin
    My_Multimeter.Status.ValueNoPrefix:=floattostr(y);
    if My_Multimeter.Status.UnitPrefix = 'K' then
      My_Multimeter.Status.ValueNoPrefix:=floattostr(y*1000)
     else if My_Multimeter.Status.UnitPrefix = 'M' then
       My_Multimeter.Status.ValueNoPrefix:=floattostr(y*1000000)
     else if My_Multimeter.Status.UnitPrefix = 'm' then
       My_Multimeter.Status.ValueNoPrefix:=floattostr(y*0.001)
     else if My_Multimeter.Status.UnitPrefix = 'u' then
       My_Multimeter.Status.ValueNoPrefix:=floattostr(y*0.000001)
     else if My_Multimeter.Status.UnitPrefix = 'n' then
       My_Multimeter.Status.ValueNoPrefix:=floattostr(y*0.000000001);
  end else
    My_Multimeter.Status.ValueNoPrefix:='0';
end;

That's all for now.
We have seen in this article how we defined our data structure from the documentation and how we can "understand the code" and fill the Multimeter status with the captured code information.
In the next article we will see the synaser integration library and the plotting library in order to obtain our final software.
Stay tuned as always !