How to check the previous value of variable

Hello Experts,
My situation is:
I receive data from rs232 using ComPort in Delphi, I receive it every single secound becouse the transfer of data from RS232 has some errors I`m forced to check the value of 2 variables - one value which has been just transfered and secound value which has been transfered one sec. earlier. I want to do this becouse I`m going to compare these two values and if the difference would be grater then let`s say 100 i won`t save the data to database.
Here is the code which I use to receive and save data from ComPort.
procedure TForm10.ComDataPacket5Packet(Sender: TObject; const Str: string);
var
m1,w1:Double;
Str2,Str3,w,m,rap : String;
begin
  ComDataPacket5.Size:=0;
  ComDataPacket5.StartString:=#02;
  ComDataPacket5.StopString:=#13;
  rap:= FormatDateTime('yyyy-MM-dd',Now)+' '+FormatDateTime('HH:mm:ss',Now);
  Str2 := Copy(Str,4,13);
  m:=Trim(Str2);
  m1:=ConvertFloat(m);
  Str3:=Copy(Str,14,26);
  w:=Trim(Str3);
  w1:=ConvertFloat(w);
 if (Pos('.', FloatToStr(m1)) <= 5) and (Pos('.', FloatToStr(m1)) > 0 ) then
   begin
    with Form1.ADOQuery2, SQL do
        begin
          Close;
          Clear;
          Add('INSERT INTO PRODUKCJA (WAGA,MASA,RATE,DATA,CZAS,RAPORT) VALUES (''6,3-12,8'',:masa,:rate,CONVERT(CHAR(10),GETDATE(),120),CONVERT(CHAR(8),GETDATE(),108),:raport)');
          Parameters.ParamByName('masa').Value := m1;
          Parameters.ParamByName('rate').Value := w1;
          Parameters.ParamByName('raport').Value := rap;
          ExecSQL;
        end;
  Form1.Edit6.Text := FloatToStr(m1);
  Form1.Edit14.Text:=FloatToStr(w1);
  Form1.Chart1.Series[4].AddXY(Time,m1);
  end;
end;
 
Please Experts Pimp my app :))
VaalarAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

MerijnBSr. Software EngineerCommented:
You have to give a little more details:

- what do all the vars mean in your code (m1, w1, Str2, Str3, w, m rap)
- what kind of data are you receiving (what format)
- what do you want to check?
0
VaalarAuthor Commented:
Hello Merlijn
1. Vars:
m:=Trim(Str2); - just to del white spaces
m1:=ConvertFloat(m); - conversion from str to float
the same situation with w and w1
as you can see I`m converting received string from ComPort
Str2 := Copy(Str,4,13); - var for the part of data from ComPort

2. It`s an ascii string
  ComDataPacket5.StartString:=#02;<- start sign for package
  ComDataPacket5.StopString:=#13;<- stop sign for package
3. I want to check what value had the m1 var and compare it with next value of m1
I give you an example:
at 12:01:23 i have got the m1 with value = 121.812
at 12:01:24 I have got the m1 with value = 1211
now i want to compare the m1 value at 12:01:24 and the value at 12:01:23 and if the difference would be greater than 100 i know that the value at 12:01:24 is wrong.
BR
Vaalar
 
0
VaalarAuthor Commented:
The Lenght of string from ComDataPacket is always 26 chars long. I can divide it and in first part i receive weight and in secound rate. That`a why i`m using Str2( chars from 4 to 13 ) and Str3 ( chars from 14 to 26 ). Rap is value for Rave Report so it`s not connected.
BR
Vaalar
0
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

Geert GOracle dbaCommented:
put the 2 variables in the object (TForm10 in your case)
and initialise them the first time
first 2 checks will fail as you don't have old data
obvoiusly you'll to do this for each commport

type
  RLastData = record
    M1_Last: Double;
    M1_Prior: Double;
    W1_Last: Double;
    W1_Prior: Double;
  end;

  TForm10 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    fPort5Data: RLastData;
    procedure InitPortData(var aPortData: RLastData);
    procedure SavePortData(var aPortData: RLastData; M1, W1: Double);
 
  end;

procedure TForm10.FormCreate(Sender: TObject);
begin
  InitPortData(fPort5Data);
end;

procedure TForm10.InitPortData(var aPortData: RLastData);
begin
  with aPortData do
  begin
     M1_Last := 0;
     M1_Prior := 0;
     W1_Last := -1;
     W1_Prior := -1;
  end;
end;

procedure TForm10.SavePortData(var aPortData: RLastData; M1, W1: Double);
begin
  W1_Prior := W1_Last;
  W1_Last := W1;
  M1_Prior := M1_Last;
  M1_Last := M1;
end;

you could then use it like:

  m1:=ConvertFloat(m);
  Str3:=Copy(Str,14,26);
  w:=Trim(Str3);
  w1:=ConvertFloat(w);
  // test here
  if fPort5Data.W1_Prior <> -1 then // check init
  begin
    if fPort5Data.W1_Last > W1 + 100 then ; // your check
  end;
  // end test
 if (Pos('.', FloatToStr(m1)) <= 5) and (Pos('.', FloatToStr(m1)) > 0 ) then
   begin
    with Form1.ADOQuery2, SQL do
        begin
          Close;
          Clear;
          Add('INSERT INTO PRODUKCJA (WAGA,MASA,RATE,DATA,CZAS,RAPORT) VALUES (''6,3-12,8'',:masa,:rate,CONVERT(CHAR(10),GETDATE(),120),CONVERT(CHAR(8),GETDATE(),108),:raport)');
          Parameters.ParamByName('masa').Value := m1;
          Parameters.ParamByName('rate').Value := w1;
          Parameters.ParamByName('raport').Value := rap;
          ExecSQL;
        end;
  Form1.Edit6.Text := FloatToStr(m1);
  Form1.Edit14.Text:=FloatToStr(w1);
  Form1.Chart1.Series[4].AddXY(Time,m1);
  end;
  SavePortData(fPort5Data, m1, w1);
end;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
VaalarAuthor Commented:
Hello Gert,
I have one request, Can you make some description where should i put the code and what is the purpose of using it. Sry for this but I would like to know what I`m doing and why.
Thx again
Vaalar
0
Geert GOracle dbaCommented:
no problem

type
  // this record will be used to store the last data
  RLastData = record
    M1_Last: Double; // Last value  for M1
    M1_Prior: Double; // Next to last value for M1
    W1_Last: Double;  // Last value  for W1
    W1_Prior: Double; // Next to last value for W1
  end;

  TForm10 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    // record variable for storing last data
    fPort5Data: RLastData;
    // initialisation routine
    procedure InitPortData(var aPortData: RLastData);
    // save last data in record variable
    procedure SavePortData(var aPortData: RLastData; M1, W1: Double);
 
  end;

procedure TForm10.FormCreate(Sender: TObject);
begin
  //Initialise record variables
  InitPortData(fPort5Data);
end;

procedure TForm10.InitPortData(var aPortData: RLastData);
begin
  with aPortData do
  begin
     M1_Last := 0;
     M1_Prior := 0;
     W1_Last := -1;
     W1_Prior := -1;
  end;
end;

procedure TForm10.SavePortData(var aPortData: RLastData; M1, W1: Double);
begin
  // Move the data to the next to last data
  W1_Prior := W1_Last;
  M1_Prior := M1_Last;

  // Save the current values in the last data
  W1_Last := W1;
  M1_Last := M1;
end;

you need to initialise the record variables in the FormCreate as this is not done automatically
do this for all the port record variables you define

if W1_Prior = -1 then there is no 2 values yet
you can only check as from the 3rd value

the purpose of using it ?
i based myself on your question ...
you needed the previous data and the data before that of 2 variables
this is one way of doing it

0
VaalarAuthor Commented:
Geert you are really a piece of Expert :)
Thx for all.
Points granted.
and the last question:
should i put your code in this place:

    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
  private
  fPort5Data: RLastData;
    procedure InitPortData(var aPortData: RLastData);
    procedure SavePortData(var aPortData: RLastData; M1, W1: Double);
  public
    { Public declarations }
  end;

var
  Form10: TForm10;
type
  RLastData = record
    M1_Last: Double;
    M1_Prior: Double;
    W1_Last: Double;
    W1_Prior: Double;
  end;

Thx again
BR
Vaalar
0
VaalarAuthor Commented:
Thx for your professional help
0
VaalarAuthor Commented:
I have made it this way:
    procedure FormCreate(Sender: TObject);
        type
  RLastData = record
    M1_Last: Double;
    M1_Prior: Double;
    W1_Last: Double;
    W1_Prior: Double;
  end;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
  private
    fPort5Data: RLastData;
    procedure InitPortData(var aPortData: RLastData);
    procedure SavePortData(var aPortData: RLastData; M1, W1: Double);
  public
    { Public declarations }
  end;

but I`ve got such error:
[DCC Error] RS232_MAIN.pas(76): E2003 Undeclared identifier: 'W1_Prior'
[DCC Error] RS232_MAIN.pas(76): E2003 Undeclared identifier: 'W1_Last'
[DCC Error] RS232_MAIN.pas(78): E2003 Undeclared identifier: 'M1_Prior'
[DCC Error] RS232_MAIN.pas(78): E2003 Undeclared identifier: 'M1_Last'
What I`ve made wrong
0
Geert GOracle dbaCommented:
hmmm, no won't work

RLastData is a type definition

so is TForm10

there are sections for declarations of type

unit Test;

interface

use unit1, unit2, unit3, etc.

const
  // declare const here
  A = 1;
  B = 2;
 
type
  // declare type definitions here
  // record definitions
  RLastData = record end;
 
  // procedural type definitions
  TNotifyEvent = procedure (Sender: TObject) of object;

  // class / form type definitions
  TForm1 = class(TForm) end;

// declare variables here  
var
  VarA: Integer;
  varB: Int64;

implementation

the type definition of TForm10 has a procedure which uses the type definition RLastData
so you need to put the record type definition of RLastData before the type definition of TForm10
it's a definition of what data a variable will hold, not the actual variable itself !

you can manually alter anything in the private,protected and public sections of the TForm10
but don't change anything manually between
  TForm10 = class(TForm)
and // leave this to the Delphi IDE to change
  private

 
 

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.