Newsgroup: it.comp.lang.visual-basic
Titolo: [?] VB6 aiuto x Terminale rs232

Ciao... avrei bisogno di aiuto per un problema con un terminale e VB6
L'hardware RS232 mi da una serie di caratteri del comando, ma non riesco a 
separarli e ricevo una linea continua di dati che anche aggiungendo.
La scheda mi manda questa riga tipo:
 A,?,AAA,R 
che riesco a vedere in una semplice textbox descritta sotto.
In pratica dalla scheda ricevo i seguenti comandi
<header>chr(2) binary 00000010
<identifier> lettera A
<separator> carattere virgola
<cmd> AAA  (solitamente tre caratteri)
<separator> sempre la virgola
<data> data = data1<separator>data2<separator>data3<separator>...dataN
<return> chr$(13) 00001101
ma proprio non so come fare per interpretare correttamente, cioè dovrei 
separare queste info che mi da coi separatori della virgola, dovrei separare 
dal chr(2) al chr(13) ogni cosa che entra sulla RS232
qualche d'uno mi potrebbe aiutare?
Nel timer della ricezione ho:
 '---------------------------------
 'Routine di Ricezione/Trasmissione
 If MSComm1.InBufferCount > 0 Then
    car = MSComm1.Input
    TBox.Text = TBox.Text & car
    'Limitazione ampiezza del TextBox per prevenire l'overflow
    If Len(TBox.Text) > 25000 Then
       TBox.Text = Right(TBox.Text, 20000)
    End If
    'Cursore dopo l'ultimo carattere
    TBox.SelStart = Len(TBox.Text)
  End If
 '---------------------------------

 If MSComm1.InBufferCount > 0 Then
Dim car as string, identifier as string, cmd as string
Dim data() as string, counter as integer
car = MSComm1.Input
' Verifica integrita' della stringa
If left (car,1)<> chr(2) or right(car,1)<> chr(13) then
    ' la stringa ricevuta NON e' buona
    exit sub
End if
Identifier = mid(car,2,1)
counter = instr(car,",") identifica la prima virgola
Do
redim data(ubound(data)+1)
  'aumenta di 1 la dimensione della matrice
data(ubound(data)) = mid(car,counter+1,instr(counter +1, data,",")
  'carica un pezzo di dati  in data()
counter = instr(counter+1, car,",")
 ' identifica la prossima virgola
loop until right(data(ubound(data)),1=chr(13)
 ' ripeti il ciclo finche' non trovi il chr(13) che e' la fine.
data(ubound(data)) = left(data(ubound(data)),len(data(ubound(data))-1)
 ' togli il chr(13) dall'ultimo pezzo di dati
' stampa nella finestra di debug i dati trovati
 dim X
for X = 1 to ubound (data)
 debug.print data(x)
next x
debug.print "Numero dati trovati " & ubound(data)
Tieni conto che ho scritto il codice "a braccio", perche' a casa NON ho
visual basic, inoltre di quel punto di domanda nella tua stringa non
ho descrizione....

 ho descrizione....
GRAZIE MILLE.... provo subito a modificare qualche cosa...
si infatti ho dimenticato il "?" della stringa è un altro CMD. Ero riuscito 
con un
MSComm1.InputLen = 11
ma molto instabile perchè ho visto che i comandi cmd1-2-3,....N variano e mi 
complicano la ricerca.
provo subito e grazie per l'aiuto! mi permetto riscrivere se mi blocco da 
qualche parte...
Ciao e grazie!
Anto

> Data(UBound(Data)) = Mid(car, counter + 1, InStr(counter + 1, Data, ","))
Ciao, ringraziando ancora per gli aiuti...
qui su questa linea mi da sull'ultimo DATA, errore "tipo non 
corrispondente"...
cosa sbaglio nel copiare l'esempio?
ps.: Nella "verifica integrità" della stringa, non rischio di perdere i dati 
che seguono se arrivano due stringhe assieme? Non ho potuto provarla per 
l'errore sopra che non riesco a risolvere quindim non saprei cosa succede... 
:-)))
ciao grazie mille!...
---cut esempio---
If MSComm1.InBufferCount > 0 Then
Dim car As String, identifier As String, cmd As String
Dim Data() As String, counter As Integer
car = MSComm1.Input
' Verifica integrita' della stringa
If Left(car, 1) <> Chr(2) Or Right(car, 1) <> Chr(13) Then
   ' la stringa ricevuta NON e' buona
    Exit Sub
End If
identifier = Mid(car, 2, 1)
counter = InStr(car, ",") 'identifica la prima virgola
Do
ReDim Data(UBound(Data) + 1)
  'aumenta di 1 la dimensione della matrice
Data(UBound(Data)) = Mid(car, counter + 1, InStr(counter + 1, Data, ","))
  'carica un pezzo di dati  in data()
counter = InStr(counter + 1, car, ",")
 ' identifica la prossima virgola
Loop Until Right(Data(UBound(Data)), 1) = Chr(13)
 ' ripeti il ciclo finche' non trovi il chr(13) che e' la fine.
Data(UBound(Data)) = Left(Data(UBound(Data)), Len(Data(UBound(Data)) - 1))
 ' togli il chr(13) dall'ultimo pezzo di dati
' stampa nella finestra di debug i dati trovati
Dim X
For X = 1 To UBound(Data)
Debug.Print Data(X)
Next X
Debug.Print "Nr " & UBound(Data) 

 cosa sbaglio nel copiare l'esempio?
Sbagliai io :)
Data(UBound(Data)) = Mid(car, counter + 1, InStr(counter + 1, 
UBound(Data),",")) 

 cosa sbaglio nel copiare l'esempio?
Sbagliai io :)
Data(UBound(Data)) = Mid(car, counter + 1, InStr(counter + 1,
UBound(Data),","))

> ReDim Data(UBound(Data) + 1)
con un indice non compreso nell'intervallo
Ho verificato subito prima un msgbox "car" e ho la stringa perfettamente
chiedo venia per la mia incapacità....!!!!
e di nuovo grazie mille per l'aiuto...
già ora ho la variabile corretta CAR con la stringa corretta
Anto

 con un indice non compreso nell'intervallo
caz...
altro errore mio: nelle prime righe m'e' sfuggito lo zero fra parentesi
Dim data(0) as string, counter as integer 

 altro errore mio: nelle prime righe m'e' sfuggito lo zero fra parentesi
hihihi... no dai sono io che sono na mazza... infatti ste dim le avevo già 
usate.... purtroppo non ci arrivo... sarà l'età... vado avanti....
COMUNQUE LA "CAR" è già fatta e sembra non sbagliare o driplare gli arrivi 
sulla com...
grazie!!!
proseguo...

 If MSComm1.InBufferCount > 0 Then
Dim car as string, identifier as string
Dim data() as string, counter as integer
redim data(0)  ' questo impone alla matrice di essere dinamica
car = MSComm1.Input
poi piu' avanti, al prossimo redim e' necessario aggiungere
"preserve" per conservare il contenuto della variabile (senno' lo azzera)
Do
redim preserve data(ubound(data)+1)


> ReDim Data(UBound(Data) + 1)
errore matrice già dimensionata....
:-))
ciao


aspe, aspe, quello zero NON va' nel dim ma nel redim... leggi l'altra mia 
risposta. 

a spetta che non avevo ancora la modifica sopra.... arrivo...
 hihihi... scusa ancora per il disturbo ma mi stai aiutando ecezzionalmente!
grazie!!!
ciao a frappoco...
Anto
"apipapip" <chi...@me.lo> ha scritto nel messaggio 
news:ge48qm$np2$1...@aioe.org...


  'aumenta di 1 la dimensione della matrice
Benissimo avanzo avanzo piano piano...
Adesso mi va in "loop" nel DO
verificando passo passo, non esce più di qui e si incrucca tutto continuando 
a giorare qua dentro:
Do
ReDim Preserve data(UBound(data) + 1)
  'aumenta di 1 la dimensione della matrice
data(UBound(data)) = Mid(car, counter + 1, InStr(counter + 1, UBound(data), 
","))
  'carica un pezzo di dati  in data()
counter = InStr(counter + 1, car, ",")
 ' identifica la prossima virgola
Loop Until Right(data(UBound(data)), 1) = Chr(13)
come se non ritrovasse il chr(13)....
ci struso un po' ... 

 ci struso un po' ...
Non riesce ad uscire dal loop,
il chr13 c'e' nella stringa d'inizio... ma dal loop non esce... addirittura 
si stinca tutto, devo resettare la task... resta nel loop.
boh... qualche consiglio?
ciao grazie


Eccazz... e' alzahimer, ne sono sicuro ...
loop until right(data(ubound(data)),1=chr(13)
ho cannato: la riga giusta e'
loop until right(data(ubound(data),1)=chr(13)

 loop until right(data(ubound(data),1)=chr(13)
looppa ancora:
Do
  ReDim Preserve data(UBound(data) + 1)
  data(UBound(data)) = Mid(car, counter + 1, InStr(counter + 1, 
UBound(data), ","))
  counter = InStr(counter + 1, car, ",")
Loop Until Right(data(UBound(data)), 1) = Chr(13)
Si ferma ancora qui dentro... e non esce più... ctrl-brk obbligatorio...
Ho aggiunto la parentesi che mancava... ho verificato le variabili ma per il 
resto non capisco, dovrebbe uscire almeno quando ha fatto tutto il ciclo....


In pratica se metto un controllo
Do
msgbox "ubound(data)"
questo avanza all'infinito mentre la stringa è solo di una decina di 
caratteri...

 msgbox "ubound(data)"
eh,, senza virgolette....
:-))
arrivo non si ferma più....
invece dovrebbe fermarsi alla fine della strringa..

"apipapip" <chi...@me.lo> ha scritto nel messaggio 
news:ge4dfr$b0a$1...@aioe.org...

e se aggiungo
Do
ReDim Preserve data(UBound(data) + 1)
data(UBound(data)) = Mid(car, counter + 1, InStr(counter + 1, UBound(data), 
","))
MsgBox data(UBound(data))
il msgbox è sempre vuoto..."" 

apipapip wrote:
[cut]
Ho trovato 1 buco di tempo per provare:
Dim car As String, data() As String, counter As Integer
ReDim data(0)
car = MSComm1.Input
' Verifica integrita' della stringa
If Left(car, 1) <> Chr(2) Or Right(car, 1) <> Chr(13) Then
    ' la stringa ricevuta NON e' buona
    Exit Sub
End If
counter = InStr(car, ",") + 1 ' prima virgola
Do
ReDim Preserve data(UBound(data) + 1)
If InStr(counter, car, ",") - counter <= 0 Then
   data(UBound(data)) = Mid(car, counter)
   Exit Do ' son finite le virgole: esci
  Else
   data(UBound(data)) = Mid(car, counter, InStr(counter, car, ",") - 
counter)
End If
counter = InStr(counter + 1, car, ",") + 1
DoEvents
Loop
data(UBound(data)) = Left(data(UBound(data)), Len(data(UBound(data))) - 1)
Dim X
For X = 1 To UBound(data)
 Debug.Print data(X)
Next X
Debug.Print "Numero dati trovati " & UBound(data)
End Sub
dovrebbe funzionare..... 

 dovrebbe funzionare.....
TROPPO gentile!
Si funziona perfettamente--- PERFETTAMENTE
Ho i dati separati nell'array e i dati numerici del debug.
un'ultima domandina che sicuramente tu saprai assicurarmi chiarezza:
c'e' mezzo di vedere tutto quello che passa direttamente dalla rs232 sul la 
text1.text tipo terminale senza controllare le sequenze ma che sia 
correttamente visto linea per linea ogni output della scheda rs232?
Se guardo il  CAR esce un po' tutto incasinato e perde qualche dato...
Il debug.print non l'ho mai usato... sto cercando di leggere il suo help ma 
ci capisco poco...
Ho provato a mettere:
    TBox = TBox + car + vbCrLf
    TBox.SelStart = Len(TBox.Text)
ma perde molto per strada...
TI RINGRAZIO MOLTISSIMO dei consigli!!!
e grazie anche per il tempo che mi hai dedicato!
Anto

 ma perde molto per strada...
Si, con l'uso del CAR non va a capo normalmente e riceve linee piuttosto 
sconnesse oltre che a perdere un mucchio di caratteri appunto...
Ricordo di aver visto un esempio di terminale RS232 che trattava carattere 
per carattere ma non trovo più l'esempio...
grazie per qualche consiglio...
Anto


Solitamente i caratteri ASCII sotto il 32mo non sono
"stampabili",  cosi' come il 255mo che e' il "cursore" testuale;
puoi fare 2 cose per evitare di "vedere" pasticci, o frulli
la stringa e sostituisci i caratteri "non stampabili" con
degli spazi, oppure trasformi la stringa in una sequenza numerica
(dove numero = carattere).
' sostituisci i caratteri "strani" con spazi
Dim x as integer, stringa2 as string
For x = 1 to len (car)
 If asc(mid(car,x,1)) < 32 or  asc(mid(car,x,1)) = 255 then ' carattere 
strano ?
   Stringa2 = stringa2 & " " 'mettici uno spazio
 Else
   Stringa2 = stringa2 & asc(mid(car,x,1))' metti il carattere
End If
Debug.print stringa2 ' oppure text1.text = stringa2
' costruisci stringa2 come sequenza numerica (esadecimale)
Dim x as integer, stringa2 as string
For x = 1 to len (car)
   Stringa2 = stringa2 & format(hex(asc(mid(car,x,1))) & " ","00")
End If

Franz_aRTiglio wrote:
'ttanaeva....
 ' costruisci stringa2 come sequenza numerica (esadecimale)
 Dim x as integer, stringa2 as string
 For x = 1 to len (car)
   Stringa2 = stringa2 & format(hex(asc(mid(car,x,1))) ,"00") & " "
 End If

"Franz_aRTiglio" <fran...@N0SPAMtin.it> ha scritto nel messaggio 
news:ge6re8$d4v$1...@aioe.org...

Grazie mille... scusa se rispondo solo ora ma ero fuori per ferie tutta la 
settimana....
Questa stringa sicuramente mi potrà servire dato che ho un'altra scheda che 
mi da sulla RS232 dei dati esadecimali in stringhe da 5byte... (per me era e 
risulta arabo lavorare con ste sctringhe per me non in chiaro...)
M a una cosa che mi pone un problema è il seguente:
impostando questa stringa d'entrata come abbiamo fatto sopra nel TR e nelle 
varie modifiche, non rischio di perdere dei caratteri cioè che non riesco a 
"monitorare" nella mia textbox esattamente tutto quanto arriva dalla rs232 
perdendo qualche "stringa per strada"?
Ora infatti uso la seguente che funziona benissimo e la riporto 1:1 così 
magari può servire anche a qualche d'uno d'altro...ma ho come l'impressione 
che qualche cosa venga perso:
Dim car As String, data() As String, counter As Integer
ReDim data(0)
If MSComm1.InBufferCount > 0 Then
car = MSComm1.Input
    If Left(car, 1) <> Chr(2) Or Right(car, 1) <> Chr(13) Then
        Exit Sub
    End If
    car = Mid(car, 2)
    If Mid(car, 5, 3) Like "###" Then Label3.Caption = Mid(car, 5, 3)
    TBox.Text = TBox.Text & car & vbCrLf
    TBox.SelStart = Len(TBox.Text)
End If
Poi verifico sotto come da te consigliatomi, le virgole e i vari dati ivi 
contenuti... ma appunto vedo che ogni tanto monitorando sulla scheda rs232 i 
dati in uscita, ho come l'impressione che ne perda per strada... o che li 
riceva non correttamente premesso che un suo applicativo "EXE" vede tutto 
senza problemi... quindi dalla scheda i dati arrivano correttamente...
qualche idea?
Ciao e grazie ancora deituoi preziosissimi consigli!

"apipapip" <chi...@me.lo> ha scritto nel messaggio 
news:gehdk5$aem$1...@aioe.org...

Secondo me la perdita di dati avviene anche da questo controllo:
    If Left(car, 1) <> Chr(2) Or Right(car, 1) <> Chr(13) Then
        ' la stringa ricevuta NON e' buona
        Exit Sub
    End If
In pratica potrebbe ricevere una parte di stringa con il chr2 o 13 
all'interno e quindi non tenerne conto... finchè il loop della scheda 
hardware non inizia magari casualmente da un chr2... ma non sono sicuro di 
come venga creata la CAR nell'input.
Forse dovrebbe prendere in considerazione tutti i caratteri e ricostruire le 
stringhe varie tra il chr2 e il chr13...all'interno del car1= car1 + car per 
non perdere niente per strada in un suo loop iniziale o sto sbagliando 
tutto?
Forse prendere i caratteri (escludendo forse la primissima stringa la quale 
potrebbe arrivare durante l'avvio del programma e quindi senza il chr2 ma 
ricevere le varie stringhe anche una dopo l'altra e lavorarle di conseguenza 
una dopo l'altra ed aggiungendole alla stringa d'arrivo fino a fine 
esecuzione ed arrivo caratteri.
Ho fatto alcune prove ed effettivamente perde molti caratteri/stringhe per 
strada per il motivo  sopra... come potrei fare per essere sicuro che quel 
che mi passa la SERIALE sia sempre visualizzato correttamente tipo modem...?
Grazie ancora per l'aiuto che mi vorrete dare!
Anto

Ecco che dopo diverse prove cosě sembra che non perdo dati :
Dim car As String, data() As String, counter As Integer
Dim xx As Integer, stringa2 As String
ReDim data(0)
If MSComm1.InBufferCount > 0 Then
        car = MSComm1.Input
 For xx = 1 To Len(car)
    If Mid(car, xx, 1) = Chr(2) Then
        car = Mid(car, 1, xx - 1) + Mid(car, xx + 1)
    End If
    If Mid(car, xx, 1) = Chr(13) Then
        car = Mid(car, 1, xx - 1) + vbCrLf + Mid(car, xx + 1)
    End If
 Next
'==================
'Devo mettere un ulteriore ciclo for per il CHR2 perchč ogni tanto mi 
ritrovo un chr2
'nella finestra tobx.text... mettendo quest'altro for non ce ne sono piů...
'==================
 For xx = 1 To Len(car)
    If Mid(car, xx, 1) = Chr(2) Then
        car = Mid(car, 1, xx - 1) + Mid(car, xx + 1)
    End If
 Next
    TBox.Text = TBox.Text & car
    TBox.SelStart = Len(TBox.Text)
car = ""
'==================================
Cosa potrei migliorare o sostituire?
grazie ancora e ciao!