Link to home
Start Free TrialLog in
Avatar of Vaalar
Vaalar

asked on

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 :))
Avatar of MerijnB
MerijnB
Flag of Netherlands image

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?
Avatar of Vaalar
Vaalar

ASKER

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
 
Avatar of Vaalar

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of Geert G
Geert G
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Vaalar

ASKER

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

Avatar of Vaalar

ASKER

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
Avatar of Vaalar

ASKER

Thx for your professional help
Avatar of Vaalar

ASKER

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