MrC Inserito: 5 luglio 2003 Segnala Inserito: 5 luglio 2003 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: 5 luglio 2003 Segnala Inserita: 5 luglio 2003 (modificato) Ciao MRC,con la spiegazione dei numeri reali ... è assai facile farti la routine:Numeri Reali Modificato: 5 luglio 2003 da Gabriele Corrieri
rguaresc Inserita: 5 luglio 2003 Segnala Inserita: 5 luglio 2003 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...23mantissa e' rappresentato nei 23 bit 22...0, ma non in modo intero:Il bit 22 pesa per 2^(-1), cioe' 0,5Il bit 21 pesa per 2^(-2), cioe' 0,25Il 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_0000espo vale 100_01111_1 --> 143 decimalePer 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
michele86 Inserita: 7 luglio 2003 Segnala Inserita: 7 luglio 2003 Ecco la routine pronta pronta da usare:Function CVT_REAL(FromPLC As String) As DoubleConst conv = 1.19209289550781E-07 'Costante di conversione mantissaDim esp As Long 'Esponente in formato LongDim man As Long 'Mantissa in formato LongDim dec As Long 'Variabile di spostamentoDim num As Double 'Variabile di spostamentoDim ott_str As String 'Ottetto in formato stringaDim ott_num(1 To 4) As Byte 'Array di ottetti in formato byteDim i As Integer 'Contatore ciclo forDim seg As Byte 'Marcatore di segnoFor i = 1 To 4 ott_str = Mid(FromPLC, i, 1) ott_num(i) = Asc(ott_str)Next i'Determino mantissaman = ((ott_num(2) And 127))man = man * (256 ^ 2)For i = 3 To 4 dec = ott_num(i) * (256 ^ (4 - i)) man = man + decNext inum = mannum = num * conv'Determino esponenteesp = ((ott_num(1) And 127) * 2)dec = ((ott_num(2) And 128) / 128)esp = esp + dec'Determino segnoseg = ((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 IfEnd Function
michele86 Inserita: 7 luglio 2003 Segnala Inserita: 7 luglio 2003 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.Quindin.real = CVT_REAL(stringa 4 byte)
dago_ Inserita: 7 luglio 2003 Segnala Inserita: 7 luglio 2003 Ciao MicheleNe approfitto anch'io, ottima funzione.Grazie
Gianmario Pedrani Inserita: 7 luglio 2003 Segnala Inserita: 7 luglio 2003 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;
fabmatt Inserita: 9 luglio 2003 Segnala Inserita: 9 luglio 2003 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
Savino Inserita: 19 luglio 2005 Segnala Inserita: 19 luglio 2005 Salve,Per andare on line con la demo del link sopra indicato bisogna avere la W95_S7.DLL disponibile nel sistema.Saluto.
Marco_Udine Inserita: 19 luglio 2005 Segnala Inserita: 19 luglio 2005 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.
JumpMan Inserita: 20 luglio 2005 Segnala Inserita: 20 luglio 2005 (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: 20 luglio 2005 da JumpMan
Marco_Udine Inserita: 17 agosto 2005 Segnala Inserita: 17 agosto 2005 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...
Marco_Udine Inserita: 17 agosto 2005 Segnala Inserita: 17 agosto 2005 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 FunctionPrivate Sub Command1_Click()Dim a As SingleDim b As Longa = Val(Text1.Text)b = CreaLong(a)Text2.Text = bText3.Text = Hex(End SubHiii 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
Marco_Udine Inserita: 17 agosto 2005 Segnala Inserita: 17 agosto 2005 Ci ho messo 25 minuti per risolvere una cosa che mi assilla da parecchio... GRAZIE !
Marco_Udine Inserita: 17 agosto 2005 Segnala Inserita: 17 agosto 2005 chiaramente funziona anche in lettura....Public Function CreaSingle(ByVal dWord As Long) As Single CopyMemory CreaSingle, dWord, 4&End Function
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora