Vai al contenuto
PLC Forum

Partecipa anche tu alla Live su Youtube martedì 28/01/2025 per festeggiare i 24 anni di PLC Forum

Per ulteriori informazioni leggi questa discussione: https://www.plcforum.it/f/topic/326513-28012025




Supervisione Di Siemens S7 300 - (Sviluppo software in visual basic)


Messaggi consigliati

Inserito:

Per comunicare con S7 300 uso una libreria venduta da una ditta che si chiama sintesi www.sintesi.com , e mi trovo molto bene .

Unico problema è nel leggere/scrivere dati in formato virgola mobile (real) .

Provate a scrivere un numero real (es. 1.5) e leggerlo in DINT

(viene qualcosa come 45637292) .

Vorrei fare una funzione in VB che facesse questa conversione , in modo da dribblare il problema .

Che senso hanno i 32 bit del formato REAL ?

Immagino che abbiano n bit x mantissa e n bit x esponente ...

Mi suggeriite un algoritmo per fare la conversione ?

Grazie


Gabriele Corrieri
Inserita: (modificato)

Ciao MRC,

con la spiegazione dei numeri reali ... è assai facile farti la routine:

Numeri Reali

Modificato: da Gabriele Corrieri
Inserita:

Non conosco abbastanza VB per dare il codice, mi limito a descrivere i numeri REAL.

I numeri IEEE Floating Point usano tutti i 32 bit. Numera i bit da destra a sinistra da 0 a 31.

Il bit 31 rappresenta il segno e lo puoi copiare tale e quale nel DINT di destinazione.

Tolto il segno un numero FP e' rappresentato entro il registro a 32 bit come 1,mantissa X 2 ^(espo-127)

espo e' rappresentato in binario normale dagli 8 bit 30...23

mantissa e' rappresentato nei 23 bit 22...0, ma non in modo intero:

Il bit 22 pesa per 2^(-1), cioe' 0,5

Il bit 21 pesa per 2^(-2), cioe' 0,25

Il bit 20 pesa per 2^(-3), cioe' 0,125

..........

Il bit 0 pesa per 2^(-23)

Per fare un esempio il numero 123456.0 risulta codificato in binario nel registro REAL come:

0100_0111_1111_0001_0010_0000_0000_0000

espo vale 100_01111_1 --> 143 decimale

Per la mantissa 111_0001_0010_0000_0000_0000 ci sono:

2^(-1) + 2^(-2) + 2^(-3) + 2^(-7) + 2^(-10)

0,5 + 0,25 + 0,125 + 0,0078125 + 0,0009765625 = 0,8837890625

Infine 1,8837890625 X 2^(143-127) = 123456

Inserita:

Ecco la routine pronta pronta da usare:

Function CVT_REAL(FromPLC As String) As Double

Const conv = 1.19209289550781E-07 'Costante di conversione mantissa

Dim esp As Long 'Esponente in formato Long

Dim man As Long 'Mantissa in formato Long

Dim dec As Long 'Variabile di spostamento

Dim num As Double 'Variabile di spostamento

Dim ott_str As String 'Ottetto in formato stringa

Dim ott_num(1 To 4) As Byte 'Array di ottetti in formato byte

Dim i As Integer 'Contatore ciclo for

Dim seg As Byte 'Marcatore di segno

For i = 1 To 4

ott_str = Mid(FromPLC, i, 1)

ott_num(i) = Asc(ott_str)

Next i

'Determino mantissa

man = ((ott_num(2) And 127))

man = man * (256 ^ 2)

For i = 3 To 4

dec = ott_num(i) * (256 ^ (4 - i))

man = man + dec

Next i

num = man

num = num * conv

'Determino esponente

esp = ((ott_num(1) And 127) * 2)

dec = ((ott_num(2) And 128) / 128)

esp = esp + dec

'Determino segno

seg = ((ott_num(1) And 128) / 128)

If seg = 0 Then

CVT_REAL = (1 + num) * (2 ^ (esp - 127))

Else

CVT_REAL = -((1 + num) * (2 ^ (esp - 127)))

End If

End Function

Inserita:

ah scusa mi ero dimenticato come usare la routine

"FromPLC" è il parametro, stringa a 4 caratteri, che contiene i 32 bit del REAL.

Il risultato della funzione è il numero reale gia convertito.

Quindi

n.real = CVT_REAL(stringa 4 byte)

Inserita:

Ciao Michele

Ne approfitto anch'io, ottima funzione.

Grazie :)

Gianmario Pedrani
Inserita:

non so se le funzioni che tu utilizzi sono simili a prodave, ma se utilizzi prodave ed delphi puoi usare queste

funzioni

function ReadReal(Low_Word: Word; High_Word: Word):Single;

var

Rec: array [0..1] of Word;

begin

try

Rec[0] := Swap(High_Word);

Rec[1] := Swap(Low_Word) ;

Move(Rec,Result,SizeOf(Result));

except

Result := 0;

end;

end;

procedure WriteReal(FloatNr:Single; var Low_Word: Word; var High_Word: Word);

var

Rec: array [0..1] of Word;

begin

try

Move(FloatNr,Rec,SizeOf(FloatNr));

Low_Word := Swap(Rec[1]);

High_Word := Swap(Rec[0]);

except

Low_Word := 0;

High_Word := 0;

end;

end;

;)

Inserita:

Anche io ho fatto una routin per leggere i numeri reali, con Prodave non sono riuscito a leggere questi numeri. La soluzione adottata comunque è un pò diversa ma simile alla vostra. Ciao

  • 2 years later...
Inserita:

Salve,

Per andare on line con la demo del link sopra indicato bisogna avere la W95_S7.DLL disponibile nel sistema.

Saluto.

Inserita:

chi si è cimentato nel fare il contrario ?

cioè dal numero reale creare i 4 byte da spedire al plc e in pratica strivere un real con quella sintassi ???

io ci ho provato..ma ho subito desistito.

Inserita: (modificato)

Provate un po’ a vedere se funziona questo:

Private Declare Sub CopyMemory Lib "kernel32" _
      Alias "RtlMoveMemory" (pDest As Any, pSource As Any, _
      ByVal ByteLen As Long)



Public Function Real(ByVal dWord As Long) As Single
    CopyMemory Real, dWord, 4&
End Function

Modificato: da JumpMan
  • 4 weeks later...
Inserita:

ottima idea...

non va proprio bene come l'hai scritta... bisogna lavorarci sopra.

ma l'idea di sfruttare il copy mem è notevole.

questo pomeriggio ci lavoro sopra e vi so dire.

Grazie...

Inserita:

CASPITA FUNZIONA...

Private Declare Sub CopyMemory Lib "kernel32" _

Alias "RtlMoveMemory" (pDest As Any, pSource As Any, _

ByVal ByteLen As Long)

Public Function CreaLong(ByVal dWord As Single) As Long

CopyMemory CreaLong, dWord, 4&

End Function

Private Sub Command1_Click()

Dim a As Single

Dim b As Long

a = Val(Text1.Text)

b = CreaLong(a)

Text2.Text = b

Text3.Text = Hex(B)

End Sub

Hiii Hiii c'e' più codice scritto per visualizzare il risultato che quello per eseguire la conversione !

Lo stesso dovrebbe valere per la lettura... basta fare viceversa

Inserita:

Ci ho messo 25 minuti per risolvere una cosa che mi assilla da parecchio... GRAZIE !

Inserita:

chiaramente funziona anche in lettura....

Public Function CreaSingle(ByVal dWord As Long) As Single

CopyMemory CreaSingle, dWord, 4&

End Function

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...