Aiuto - Cerca - Utenti - Calendario
Versione completa: Chiarimenti Sulla Comunicazione Visual Basic-s7200
PLC Forum -> Forums automazione > AUTOMAZIONE > PLC > Siemens > S7-200
sorecaro
salve a tutti e spero che mi possiate aiutare.
sto leggendo un libro di visula basic e sto pensando di creare un sistema di supervisione con vb2005express edition. ho fatto delle ricerche sul forum e ho letto del software PCACESS che per queste applicazioni è molto utile. ho scaricato la demo ma adesso mi trovo al punto di non sapere come continuare, come faccio a mandare un segnale al plc? lo so che la domanda puo essere stupida ma è la prima volta che mi avvicno al mondo di visua basic.
ad esempio si premo un pulsante come faccio ad settare un uscita?
Aleandro2008
CITAZIONE
lo so che la domanda puo essere stupida ma è la prima volta che mi avvicno al mondo di visua basic.


Penso che dovresti partire da un concetto di fondo Visual Basic come altri ambienti è un ambiente RAD ovvero serve per sviluppare

rapidamente applicazioni software, ma salvo questo non conosce alcuna marca o modello di PLC per fare quello che vuoi tu devi possedere

almeno delle librerie di comunicazione per VB, un pò come fanno gli SCADA quando si selezionano i Drive di periferica,

poi per farti un esempio metti un comando di queste librerie nel "Click" codice di un pulsante e invii un dato al PLC,

Il comando potrebbe essere tipo questo:

Private sub Command1_Click ()

OBJ.DT 1000, 1, Valore

end sub

dove Obj è la libreria, 1000 il registro che vuoi settare e "Valore" è il valore da scrivere!

L'esempio lo fatto volutamente in VB6 ma lo puoi trascrivere facilmente in VB.NET...






sorecaro
come faccio ad includere la libreria? sai se cè qualche esempio su cui poter "studiare"?
Gianmario Pedrani
Penso che prima tu debba imparare ad usare visual basic magari leggendo un bel manuale, poi puoi pensare di provare a fare una supervisione... Iniziare a pensare ad una supervisione, senza sapere niente di vb è come costruire una casa partendo dal tetto...
Aleandro2008
Le librerie su Visualbasic si includono a se condo del tipo

da Progetto\Componenti oppure da Progetto\Riferimenti....

Questa è una procedura simile sia per VB6 che per Excel, Word, Power point, Access e più che qualche scada che usa VBA in sottofondo....

in generale il metodo di importazione, salvo la forma e similare per tutti i programmi in tecnologia COM (più conoscita come ActiveX)...

Ti serve anche sapere come si importano su .NET o pensi che girà gira ci arrivi da solo....

Savino
Concordo con Gianmario Pedrani..
QUOTE
come faccio ad includere la libreria? sai se cè qualche esempio su cui poter "studiare"?
Le librerie di solito sono fondate su delle DLLs, quindi dovresti anche saperne come interfacciarti con questa tecnologia.
PCACESS non l'ho mai utilizzato, so che sarebbe un OPC... Poi volendo avresti anche l'option PRODAVE per S7200 per un collegamento punto a punto.
Entrambi sitemi forniscono degli esempi esaurienti per l'utilizzo in ambiente VB e VC++.
sorecaro
tutto quello che dite voi è giustissimo e vi ringrazio molto per l'aiuto che date. il manuale l'ho letto e ho anche create dei semplici sistemi di supervisione. il mio problema è che non trovo niente su come fare ad esempio: mi creo il mio form e gli incollo un pulsante. adesso nella sub del pulsante non so cosa scrivere per fare in modo di settare per esempio un bit. penso che se potrei partire da qualche esempio anche semplice le cose potrebbero andare molto meglio.
il mio problema è che sono autodidatta e non conosco nessuno che mi possa dare un aiuto ho una semplice informazione.
come manuale ho letto visula basic passo passo
Savino
Se utilizzi PRODAVE, allora la DLL d'interfaccia sarebbe la w95_s7.dll....
QUOTE
C:\Windows\System32\w95_s7.dll
Nel Modulo del progetto, devi dichiarare tutti gli entry point d'interfaccia alle funzioni o metodi della DLL... esempio
CODE
Declare Function as200_mb_setbit Lib "w95_s7.dll" (ByVal no As Long, ByVal bitno As Long) As Long
Poi, nella Form..
CODE
no = IDNO.Text  // input
bitno = IDBITNO.Text  // input

res = new_ss(VerbIdx + 1)   // questa funzione fa anche parte della suite
If (res = 0) Then
     res = as200_mb_setbit(no, bitno)
End If
Comunque, trovi tutto sul manuale e progetto di esempio, molto facile wink.gif
Se utilizzi PCACCESS, immagino dovresti creare una connessione del tipo OPC, che sarebbe una struttura un pochino piu'
complessa.... Ci dovrebbe essere un progetto VB e MFC allegato al gruppo di DLL, guarda bene dry.gif
sorecaro
ok grazie guardero meglio. un altra domanda.
se non utilizzo ne prodave e ne pcaccess, ma con il visual basic mi leggo i dati della porta seriale il il plc lo devo impostare sulla comunicazione freeport, giusto??
Savino
QUOTE
comunicazione freeport
su questi genere di collegamenti, sei libero dai protocolli propietari.. ti basta una modalita' di telegramma in ASCII, molto facile da implementare da entrambi lati, PC-PLC. wink.gif
sorecaro
grazie savino per le tue spiegazioni. e scusa se ti faccio domande "banali" ma essendo autodidatta devo leggere manuali e fare prove, e non sempre e' cosi semplice come sembra. ora ho comprato un altro libro su vb2005 visual basic 2005 net.framwork, speriamo che sara utile.
Savino
Si, va bene quello che stai facendo ma e' molto importante anche leggere i manuali dell' interfaccie allegati, insieme ai files sorgenti dati da esempi. Soltanto qui trovi l'info adeguata da incastonare nel tuo applicativo e non su altri manuali ... senza questi esempi, ti sarebbe molto difficile riuscire a fare un bel lavoro (anche per i piu' esperti)... non ti dimenticare che non si tratta solo d' impostare una connessione che gire per 10 sec., 10 min. o 1 ora.. alla fine bisogna che l'applicazione reste un prodotto testato e validato a dovere, per funzionare in modo professionale
Savino
QUOTE
Soltanto qui trovi l'info adeguata da incastonare nel tuo applicativo e non su altri manuali ... senza questi esempi, ti sarebbe molto difficile riuscire a fare un bel lavoro (anche per i piu' esperti)...
Poi, tieni presente che tutte le terminologie usate per una interfaccia (Server name, function names, data types, etc) sono univoche alle loro stesse propieta'..
sorecaro
savino sto seguendo il tuo consiglio e sto leggendo visual basic 2005:il linguaggio e il framework, in più mi sono stampato l'esempio che da pcaccess per visual basic, e ti devo dire che qualcosina sto capendo, ma ancora non riesco a capire come faccio a caricare gli item creati da pcaccess sul visual basic, adesso sto provando a caricarli come database. il problema è che l'esempio dato secondo il mio modesto parere non è molto facile da capire, almeno per me.
ho provato ha realizzare una piccola applicazione con excel e li non ho trovato problemi, anche se devo ammettere che è molto più semplice, comunque qualsiasi consiglio è sempre ben accetto. ti faccio sapere appena ho provato in questa maniera.
un altra cosa, non rieco a comprendere come caricare un opcserver con il visual basic, forse il problema e' tutto li
Savino
QUOTE
capire come faccio a caricare gli item creati da pcaccess sul visual basic
QUOTE
un altra cosa, non rieco a comprendere come caricare un opcserver con il visual basic, forse il problema e' tutto li
Per fare una connessione OPC Client devi seguire univocamente il "modello" definito dallo standard COM.. la specifica la trovi sul manuale.
Ti ho suggerito di seguire rigorosamente il modello struttura elencato nel file dell' esempio demo allegato per una Automation Interface Application (VBA). Dovresti innanzitutto fare una compilazione dell' esempio e metterlo in Run, in modo di riuscire a testarlo e vedere che tutto funziona a dovere. Le demo di solito, forniscono un accesso in lettura ed scrittura di pochi items, forse 4 words, bits.. Poi quando vedi che riesci a gestire questi items, allora ti costruisci un progetto nuovo, seguendo come modello la struttura della sorgente demo, incrementando il numero di items a secondo il tuo bisogno.
QUOTE
l'esempio dato secondo il mio modesto parere non è molto facile da capire, almeno per me
Si'! ma importante che funzioni wink.gif
Se l'esempio funziona, allora fare un alias incrementato viene di conseguenza. smile.gif .. poi, guarda che se ci metti qualche giorno o settimana in piu' rolleyes.gif , visto che sei agli inizi, non sarebbe un grosso problema. Importante e' arrivarci e avere capito quello che hai fatto.
sorecaro
certo l'importante è capire come funziona e perchè funzione. ho letto il manuale e alcune cose adesso sono piu chiare. adesso leggero più profondamente il COM e ti faro sapere come è andata, spero che vada bene laugh.gif
varg
Well, eccomi qua allora prima di tutto ho letto che sei alle prime armi in VB.NET ok non cè problema, chiedo ti e' gia chiaro il concetto di Form, Moduli ecc... ?
Dai l'ok procedo a qualche esempio concreto.

Saluti
varg
Allora... procediamo al primo caso, ovvero uso della DLL LibNoDave senza usare il Wrapper per .NET hai meno potenzialità ma almeno funziona e' iniziamo a capire un po il tutto eventualmente dopo vediamo anche quello con il Wrapper .NET
Per comodità normalmente quando scrivo funzioni o altro legate prettamente a un dispositivo cerco di racchiudere il tutto dentro un Modulo per poterlo Riutilizziare agevolmente.

1. Step Creiamo un modulo es: (ModSiemens.vb)

- Progetto
- Aggiungi Modulo

2. Dobbiamo interfacciarci a una DLL di vecchio stampo e non una appositamente disegnata per .NET quindi dobbiamo dichiarare l'interoperabilita.
- Sul modulo prima della dichiarazione delle stesso (Module modSiemens) scriviamo:

CODICE
Imports System.Runtime.InteropServices


3. MI creo la mia struttura che rappresenterà la mia configurazione del PLC, con vari settaggi legati alla com ecc..

CODICE
    Public Structure PLC_AdrType
        Dim iConnessione As Integer
        Dim sPLC_IP As String
        Dim sPortaSeriale As String
        Dim sBaudRate As String
        Dim sComParity As String
        Dim sConnessione As String
        Dim iMpiPpi As Integer
        Dim ph As Integer
        Dim dInterf As Integer
        Dim dConn As Integer
        Dim retval As Integer
        Dim sMessaggio As String
        Dim lUsedTime As Integer
        Dim iRack As Integer
        Dim iSlot As Integer
        Dim lCommErr As Integer
        Dim lCommOK As Integer
    End Structure


4. Dichiaro le mie costanti che verranno usate in seguito per la configurazione e comunicazione con la DLL

CODICE
' Numero massimo di byte in un'unico telegramma in lettura
    Private Const br1MaxByteRead = 200
    ' Numero massimo di byte in un'unico telegramma in scrittura
    Private Const br1MaxByteWrite = 200
    '
    '    Protocol types to be used with newInterface:
    '
    Private Const daveProtoMPI = 0      '  MPI for S7 300/400
    Private Const daveProtoMPI2 = 1    '  MPI for S7 300/400, "Andrew's version"
    Private Const daveProtoMPI3 = 2    '  MPI for S7 300/400, Step 7 Version, not yet implemented
    Private Const daveProtoPPI = 10    '  PPI for S7 200
    Private Const daveProtoAS511 = 20    '  S5 via programming interface
    Private Const daveProtoS7online = 50    '  S7 using Siemens libraries & drivers for transport
    Private Const daveProtoISOTCP = 122 '  ISO over TCP
    Private Const daveProtoISOTCP243 = 123 '  ISO o?ver TCP with CP243
    Private Const daveProtoMPI_IBH = 223   '  MPI with IBH NetLink MPI to ethernet gateway */
    Private Const daveProtoPPI_IBH = 224   '  PPI with IBH NetLink PPI to ethernet gateway */
    Private Const daveProtoUserTransport = 255 '  Libnodave will pass the PDUs of S7 Communication to user defined call back functions.
    '
    '    ProfiBus speed constants:
    '
    Private Const daveSpeed9k = 0
    Private Const daveSpeed19k = 1
    Private Const daveSpeed187k = 2
    Private Const daveSpeed500k = 3
    Private Const daveSpeed1500k = 4
    Private Const daveSpeed45k = 5
    Private Const daveSpeed93k = 6
    '
    '    S7 specific constants:
    '
    Private Const daveBlockType_OB = "8"
    Private Const daveBlockType_DB = "A"
    Private Const daveBlockType_SDB = "B"
    Private Const daveBlockType_FC = "C"
    Private Const daveBlockType_SFC = "D"
    Private Const daveBlockType_FB = "E"
    Private Const daveBlockType_SFB = "F"
    '
    ' Use these constants for parameter "area" in daveReadBytes and daveWriteBytes
    '
    Private Const daveSysInfo = &H3      '  System info of 200 family
    Private Const daveSysFlags = &H5   '  System flags of 200 family
    Private Const daveAnaIn = &H6      '  analog inputs of 200 family
    Private Const daveAnaOut = &H7     '  analog outputs of 200 family
    Private Const daveP = &H80          ' direct access to peripheral adresses
    Private Const daveInputs = &H81
    Private Const daveOutputs = &H82
    Private Const daveFlags = &H83
    Private Const daveDB = &H84 '  data blocks
    Private Const daveDI = &H85  '  instance data blocks
    Private Const daveV = &H87      ' don't know what it is
    Private Const daveCounter = 28  ' S7 counters
    Private Const daveTimer = 29    ' S7 timers
    Private Const daveCounter200 = 30       ' IEC counters (200 family)
    Private Const daveTimer200 = 31         ' IEC timers (200 family)
    '
    Private Const daveOrderCodeSize = 21    ' Length of order code (MLFB number)
    '
    '    Library specific:
    '
    '
    '    Result codes. Genarally, 0 means ok,
    '    >0 are results (also errors) reported by the PLC
    '    <0 means error reported by library code.
    '
    Private Const daveResOK = 0                        ' means all ok
    Private Const daveResNoPeripheralAtAddress = 1     ' CPU tells there is no peripheral at address
    Private Const daveResMultipleBitsNotSupported = 6  ' CPU tells it does not support to read a bit block with a
    ' length other than 1 bit.
    Private Const daveResItemNotAvailable200 = 3       ' means a a piece of data is not available in the CPU, e.g.
    ' when trying to read a non existing DB or bit bloc of length<>1
    ' This code seems to be specific to 200 family.
    Private Const daveResItemNotAvailable = 10         ' means a a piece of data is not available in the CPU, e.g.
    ' when trying to read a non existing DB
    Private Const daveAddressOutOfRange = 5            ' means the data address is beyond the CPUs address range
    Private Const daveWriteDataSizeMismatch = 7        ' means the write data size doesn't fit item size
    Private Const daveResCannotEvaluatePDU = -123
    Private Const daveResCPUNoData = -124
    Private Const daveUnknownError = -125
    Private Const daveEmptyResultError = -126
    Private Const daveEmptyResultSetError = -127
    Private Const daveResUnexpectedFunc = -128
    Private Const daveResUnknownDataUnitSize = -129
    Private Const daveResShortPacket = -1024
    Private Const daveResTimeout = -1025
    '
    '    Max number of bytes in a single message.
    '
    Private Const daveMaxRawLen = 2048
    '
    '    Some definitions for debugging:
    '
    Private Const daveDebugRawRead = &H1            ' Show the single bytes received
    Private Const daveDebugSpecialChars = &H2       ' Show when special chars are read
    Private Const daveDebugRawWrite = &H4           ' Show the single bytes written
    Private Const daveDebugListReachables = &H8     ' Show the steps when determine devices in MPI net
    Private Const daveDebugInitAdapter = &H10       ' Show the steps when Initilizing the MPI adapter
    Private Const daveDebugConnect = &H20           ' Show the steps when connecting a PLC
    Private Const daveDebugPacket = &H40
    Private Const daveDebugByte = &H80
    Private Const daveDebugCompare = &H100
    Private Const daveDebugExchange = &H200
    Private Const daveDebugPDU = &H400      ' debug PDU handling
    Private Const daveDebugUpload = &H800   ' debug PDU loading program blocks from PLC
    Private Const daveDebugMPI = &H1000
    Private Const daveDebugPrintErrors = &H2000     ' Print error messages
    Private Const daveDebugPassive = &H4000
    Private Const daveDebugErrorReporting = &H8000
    Private Const daveDebugOpen = &H8000
    Private Const daveDebugAll = &H1FFFF


varg
5. Dichiaro le funzioni contenute nelle DLL, attenzione ho adattato solo alcune funzioni non tutte, comunque è in grado di leggere e scrivere tranquillamente
dentro alle DB, se uno vuole convertire tutte le funzione basta sostiruire al posto di as Long un bel as Integer, dato che il VB .NET ha cambiato nome ai tipi di dato.

CODICE
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Integer, ByRef Source As Integer, ByVal Length As Integer)
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer)

    '
    '    Set and read debug level:
    '
    Private Declare Sub daveSetDebug Lib "libnodave.dll" (ByVal level As Long)
    Private Declare Function daveGetDebug Lib "libnodave.dll" () As Long
    '
    ' You may wonder what sense it might make to set debug level, as you cannot see
    ' messages when you opened excel or some VB application from Windows GUI.
    ' You can invoke Excel from the console or from a batch file with:
    ' <myPathToExcel>\Excel.Exe <MyPathToXLS-File>VBATest.XLS >ExcelOut
    ' This will start Excel with VBATest.XLS and all debug messages (and a few from Excel itself)
    ' go into the file ExcelOut.
    '
    '    Error code to message string conversion:
    '    Call this function to get an explanation for error codes returned by other functions.
    '
    '
    ' The folowing doesn't work properly. A VB string is something different from a pointer to char:
    '
    ' Private Declare Function daveStrerror Lib "libnodave.dll" Alias "daveStrerror" (ByVal en As Long) As String
    '
    Private Declare Function daveInternalStrerror Lib "libnodave.dll" Alias "daveStrerror" (ByVal en As Integer) As Integer
    ' So, I added another function to libnodave wich copies the text into a VB String.
    ' This function is still not useful without some code araound it, so I call it "internal"
    Private Declare Sub daveStringCopy Lib "libnodave.dll" (ByVal internalPointer As Integer, ByVal s As String)
    '
    ' Setup a new interface structure using a handle to an open port or socket:
    '
    Private Declare Function daveNewInterface Lib "libnodave.dll" (ByVal fd1 As Integer, ByVal fd2 As Integer, ByVal name As String, ByVal localMPI As Integer, ByVal protocol As Integer, ByVal speed As Integer) As Integer
    '
    ' Setup a new connection structure using an initialized daveInterface and PLC's MPI address.
    ' Note: The parameter di must have been obtained from daveNewinterface.
    '
    Private Declare Function daveNewConnection Lib "libnodave.dll" (ByVal di As Integer, ByVal mpi As Integer, ByVal Rack As Integer, ByVal Slot As Integer) As Integer
    '
    '    PDU handling:
    '    PDU is the central structure present in S7 communication.
    '    It is composed of a 10 or 12 byte header,a parameter block and a data block.
    '    When reading or writing values, the data field is itself composed of a data
    '    header followed by payload data
    '
    '    retrieve the answer:
    '    Note: The parameter dc must have been obtained from daveNewConnection.
    '
    Private Declare Function daveGetResponse Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    '    send PDU to PLC
    '    Note: The parameter dc must have been obtained from daveNewConnection,
    '          The parameter pdu must have been obtained from daveNewPDU.
    '
    Private Declare Function daveSendMessage Lib "libnodave.dll" (ByVal dc As Long, ByVal pdu As Long) As Long
    '******
    '
    'Utilities:
    '
    '****
    '*
    '    Hex dump PDU:
    '
    Private Declare Sub daveDumpPDU Lib "libnodave.dll" (ByVal pdu As Long)
    '
    '    Hex dump. Write the name followed by len bytes written in hex and a newline:
    '
    Private Declare Sub daveDump Lib "libnodave.dll" (ByVal name As String, ByVal pdu As Long, ByVal Length As Long)
    '
    '    names for PLC objects. This is again the intenal function. Use the wrapper code below.
    '
    Private Declare Function daveInternalAreaName Lib "libnodave.dll" Alias "daveAreaName" (ByVal en As Long) As Long
    Private Declare Function daveInternalBlockName Lib "libnodave.dll" Alias "daveBlockName" (ByVal en As Long) As Long
    '
    '   swap functions. They change the byte order, if byte order on the computer differs from
    '   PLC byte order:
    '
    Private Declare Function daveSwapIed_16 Lib "libnodave.dll" (ByVal x As Long) As Long
    Private Declare Function daveSwapIed_32 Lib "libnodave.dll" (ByVal x As Long) As Long
    '
    '    Data conversion convenience functions. The older set has been removed.
    '    Newer conversion routines. As the terms WORD, INT, INTEGER etc have different meanings
    '    for users of different programming languages and compilers, I choose to provide a new
    '    set of conversion routines named according to the bit length of the value used. The 'U'
    '    or 'S' stands for unsigned or signed.
    '
    '
    '    Get a value from the position b points to. B is typically a pointer to a buffer that has
    '    been filled with daveReadBytes:
    '
    Private Declare Function toPLCfloat Lib "libnodave.dll" (ByVal f As Single) As Single
    Private Declare Function daveToPLCfloat Lib "libnodave.dll" (ByVal f As Single) As Long
    '
    ' Copy and convert value of 8,16,or 32 bit, signed or unsigned at position pos
    ' from internal buffer:
    '
    Private Declare Function daveGetS8from Lib "libnodave.dll" (ByRef buffer As Byte) As Long
    Private Declare Function daveGetU8from Lib "libnodave.dll" (ByRef buffer As Byte) As Long
    Private Declare Function daveGetS16from Lib "libnodave.dll" (ByRef buffer As Byte) As Long
    Private Declare Function daveGetU16from Lib "libnodave.dll" (ByRef buffer As Byte) As Long
    Private Declare Function daveGetS32from Lib "libnodave.dll" (ByRef buffer As Byte) As Long
    '
    ' Is there an unsigned long? Or a longer integer than long? This doesn't work.
    ' Private Declare Function daveGetU32from Lib "libnodave.dll" (ByRef buffer As Byte) As Long
    '
    Private Declare Function daveGetFloatfrom Lib "libnodave.dll" (ByRef buffer As Byte) As Single
    '
    ' Copy and convert a value of 8,16,or 32 bit, signed or unsigned from internal buffer. These
    ' functions increment an internal buffer position. This buffer position is set to zero by
    ' daveReadBytes, daveReadBits, daveReadSZL.
    '
    Private Declare Function daveGetS8 Lib "libnodave.dll" (ByVal dc As Long) As Long
    Private Declare Function daveGetU8 Lib "libnodave.dll" (ByVal dc As Integer) As Integer
    Private Declare Function daveGetS16 Lib "libnodave.dll" (ByVal dc As Long) As Long
    Private Declare Function daveGetU16 Lib "libnodave.dll" (ByVal dc As Long) As Long
    Private Declare Function daveGetS32 Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    ' Is there an unsigned long? Or a longer integer than long? This doesn't work.
    'Private Declare Function daveGetU32 Lib "libnodave.dll" (ByVal dc As Long) As Long
    Private Declare Function daveGetFloat Lib "libnodave.dll" (ByVal dc As Long) As Single
    '
    ' Read a value of 8,16,or 32 bit, signed or unsigned at position pos from internal buffer:
    '
    Private Declare Function daveGetS8At Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Long
    Private Declare Function daveGetU8At Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Long
    Private Declare Function daveGetS16At Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Long
    Private Declare Function daveGetU16At Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Long
    Private Declare Function daveGetS32At Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Long
    '
    ' Is there an unsigned long? Or a longer integer than long? This doesn't work.
    'Private Declare Function daveGetU32At Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Long
    Private Declare Function daveGetFloatAt Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Single
    '
    ' Copy and convert a value of 8,16,or 32 bit, signed or unsigned into a buffer. The buffer
    ' is usually used by daveWriteBytes, daveWriteBits later.
    '
    Private Declare Function davePut8 Lib "libnodave.dll" (ByRef buffer As Byte, ByVal Value As Integer) As Integer
    Private Declare Function davePut16 Lib "libnodave.dll" (ByRef buffer As Byte, ByVal Value As Integer) As Integer
    Private Declare Function davePut32 Lib "libnodave.dll" (ByRef buffer As Byte, ByVal Value As Integer) As Integer
    Private Declare Function davePutFloat Lib "libnodave.dll" (ByRef buffer As Byte, ByVal Value As Single) As Integer
    '
    ' Copy and convert a value of 8,16,or 32 bit, signed or unsigned to position pos of a buffer.
    ' The buffer is usually used by daveWriteBytes, daveWriteBits later.
    '
    Private Declare Function davePut8At Lib "libnodave.dll" (ByRef buffer As Byte, ByVal pos As Long, ByVal Value As Long) As Long
    Private Declare Function davePut16At Lib "libnodave.dll" (ByRef buffer As Byte, ByVal pos As Long, ByVal Value As Long) As Long
    Private Declare Function davePut32At Lib "libnodave.dll" (ByRef buffer As Byte, ByVal pos As Long, ByVal Value As Long) As Long
    Private Declare Function davePutFloatAt Lib "libnodave.dll" (ByRef buffer As Byte, ByVal pos As Long, ByVal Value As Single) As Long
    '
    ' Takes a timer value and converts it into seconds:
    '
    Private Declare Function daveGetSeconds Lib "libnodave.dll" (ByVal dc As Long) As Single
    Private Declare Function daveGetSecondsAt Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Single
    '
    ' Takes a counter value and converts it to integer:
    '
    Private Declare Function daveGetCounterValue Lib "libnodave.dll" (ByVal dc As Long) As Long
    Private Declare Function daveGetCounterValueAt Lib "libnodave.dll" (ByVal dc As Long, ByVal pos As Long) As Long
    '
    ' Get the order code (MLFB number) from a PLC. Does NOT work with 200 family.
    '
    Private Declare Function daveGetOrderCode Lib "libnodave.dll" (ByVal en As Long, ByRef buffer As Byte) As Long
    '
    ' Connect to a PLC.
    '
    Private Declare Function daveConnectPLC Lib "libnodave.dll" (ByVal dc As Integer) As Integer
    '
    '
    ' Read a value or a block of values from PLC.
    '
    Private Declare Function daveReadBytes Lib "libnodave.dll" (ByVal dc As Integer, ByVal area As Integer, ByVal AreaNumber As Integer, ByVal start As Integer, ByVal numBytes As Integer, ByVal buffer As Integer) As Integer
    '
    ' Read a long block of values from PLC. Long means too long to transport in a single PDU.
    '
    Private Declare Function daveManyReadBytes Lib "libnodave.dll" (ByVal dc As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long, ByVal buffer As Long) As Long
    '
    ' Write a value or a block of values to PLC.
    '
    Private Declare Function daveWriteBytes Lib "libnodave.dll" (ByVal dc As Integer, ByVal area As Integer, ByVal AreaNumber As Integer, ByVal start As Integer, ByVal numBytes As Integer, ByRef buffer As Byte) As Integer
    '
    ' Write a long block of values to PLC. Long means too long to transport in a single PDU.
    '
    Private Declare Function daveWriteManyBytes Lib "libnodave.dll" (ByVal dc As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long, ByRef buffer As Byte) As Long
    '
    ' Read a bit from PLC. numBytes must be exactly one with all PLCs tested.
    ' Start is calculated as 8*byte number+bit number.
    '
    Private Declare Function daveReadBits Lib "libnodave.dll" (ByVal dc As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long, ByVal buffer As Long) As Long
    '
    ' Write a bit to PLC. numBytes must be exactly one with all PLCs tested.
    '
    Private Declare Function daveWriteBits Lib "libnodave.dll" (ByVal dc As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long, ByRef buffer As Byte) As Long
    '
    ' Set a bit in PLC to 1.
    '
    Private Declare Function daveSetBit Lib "libnodave.dll" (ByVal dc As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal byteAddress As Long, ByVal bitAddress As Long) As Long
    '
    ' Set a bit in PLC to 0.
    '
    Private Declare Function daveClrBit Lib "libnodave.dll" (ByVal dc As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal byteAddress As Long, ByVal bitAddress As Long) As Long
    '
    ' Read a diagnostic list (SZL) from PLC. Does NOT work with 200 family.
    '
    Private Declare Function daveReadSZL Lib "libnodave.dll" (ByVal dc As Long, ByVal ID As Long, ByVal index As Long, ByRef buffer As Byte) As Long
    '
    Private Declare Function daveListBlocksOfType Lib "libnodave.dll" (ByVal dc As Long, ByVal typ As Long, ByRef buffer As Byte) As Long
    Private Declare Function daveListBlocks Lib "libnodave.dll" (ByVal dc As Long, ByRef buffer As Byte) As Long
    Private Declare Function internalDaveGetBlockInfo Lib "libnodave.dll" Alias "daveGetBlockInfo" (ByVal dc As Long, ByRef buffer As Byte, ByVal block_type As Long, ByVal number As Long) As Long
    '
    Private Declare Function daveGetProgramBlock Lib "libnodave.dll" (ByVal dc As Long, ByVal blockType As Long, ByVal number As Long, ByRef buffer As Byte, ByRef Length As Long) As Long
    '
    ' Start or Stop a PLC:
    '
    Private Declare Function daveStart Lib "libnodave.dll" (ByVal dc As Long) As Long
    Private Declare Function daveStop Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    ' Set outputs (digital or analog ones) of an S7-200 that is in stop mode:
    '
    Private Declare Function daveForce200 Lib "libnodave.dll" (ByVal dc As Long, ByVal area As Long, ByVal start As Long, ByVal Value As Long) As Long
    '
    ' Initialize a multivariable read request.
    ' The parameter PDU must have been obtained from daveNew PDU:
    '
    Private Declare Sub davePrepareReadRequest Lib "libnodave.dll" (ByVal dc As Long, ByVal pdu As Long)
    '
    ' Add a new variable to a prepared request:
    '
    Private Declare Sub daveAddVarToReadRequest Lib "libnodave.dll" (ByVal pdu As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long)
    '
    ' Executes the entire request:
    '
    Private Declare Function daveExecReadRequest Lib "libnodave.dll" (ByVal dc As Long, ByVal pdu As Long, ByVal Rs As Long) As Long
    '
    ' Use the n-th result. This lets the functions daveGet<data type> work on that part of the
    ' internal buffer that contains the n-th result:
    '
    Private Declare Function daveUseResult Lib "libnodave.dll" (ByVal dc As Long, ByVal Rs As Long, ByVal resultNumber As Long) As Long
    '
    ' Frees the memory occupied by single results in the result structure. After that, you can reuse
    ' the resultSet in another call to daveExecReadRequest.
    '
    Private Declare Sub daveFreeResults Lib "libnodave.dll" (ByVal Rs As Long)
    '
    ' Adds a new bit variable to a prepared request. As with daveReadBits, numBytes must be one for
    ' all tested PLCs.
    '
    Private Declare Sub daveAddBitVarToReadRequest Lib "libnodave.dll" (ByVal pdu As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long)
    '
    ' Initialize a multivariable write request.
    ' The parameter PDU must have been obtained from daveNew PDU:
    '
    Private Declare Sub davePrepareWriteRequest Lib "libnodave.dll" (ByVal dc As Long, ByVal pdu As Long)
    '
    ' Add a new variable to a prepared write request:
    '
    Private Declare Sub daveAddVarToWriteRequest Lib "libnodave.dll" (ByVal pdu As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long, ByRef buffer As Byte)
    '
    ' Add a new bit variable to a prepared write request:
    '
    Private Declare Sub daveAddBitVarToWriteRequest Lib "libnodave.dll" (ByVal pdu As Long, ByVal area As Long, ByVal AreaNumber As Long, ByVal start As Long, ByVal numBytes As Long, ByRef buffer As Byte)
    '
    ' Execute the entire write request:
    '
    Private Declare Function daveExecWriteRequest Lib "libnodave.dll" (ByVal dc As Long, ByVal pdu As Long, ByVal Rs As Long) As Long
    '
    ' Initialize an MPI Adapter or NetLink Ethernet MPI gateway.
    ' While some protocols do not need this, I recommend to allways use it. It will do nothing if
    ' the protocol doesn't need it. But you can change protocols without changing your program code.
    '
    Private Declare Function daveInitAdapter Lib "libnodave.dll" (ByVal di As Integer) As Integer
    '
    ' Disconnect from a PLC. While some protocols do not need this, I recommend to allways use it.
    ' It will do nothing if the protocol doesn't need it. But you can change protocols without
    ' changing your program code.
    '
    Private Declare Function daveDisconnectPLC Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    '
    ' Disconnect from an MPI Adapter or NetLink Ethernet MPI gateway.
    ' While some protocols do not need this, I recommend to allways use it.
    ' It will do nothing if the protocol doesn't need it. But you can change protocols without
    ' changing your program code.
    '
    Private Declare Function daveDisconnectAdapter Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    '
    ' List nodes on an MPI or Profibus Network:
    '
    Private Declare Function daveListReachablePartners Lib "libnodave.dll" (ByVal dc As Long, ByRef buffer As Byte) As Long
    '
    '
    ' Set/change the timeout for an interface:
    '
    Private Declare Sub daveSetTimeout Lib "libnodave.dll" (ByVal di As Integer, ByVal maxTime As Integer)
    '
    ' Read the timeout setting for an interface:
    '
    Private Declare Function daveGetTimeout Lib "libnodave.dll" (ByVal di As Long)
    '
    ' Get the name of an interface. Do NOT use this, but the wrapper function defined below!
    '
    Private Declare Function daveInternalGetName Lib "libnodave.dll" Alias "daveGetName" (ByVal en As Long) As Long
    '
    ' Get the MPI address of a connection.
    '
    Private Declare Function daveGetMPIAdr Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    ' Get the length (in bytes) of the last data received on a connection.
    '
    Private Declare Function daveGetAnswLen Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    ' Get the maximum length of a communication packet (PDU).
    ' This value depends on your CPU and connection type. It is negociated in daveConnectPLC.
    ' A simple read can read MaxPDULen-18 bytes.
    '
    Private Declare Function daveGetMaxPDULen Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    ' Reserve memory for a resultSet and get a handle to it:
    '
    Private Declare Function daveNewResultSet Lib "libnodave.dll" () As Long
    '
    ' Destroy handles to daveInterface, daveConnections, PDUs and resultSets
    ' Free the memory reserved for them.
    '
    Private Declare Sub daveFree Lib "libnodave.dll" (ByVal Item As Long)
    '
    ' Reserve memory for a PDU and get a handle to it:
    '
    Private Declare Function daveNewPDU Lib "libnodave.dll" () As Long
    '
    ' Get the error code of the n-th single result in a result set:
    '
    Private Declare Function daveGetErrorOfResult Lib "libnodave.dll" (ByVal resultSet As Long, ByVal resultNumber As Long) As Long
    '
    Private Declare Function daveForceDisconnectIBH Lib "libnodave.dll" (ByVal di As Long, ByVal src As Long, ByVal dest As Long, ByVal mpi As Long) As Long
    '
    ' Helper functions to open serial ports and IP connections. You can use others if you want and
    ' pass their results to daveNewInterface.
    '
    ' Open a serial port using name, baud rate and parity. Everything else is set automatically:
    '
    Private Declare Function setPort Lib "libnodave.dll" (ByVal portName As String, ByVal BaudRate As String, ByVal parity As Byte) As Integer
    '
    ' Open a TCP/IP connection using port number (1099 for NetLink, 102 for ISO over TCP) and
    ' IP address. You must use an IP address, NOT a hostname!
    '
    Private Declare Function openSocket Lib "libnodave.dll" (ByVal port As Long, ByVal peer As String) As Long
    '
    ' Open an access oint. This is a name in you can add in the "set Programmer/PLC interface" dialog.
    ' To the access point, you can assign an interface like MPI adapter, CP511 etc.
    '
    Private Declare Function openS7online Lib "libnodave.dll" (ByVal peer As String) As Long
    '
    ' Close connections and serial ports opened with above functions:
    '
    Private Declare Function closePort Lib "libnodave.dll" (ByVal fh As Long) As Long
    '
    ' Close handle opende by opens7online:
    '
    Private Declare Function closeS7online Lib "libnodave.dll" (ByVal fh As Long) As Long
    '
    ' Read Clock time from PLC:
    '
    Private Declare Function daveReadPLCTime Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    ' set clock to a value given by user
    '
    Private Declare Function daveSetPLCTime Lib "libnodave.dll" (ByVal dc As Long, ByRef timestamp As Byte) As Long
    '
    ' set clock to PC system clock:
    '
    Private Declare Function daveSetPLCTimeToSystime Lib "libnodave.dll" (ByVal dc As Long) As Long
    '
    '       BCD conversions:
    '
    Private Declare Function daveToBCD Lib "libnodave.dll" (ByVal dc As Long) As Long
    Private Declare Function daveFromBCD Lib "libnodave.dll" (ByVal dc As Long) As Long



6. Ok intanto vi lascio riflettere e lavorare su questo, appena riesco vado avanti con tutto il discorso.

Saluti
sorecaro
ok grazie molte comincioro a studiare da qui, un altra domanda se non ti dispiace, volendo leggere un ingresso con pcaccess è molto diverso??
varg
son sincero... non conosco pcaccess, ho sudato un po ma poi con le LibNoDave mi sono trovato bene e non ho avuto necessita di cercare altro...
Savino
QUOTE
un altra domanda se non ti dispiace, volendo leggere un ingresso con pcaccess è molto diverso??
biggrin.gif biggrin.gif
Bruno
Scusate se mi intrometto....
domanda per varg, mi sembra di riconoscere alcune cose nei moduli che hai postato e sono felicissimo di sapere di utilizzi del genere, perchè non pubblichi un esempio sviluppato in VB.NET (nella sezione upload/download) ???
Per quanto mi riguarda sto per rilasciare una nuova release dell'esempio in C# in cui completerò l'interfaccia in .NET per la libreria libnodave (in modo da accedere ad alcune funzioni presenti nella DLL, ma non pubblicate per .NET).

Ciao
BR1
varg
Salve, certo che li riconosci ghgh sono i tuoi famigerati esempi reinterpretati per il VB.NET appena riesco pubblico sia il vecchio modulo che avevi fatto per il VB6 adattato per il VB.NET e il modulo che avevi fatto in C# rifatto per il VB.NET, appena aggiorni il modulo in C# dimmi qualcosa cosi sincronizzo il mio in VB.NET !

A dimenticamento una cosa che ho notato nel modulo.... Nella classe conti le connessioni facendo un +1 pero quando chiudi le connessioni non decrementi...

Saluti
varg
Bene ho pubblicato nella Sezione UP/DOWNLOAD del sito i 2 modulini... sono dentro un file .zip

LibNoDaveVBNET01.zip

ce un piccolo txt che vi indica la differenza tra i 2 moduli, poi all'interno di ogni modulo cè una spiegazione un po piu approfondita.

I moduli sono stati sviluppati in Visual Studio 2005.

Testati su macchine XP Prof 32Bit e Vista 32Bit. Su macchine a 64bit hanno problemi molto probabilmente e' un problema della DLL.
Savino
Diciamo che i post per Libnodave potevano essere stati inseriti in questa altra discussione Link, aperta da sorecaro.
Qui si parlava di PCACCESS, che e' un OPC Server, e quindi qualcosa di diverso. Link
Poicche Libnodave non utilizza la tecnologia OPC, e sarebbe un OpenSource software.
sorecaro
sto cercando di capire l'esempio dato da pcaccess in visual basic e qualcosa sono risuscito ad interpretare. allora cominciamo.

Private Sub cmdAddItem_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdAddItem.Click
On Error GoTo ErrorHandler
Dim i As Integer
Dim ErrorFlag As Boolean
Dim ItemObj As OPCSiemensDAAutomation.OPCItem
'UPGRADE_WARNING: Il limite inferiore della matrice ItemIDs è stato cambiato da 1 a 0. Fare clic per ulteriori informazioni: 'ms-.://MS.V***pressCC.v80/dv_commoner/local/redirect.htm?keyword="0F1C9BE1-AF9D-476E-83B1-17D43BECFF20"'
Dim ItemIDs(2) As String
'UPGRADE_WARNING: Il limite inferiore della matrice ItemClientHandles è stato cambiato da 1 a 0. Fare clic per ulteriori informazioni: 'ms-.://MS.V***pressCC.v80/dv_commoner/local/redirect.htm?keyword="0F1C9BE1-AF9D-476E-83B1-17D43BECFF20"'
Dim ItemClientHandles(2) As Integer
Dim Errors() As Integer ' Array for returned Item related errors
ErrorFlag = False

MyItems = MyGroup.OPCItems ' Get OPCItems Collection Object from MyOPCServer

' Initialize the [IN] parameters for the Add Items call
' ItemIDs -> ItemIDs of the Items to add
' ItemClientHandles -> Client defined handles for the Items. The Server sends these handles in the Callbacks
ItemIDs(1) = txtItem2.Text
ItemIDs(2) = txtItem2.Text ' Read ItemId 2 from Text Box
ItemClientHandles(1) = 1
ItemClientHandles(2) = 2
' [OUT] parameters are
' ItemServerHandles -> Server defined handles for the Items. The client must use these handles for all Read/Write calls
' Errors -> Item related errors

' Add Items to the Group
Call MyItems.AddItems(2, ItemIDs, ItemClientHandles, MyItemServerHandles, Errors)

' Check Item Errors
For i = 1 To 2
If Not Errors(i) = 0 Then
MsgBox("Item " & Str(i) & " FAILED. Error Code = " & Str(Errors(i)), MsgBoxStyle.Critical)
ErrorFlag = True
End If
Next

' Continue only if all Items SUCCEEDED
Dim RemoveErrors() As Integer
'UPGRADE_WARNING: Il limite inferiore della matrice RemoveHandles è stato cambiato da 1 a 0. Fare clic per ulteriori informazioni: 'ms-.://MS.V***pressCC.v80/dv_commoner/local/redirect.htm?keyword="0F1C9BE1-AF9D-476E-83B1-17D43BECFF20"'
Dim RemoveHandles(1) As Integer
If ErrorFlag Then
' Remove Succeede Items
For i = 1 To 2
If Errors(i) = 0 Then
RemoveHandles(1) = MyItemServerHandles(i)
Call MyItems.Remove(1, RemoveHandles, RemoveErrors)
End If
Next
Else
' Set Button Enable
cmdAddItem.Enabled = False
cmdRemGroup.Enabled = False
cmdRemItem.Enabled = True
cmdWriteSync.Enabled = True
cmdWriteAsync.Enabled = True
cmdReadSync.Enabled = True
cmdReadAsync.Enabled = True
End If
Exit Sub
questa dovrebbe essere la sub del pulsante Aggiungi Item. l'item di pcaccess viene aggiunto quando nella txt1item viene scritto ad esempio 2,M0.0,bit premo il pulsante aggiunfi item e viene aggiunto ne MYitems .se io cambio la dicitura di txtitem1.text in "2,M0.0,bit" il risultato dovrebbe essere lo stesso??

Private Sub cmdWriteAsync_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdWriteAsync.Click
On Error GoTo ErrorHandler
Dim i As Integer
'UPGRADE_WARNING: Il limite inferiore della matrice Values è stato cambiato da 1 a 0. Fare clic per ulteriori informazioni: 'ms-.://MS.V***pressCC.v80/dv_commoner/local/redirect.htm?keyword="0F1C9BE1-AF9D-476E-83B1-17D43BECFF20"'
Dim Values(2) As Object
Dim Errors() As Integer ' Array for returned Item related errors
Dim CID As Integer ' CancelID, servergenerierter Wert, mit dem die Transaktion identifiziert

' Initialize the [IN] parameters for the SyncWrite call
' Values -> Values to write
'UPGRADE_WARNING: Impossibile risolvere la proprietà predefinita dell'oggetto Values(1). Fare clic per ulteriori informazioni: 'ms-.://MS.V***pressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
Values(1) = txtWriteVal1.Text ' Read Value 1 from Text Box
'UPGRADE_WARNING: Impossibile risolvere la proprietà predefinita dell'oggetto Values(2). Fare clic per ulteriori informazioni: 'ms-.://MS.V***pressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
Values(2) = txtWriteVal2.Text ' Read Value 2 from Text Box
' ItemServerHandles -> Server defined handles from the AddItems call
MyTID = MyTID + 1 ' Increment Transaction ID

' Write Values Asyncronous
Call MyGroup.AsyncWrite(2, MyItemServerHandles, Values, Errors, MyTID, CID)

' Check Item Errors
For i = 1 To 2
If Not Errors(i) = 0 Then MsgBox("Item " & Str(i) & " FAILED. Error Code = " & Str(Errors(i)), MsgBoxStyle.Critical)
Next

Exit Sub
ErrorHandler:
MsgBox(Err.Description & Chr(13) & "Writing Items Asyncronous", MsgBoxStyle.Critical, "ERROR")
End Sub

questa e' la sub del pulsante scrivi valore nell item. se io cambio values(1)=txtwritevall.text in values(1)= 1 penso che nell'item 1 (2,M0.0,bit) mi dovrebbe scrivere il valora 1. ci sono o ho sbagliato tutto??

Rwhite
Ciao, per la prima domanda si, funziona, per la seconda se non ricordo male devi mettere values(1)= "1"
sorecaro
grazie per l'aiuto, se invece voglio leggere il valore di un bit?
Rwhite
Usi la prima part per aggiungere il bit, word, o dword che vuoi leggere e poi usi la sub di lettura sincrona o asincrona
sorecaro
come mai l'esempio con visual basci 2005 non funziona, mi da messaggi di errore
varg
prova a dire quali sono gli errori...
sorecaro
scusa se non ti ho risposto prima ma ho avuto dei dei problemik con fastweb. allora l'errore che mi da e' =IMPOSSIBILE ESEGUIRE IL CAST DI OGGETTI DI TIPO 'SYSTEM.INT32[*] SUL TIPO 'SYSTEM.INT32[]. ADDING ITEM TO THE GROUP.
penso che l'errore sia dovuto ad un fatto di conversione da vb6 a vb2005 perche con vb6 funziona correttamente.
provando cpon vb6 va tutto bene e risesco ad associare un valore ad un item. ma appena mi creo un pulsante nuoivo, gli copio il contenuto della sup di un pulsante del progetto di esempio che dovrebbe scrivere un valore in un item non va, mi dice che l'oggetto non e' associato. ho fatto varie prove ma niente, lo so che chiedo troppo ma se era possibile avere un piccolo esempio completo,sia vb6 o vb2005express edition, che abbia 2 pulsanti, uno che legge un valore, ed un altro che lo scirve perche non rieco a farlo, ho fatto le prove usando excel e va tutto a meraviglia
PLCforum Staff
Questa discussione e' chiusa, la puoi trovare nella nuova sezione PLC raggiungibile a questo indirizzo plc.plcforum.it
PLCforum Staff
Questa discussione e' chiusa, la puoi trovare nella nuova sezione PLC raggiungibile a questo indirizzo plc.plcforum.it
Questa è la versione 'lo-fi' del forum. Per visualizzare la versione completa con molte più informazioni, formattazione ed immagini, per favore clicca qui.