Vai al contenuto
PLC Forum


Applicazione Visual Studio


Reverendo bit

Messaggi consigliati

del_user_56966
Ma quando cerco di compilare mi da un'errore e mi dice Errore di compilazione Variabile XComm1) non definita

semplice XComm1 non è una variabile ma un oggetto che devi caricare dal menu componenti... :lol:

quindi vai su "Progetto" e poi su "Componenti" (oppure premi CRTL + T) e carica l'oggetto ABS6 - XComm ++ Interface...

non puoi sbagliare c'è solo quello con i "++"

ora l'oggetto si posiziona sulla barra degli oggetti e da li lo devi portare sul form, quando ci fai doppio click sopra entri negli eventi dello stesso...

da li in poi il codice che a scritto Baltimora è valido... ;)

Link al commento
Condividi su altri siti


  • Risposte 91
  • Created
  • Ultima risposta

Top Posters In This Topic

  • del_user_56966

    36

  • baltimora

    27

  • Reverendo bit

    17

  • Savino

    6

Per convertire la word in bit:

CODICE

Private Sub Command1_Click(Index As Integer)

Dim P As Long

p = ModbusRTU1.Read.Register(1) 'leggo il valore della word del primo registro

AdvDisplay1(0).Text = (p And 1) 'estraggo il primo bit e lo scrivo in una casella di testo

AdvDisplay1(1).Text = (p And 2) / 2 'estraggo il secondo bit

AdvDisplay1(2).Text = (p And 4) / 4

AdvDisplay1(3).Text = (p And 8) / 8

AdvDisplay1(4).Text = (p And 16) / 16

AdvDisplay1(5).Text = (p And 32) / 32

AdvDisplay1(6).Text = (p And 64) / 64

AdvDisplay1(7).Text = (p And 128) / 128

AdvDisplay1(8).Text = (p And 256) / 256

AdvDisplay1(9).Text = (p And 512) / 512

AdvDisplay1(10).Text = (p And 1024) / 1024

AdvDisplay1(11).Text = (p And 2048) / 2048

AdvDisplay1(12).Text = (p And 4096) / 4096

AdvDisplay1(13).Text = (p And 8192) / 8192

AdvDisplay1(14).Text = (p And 16384) / 16384

AdvDisplay1(15).Text = (p And 32768) / 32768 'estraggo il sedicesimo bit

'P= è la variabile che contiene il valore della Word letta

End Sub

Per convertire bit in word:

CODICE

Private Sub Forza1_Click()

Dim i As Long

Dim n As Long

n = 0

For i = 0 To 15

n = n + Check1(i).Value * (2 ^ i)

Next

Wordrw.Text = n

ModbusRTU1.WriteRegister 22, n '22 è il registro da scrivere, n è la word da scrivere.

End Sub

baltimora,

Anche se questo funzionarebbe, se dovresti lavorare con 10000 tags ( od anche con 100) come tempo ciclo resultarebbe inaccettabile. Poi, non ci vogliono degli algoritmi, basta ricavare per correspondenza.

Vai su questo Link e scarica una DLL che potresti utilizzare come struttura di dati a quel fine e vedrai che tutto sara' piu' facile e semplificato.

Leggeti il Word16Demo.txt allegato, per capire come utilizzare le funzionalita' della dll, in VB.

Su questo altro Link trovi un'API demo in VB che utilizza a punto la dll.

Modificato: da Savino
Link al commento
Condividi su altri siti

Anche se questo funzionarebbe, se dovresti lavorare con 10000 tags ( od anche con 100) come tempo ciclo resultarebbe inaccettabile. Poi, non ci vogliono degli algoritmi, basta ricavare per correspondenza.

Il codice funziona, perchè prima di postarlo l'ho provato. Sicuramente non è ottimizzato, ma haimè, le mie capacità hanno dei limiti, anche troppi.(Non ho saputo fare di meglio).

Credo comunque che inserito in una sub possa essere richiamato ogni volta che si legge un registro, ottizzando cosi il codice.

Ho scaricato la dll ed ora cerco di comprenderne il funzionamento. In caso contrario questa notte verso le tre ti telefono. Distrurbo?

P.s. L'esempio delle API mi chiede una dll la "KomFort.dll"

ciao

Link al commento
Condividi su altri siti

P.s. L'esempio delle API mi chiede una dll la "KomFort.dll"

Ahh, perche quella demo sarebbe in grado di andare online con i PLC S7300, sfruttando l'interfaccia Prodave.

Comunque, non fare retta, a te non servirebbe. Era soltanto per mostrare la performance della dll.

Se incambio, poi non riesci a lanciare l'API, allora provo a sostituire la demo.

Nel frattempo, seguendo gli esempi sul file.txt di aiuto, vedi se riesci ad impostare qualcosa.

In caso contrario questa notte verso le tre ti telefono. Distrurbo?

Telefona pure. ( tanto il numero non c'e' l'hai ) :)

Link al commento
Condividi su altri siti

del_user_56966
Il codice funziona, perchè prima di postarlo l'ho provato. Sicuramente non è ottimizzato,

Iop farei un passo alla volta, prima cerca di scrivere codice che funziona, poi se è il caso passi ad ottimizzare,

per le poche variabili che supporta lo Zelio in scambio dati con un protocollo come il Modbus RTU, il codice che utilizzi

può andare bene senza problemi, conosco molti Scada che sono molto più lenti.... :lol:

Link al commento
Condividi su altri siti

Spero sia stata "femmena!"..

Purtroppo no, ma questa notte ci riprovo....solo per esserne certo.....

Volendo scrivere il reg. 33 dello zelio, per la scrittura dell'orologio, come si può convertire il valore decimale in word?

Mi spiego meglio,

Ho provato a scrivere il su citato registro per modificare l'ora dello zelio, e volevo inpostarlo alle ore 10:32. In sintesi ho eseguito la vonversione componendo la word con due byte separati, (se non erro i primi 8 bit sono i minuti (da 0 a 7) e i successivi 8 sono le ore (da 8 a 15)). pertanto ho scomposo la cifra 10 in un byte e la cifra 32 in un altro byte, poi li ho all'ineati e convertiti in word ed inviati allo zelio, per scoprire che in realtà l'ora visualizzata sullo zelio non era quella da me impostata.

Non ho compreso la giusta logica per l'impostazione dell'ora. Qualcuno puo spiegarmela?

Grazie

Link al commento
Condividi su altri siti

Questo è il codice che ho utilizzato per la scrittura del registro dell'orologio:

Private Sub Invia_Click()
Dim Ora As Long
Dim minuti As Long
Dim word33(16) As Long
Dim i As Long
Dim h As Long

Ora = Textdata(0).Text     'Leggo l'ora che voglio scrivere da una casella di testo 
minuti = Textdata(1).Text  'Leggo i minuti che voglio scrivere da una casella di testo 


    word33(0) = (minuti And 1)        'Converto i minuti in bit (i primi 8 da 0 a 7)
    word33(1) = (minuti And 2) / 2
    word33(2) = (minuti And 4) / 4
    word33(3) = (minuti And 8) / 8
    word33(4) = (minuti And 16) / 16
    word33(5) = (minuti And 32) / 32
    word33(6) = (minuti And 64) / 64
    word33(7) = (minuti And 128) / 128
    
    word33(8) = (Ora And 1)          'Converto l'ora in bit (da 8  a 15)
    word33(9) = (Ora And 2) / 2
    word33(10) = (Ora And 4) / 4
    word33(11) = (Ora And 8) / 8
    word33(12) = (Ora And 16) / 16
    word33(13) = (Ora And 32) / 32
    word33(14) = (Ora And 64) / 64
    word33(15) = (Ora And 128) / 128
    
'Compongo la word:
    h = 0
    For i = 0 To 15
    h = h + word33(i) * (2 ^ i)
    Next
    wordata.Text = h 'scrivo la word che verrà trasmessa in una casella di testo

server.ModbusRTU1.WriteRegister 33, h     'scrivo il registro 33 con il valore della word
End Sub

Ora i problema è questo:

se voglio impostare l'ora del PLC alle 16,20 eseguendo la conversione di sopra, la word assume un valore di "4116" che equivale alla conversione di 1620, ma sul plc la data viene impostata alle ore 10,15.

ho notato che il "peso" del sistema decimale, convertito in word è diverso. In pratica per impostare l'ora alle 08,10 la word deve avere un valore di 2064.

Non ho ancora compreso la relazione con il sistema decimale.

Modificato: da baltimora
Link al commento
Condividi su altri siti

Baltimora wrote:

Ora i problema è questo:

se voglio impostare l'ora del PLC alle 16,20 eseguendo la conversione di sopra, la word assume un valore di "4116" che equivale alla conversione di 1620, ma sul plc la data viene impostata alle ore 10,15.

ho notato che il "peso" del sistema decimale, convertito in word è diverso. In pratica per impostare l'ora alle 08,10 la word deve avere un valore di 2064.

Non ho ancora compreso la relazione con il sistema decimale.

Dalle mie esperienze con TWIDO,M340 & PREMIUM, dove la data e l' ora sono memorizzate in System Word ed in formato BCD, penso che tu stia dimenticando proprio questo particolare : il BCD.

Altra nota : non mi risulta che con il Modbus (sia RTU che TCP) tu abbia accesso diretto ai registri di sistema (%SW per capirci) : penso che tu debba quindi scrivere i tuoi dati nelle %MW e poi, nel PLC, procedere all' aggiornamento della data/ora.

Modificato: da max.riservo
Link al commento
Condividi su altri siti

Dalle mie esperienze con TWIDO,M340 & PREMIUM, dove la data e l' ora sono memorizzate in System Word ed in formato BCD, penso che tu stia dimenticando proprio questo particolare : il BCD.

Problema risolto.

Il formato della data è in BCD.

Link al commento
Condividi su altri siti

alen

Iop farei un passo alla volta, prima cerca di scrivere codice che funziona, poi se è il caso passi ad ottimizzare,

per le poche variabili che supporta lo Zelio in scambio dati con un protocollo come il Modbus RTU, il codice che utilizzi

può andare bene senza problemi, conosco molti Scada che sono molto più lenti....

baltimora,

Anche se si tratterebbe di solo 1 word, quel codice li' non sarebbe per niente accettabile, poco professionale direi.

La Struttura fondata su quella DLL del mio link, non e' altro che una unione C++ tra una word, 2 bytes e 16 bits. Una forma standard adottata per tutti i costruttori di PLC e dispositivi simili (posso immaginare)

INTEL:

+-------------------------------------+
|                WORD                 |
+--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
+--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+
|     BYTE 1          |    BYTE 0     |
+---------------------+---------------+

/////////

C++
===

    union reg_16bits
        {short int mw_16;
         signed char mb_16[2];
         struct cointainer_16 {
                  
                  unsigned bit0:1;
                  unsigned bit1:1;
                  unsigned bit2:1;
                  unsigned bit3:1;
                  unsigned bit4:1;
                  unsigned bit5:1;
                  unsigned bit6:1;
                  unsigned bit7:1;

                  unsigned bit8:1;
                  unsigned bit9:1;
                  unsigned bit10:1;
                  unsigned bit11:1;
                  unsigned bit12:1;
                  unsigned bit13:1;
                  unsigned bit14:1;
                  unsigned bit15:1;
                  
                                }wd16;
        };
Poi, ti basta dechiarare dei dati del tipo Integer, passare questi alla funzione, e ricavare "per corrispondenza", che vuoldire no tempo di scansione per qualsiasi tipo di conversione
VB
==

Global m_Word16_0 As Integer
Global m_Word16_1 As Integer
Global m_Word16_2 As Integer
Global m_Word16_3 As Integer
..
.

Global mb_0 As Byte
Global mb_1 As Byte
Global bit_31 As Boolean
Global bit_30 As Boolean
Global bit_29 As Boolean
Global bit_28 As Boolean
Global bit_27 As Boolean
Global bit_26 As Boolean
Global bit_25 As Boolean
Global bit_24 As Boolean
Global bit_23 As Boolean
Global bit_22 As Boolean
Global bit_21 As Boolean
Global bit_20 As Boolean
Global bit_19 As Boolean
Global bit_18 As Boolean
Global bit_17 As Boolean
Global bit_16 As Boolean
Global bit_15 As Boolean
Global bit_14 As Boolean
Global bit_13 As Boolean
Global bit_12 As Boolean
Global bit_11 As Boolean
Global bit_10 As Boolean
Global bit_9 As Boolean
Global bit_8 As Boolean
Global bit_7 As Boolean
Global bit_6 As Boolean
Global bit_5 As Boolean
Global bit_4 As Boolean
Global bit_3 As Boolean
Global bit_2 As Boolean
Global bit_1 As Boolean
Global bit_0 As Boolean

Global result As Boolean

////
input da text box

m_Word16_0 = IDDecBoxInput.Text
result = Word16ToByte(m_Word16_0, mb_0, mb_1, bit_15, bit_14, bit_13, bit_12, bit_11, bit_10, bit_9, bit_8, bit_7, bit_6, bit_5, bit_4, bit_3, bit_2, bit_1, bit_0)
...
..


/// 
imput per assegnazione diretta

m_Word16_1 = &H4A1C
result = Word16ToByte(m_Word16_1, mb_0, mb_1, bit_15, bit_14, bit_13, bit_12, bit_11, bit_10, bit_9, bit_8, bit_7, bit_6, bit_5, bit_4, bit_3, bit_2, bit_1, bit_0)
...
..
/////
input da oggetto PLC

m_Word16_2 = ObjectPLC.Offset.Adress 
result = Word16ToByte(m_Word16_2, mb_0, mb_1, bit_15, bit_14, bit_13, bit_12, bit_11, bit_10, bit_9, bit_8, bit_7, bit_6, bit_5, bit_4, bit_3, bit_2, bit_1, bit_0)
...
..

Va bene, no e' una forzatura, tempo per ottimizzare forse ne avrai.

Ma c'e' una bella differenza tra ottimizzare il codice, e scrivere un modo professionale.

Ma si', puo fare come vuoi, ma se scrivi del codice cosi', posso immaginare tutto il resto.

Comunque, se fai una ricerca nel forum su VB, mi sa che gli utenti ifachsoftware e dago_ hanno anche esposto delle strutture simili alle unioni del C++ fatte in VB.

Modificato: da Savino
Link al commento
Condividi su altri siti

max.riservo

Dalle mie esperienze con TWIDO,M340 & PREMIUM, dove la data e l' ora sono memorizzate in System Word ed in formato BCD, penso che tu stia dimenticando proprio questo particolare : il BCD.

Questo e' standard per tutti i PLCs.

Link al commento
Condividi su altri siti

Savino wrote:

Poi, ti basta dechiarare dei dati del tipo Integer, passare questi alla funzione, e ricavare "per corrispondenza", che vuoldire no tempo di scansione per qualsiasi tipo di conversione

Francamente non ho capito il significato di questa affermazione ......

Per Savino

alcune considerazione sul tuo codice in VB :

- le variabili dichiarate come Global sono da utilizzarsi il meno possibile (si usano solo per quelle 'poche' vaiabili che devono essere viste da tutto il programma);

- non è molto elegante dichiarare 32 variabili (bit_0,bit_1, etc) funzionalmente uguali : è molto meglio utilizzare un array (Dim Bits(0 to 31) as boolean);

Modificato: da max.riservo
Link al commento
Condividi su altri siti

max.riservo,

Le tue considerazioni sono fuori del proposito di quello che ho voluto intendere.

Io non sono qui per discuttere di stessura di codice elegante in VB, solo per spiegare qualcosa altro che tu vedo non sei stato capace di arrivare, mi riferisco a ricavare "per corrispondenza",

Se tu non hai capito cosa vuoldire, guarda meglio lasciare perdere.

la stessura di codice che ho postato in VB, sono soltanto uno esempio molto molto banale per dimostrare appunto l'uso della DLL.

Certo che le dichiarazioni globali vengono fatte sul modulo, e poi le dichiarazione delle varaibili bool sono state fatte in quel modo e non come array, per esporrere il fatto con una espiegazione al piu banale possibile di quello che realmente ho voluto dire.

Certo che non mi sono preocupato di tanto, per quanto riguarda il resto.

Non sono qui per spiegare appunto, come se dichiarano le variabili in VB.

Ma visto che tu sei stato un pignolo in merito che ti sei permesso di parlare cosi ( non capendo il nocciolo fondamentale del proposito), e allora forse ti consideri uno esperto di VB, vai avanti e porta una soluzione elegante en linea con una simile struttura di dati come una unione tra una word, 2 bytes e 16 bits.

Dopodiche', alla fine vedrai che imparerai a capire e afferrerai il concetto di cosa vuoldire ricavare " per corrispondenza"

Grazie.

Modificato: da Savino
Link al commento
Condividi su altri siti

- non è molto elegante dichiarare 32 variabili (bit_0,bit_1, etc) funzionalmente uguali : è molto meglio utilizzare un array (Dim Bits(0 to 31) as boolean

max.riservo,

Vedi sono rismasto chiediendomi se tu, che non hai capito cosa vuoldire ricavere per corrispondenza, sai cosa vuoldire una word, 2 bytes and 16 bits.

Prima tutto a me servivano 16 bool e non 32, quindi li ho anche scritto delle bool in piu.

Poi, ho preferito dechiarare le 16 variabile in quel modo, per dare un quadro piu dittagliato per quello che intendevo dire, ed anche e nel modo come doveva essere utilizzato.

Niente, resto in attessa del tuo codice "elegante" per leggere a bit, a byte da una word.

;)

Modificato: da Savino
Link al commento
Condividi su altri siti

del_user_56966

Solo una piccola nota, una differenza fondamentale tra l'uso classico "all in one" di un programma scada

e l'uso con tecnologia XComm sta proprio nel fatto che quello che il programma svolge interessa relativamente

al server visto che la tecnologia è creata "without reference" ovvero senza riferimenti tra processi,

in questo caso se la routin di decodifica gira +/- veloce al sistema non interessa molto..

questo si identifica come sistema multiprocesso che è un passo più avanti del multitask in se!... ;)

Link al commento
Condividi su altri siti

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