PDA

Visualizza la versione completa : [DELPHI] Importare variabile di tipo REAL*4


ganesha
06-04-2007, 11:08
Facendo riferimento a questa discussione (http://forum.html.it/forum/showthread.php?s=&threadid=1105526) come faccio a fare la stessa cosa in delphi?
cioè a leggere un array di 4 byte come se fosse una variabile di tipo Single.

ganesha
06-04-2007, 15:49
:ciauz:

alka
07-04-2007, 17:34
Con le funzioni a disposizione che operano sui bit, non potresti creare una funzione che semplicemente estrae le parti singolarmente dal vettore di byte che ottieni e, successivamente, le dispone all'interno di una variabile di tipo Double?

Voglio dire, se conosci il significato dei singoli bit, allora qual è la difficoltà nell'estrarli in variabili separate e determinare il valore effettivo? :master:

ganesha
11-04-2007, 10:54
quali sono queste funzioni? :master:

forse stai sopravvalutanto la mia conoscenza del linguaggio :D

ganesha
11-04-2007, 11:14
questa sotto è la funzione per leggere una variabile intera di tipo doubleword:

function TModBusConnection.ReadRegister(Adress: Cardinal;
var Value: LongWord): Cardinal;
var
PointerToDWordBuffer: TpDWordBuffer;
begin
f_Adress := Adress;
f_Quantity := 2;
f_FunctionCode := mbfREADREGISTER;
result := Execute;
if result = 0 then begin
PointerToDWordBuffer := @f_ReadBuffer;
Value := MBTSwapDWord(PointerToDWordBuffer[0]);
end;
end;

la funzione MBTSwapDWord serve a scambiare i byte a due a due perché in alcuni plc (o su tutti, non lo so) il byte più significativo e quello meno significativo sono invertiti.


Per le variabili Real ho fatto l'overloading della funzione però non so come modificare lo statement in rosso...

function TModBusConnection.ReadRegister(Adress: Cardinal;
var Value: Single): Cardinal;
var
PointerToDWordBuffer: TpDWordBuffer;
begin
f_Adress := Adress;
f_Quantity := 2;
f_FunctionCode := mbfREADREGISTER;
result := Execute;
if result = 0 then begin
PointerToDWordBuffer := @f_ReadBuffer;
Value := MBTSwapDWord(PointerToDWordBuffer[0]);
end;
end;

ganesha
11-04-2007, 11:36
TDWordBuffer = array[0..62] of LongWord;
TpDWordBuffer = ^TDWordBuffer;


ho definito il seguente tipo:

TSingleBuffer = array[0..62] of Single;
TpSingleBuffer = ^TSingleBuffer;


ho provato così, ma la MBTSwapDWord va in errore e non ho la possibilità di modificarla perché sta in una dll:

function TModBusConnection.ReadRegister(Adress: Cardinal;
var Value: Single): Cardinal;
var
//PointerToDWordBuffer: TpDWordBuffer;
PointerToSingleBuffer: TpSingleBuffer;
begin
f_Adress := Adress;
f_Quantity := 2;
f_FunctionCode := mbfREADREGISTER;
result := Execute;
if result = 0 then begin
PointerToSingleBuffer := @f_ReadBuffer;
Value := MBTSwapDWord(PointerToSingleBuffer[0]);
end;
end;

ganesha
11-04-2007, 13:37
Ho provato così:

function TModBusConnection.ReadRegister(Adress: Cardinal;
var Value: Single): Cardinal;
var
PointerToDWordBuffer: TpDWordBuffer;
PointerToSingleBuffer: TpSingleBuffer;
DWordValue: LongWord;
begin
f_Adress := Adress;
f_Quantity := 2;
f_FunctionCode := mbfREADREGISTER;
result := Execute;
if result = 0 then begin
PointerToDWordBuffer := @f_ReadBuffer;
DWordValue := MBTSwapDWord(PointerToDWordBuffer[0]);
PointerToSingleBuffer := @DWordValue;
Value := PointerToSingleBuffer^[0];
end;
end;
non da errore ma il numero restituito è sbagliato
:master:

ganesha
11-04-2007, 16:49
Ho risolto! :unz:

ho aggiunto questa funzione che scambia, dato un array di byte, i byte pari con quelli dispari:

procedure TModBusConnection.SwapByteArray(ArrayOfByte: TpByteBuffer);
var
i: Integer;
byt: Byte;
begin
for i := 0 to 3 do
begin
if (i mod 2) = 0 then
begin
byt:= ArrayOfByte[i + 1];
ArrayOfByte[i + 1]:= ArrayOfByte[i];
ArrayOfByte[i]:= byt;
end;
end;
end;

poi ho modificato così la ReadRegister:

function TModBusConnection.ReadRegister(Adress: Cardinal;
var Value: Single): Cardinal;
var
PointerToSingleBuffer: TpSingleBuffer;
DWordValue: LongWord;
begin
f_Adress := Adress;
f_Quantity := 2;
f_FunctionCode := mbfREADREGISTER;
result := Execute;
if result = 0 then begin
SwapByteArray(@f_ReadBuffer);
PointerToSingleBuffer := @f_ReadBuffer;
Value := PointerToSingleBuffer^[0];
end;
end;

:ciauz:

alka
14-04-2007, 17:34
Originariamente inviato da ganesha
forse stai sopravvalutanto la mia conoscenza del linguaggio :D
In tal caso, posso solo suggerirti di approfondire il linguaggio. :stordita:



ho aggiunto questa funzione che scambia, dato un array di byte, i byte pari con quelli dispari

In questo caso, diciamo allora che - considerando quanto ho capito della tua soluzione - sono io che ho sopravvalutato il mio stesso grado di comprensione del problema proposto. :D

ganesha
17-04-2007, 13:37
probabilmente dipende da come io ho esposto il problema :D

Loading