PDA

View Full Version : [VB6] gestione buffer mscomm


aduri
16-11-2009, 22:20
Premetto che non conosco molto bene questo sw, io per lo più traffico con i compilatori MikroC e Mikrobasic relativo ai microcontrollori PIC.
Sono riuscito a leggere dei segnali analogici convertirli in digitale a 10bit e inviarli attraverso la seriale e visualizzarli su LCD e su Yperterminal.
Ora sto combattendo con l'interfaccia col PC.
Sto provando con VB6 e con Excel ma ho difficoltà.
Il mio intendimento è quello di porre su un grafico cartesiano tre variabili acquisite dagli adc del pic.
Più precisamente un tracciacurve x valvole dove Ianodica in ordinata, Vanodica in ascissa in funzione di diverse tensioni di griglia.

Qualcuno mi può dare qualche spunto e stralcio di codice per gestire i buffer dalla porta seriale?
Sono 253 variabili testo (5 caratteri) a gruppi di 3 con virgola e punto e virgola usati come separatori.

es: " 1023, 45, 945; 1021, 4, 45; ecc...."

Grazie
Antonio

MarcoGG
17-11-2009, 08:50
Devi anzitutto individuare ed estrarre i singoli valori dalla stringa del buffer :

Dim buffer As String
buffer = "1023, 45, 945; 1021, 4, 45;"

Dim terne() As String
terne = Split(buffer, ";")

Dim i As Integer
Dim j As Integer
Dim terna As String
Dim valoriTerna() As String
Dim valoreTerna As Integer

For i = 0 To UBound(terne)
terna = terne(i)
valoriTerna = Split(terna, ",")
For j = 0 To UBound(valoriTerna)
valoreTerna = CInt(Trim(valoriTerna(j)))
MsgBox "Terna " & i & " - Valore " & j & " : " & valoreTerna
Next j
Next i

Poi non è chiaro come vuoi utilizzarli per il grafico. Puoi appoggiarti ad Excel, oppure disegnare il grafico su un controllo WinForm di VB6...

aduri
17-11-2009, 09:14
Innanzitutto grazie della risposta.
Proverò ad usarla, intanto avevo tirato giù questo sw per
cercare di fare da solo e vado un passo alla volta.
Ho cominciato con la lettura del buffer ed ho il primo problema, apro il programma e invio i dati ma OnComm() non li rileva se chiudo il programma e lo riapro comincia a leggere il buffer e lo visualizza su txtRicezione.


Private Sub Command1_Click()
End
End Sub

Private Sub Form_Load()
' Apre la porta seriale
MSComm1.CommPort = 1
MSComm1.Settings = "9600,n,8,1"
On Error Resume Next
MSComm1.PortOpen = True
If Err Then
MsgBox "Impossibile aprire la porta" & MSComm1.CommPort & vbCrLf & Error$
End If
MSComm1.RThreshold = 1
End Sub

Private Sub MSComm1_OnComm()
Dim Messaggio$
Messaggio$ = MSComm1.Input
If Len(Messaggio$) Then
txtRicezione = txtRicezione.Text & Messaggio$
End If
End Sub

Per ciò che riguarda il grafico preferirei excel ma non so come agganciarlo a VB6 o in alternativa si può usare VBA direttamente in excel?

Grazie
Antonio

MarcoGG
17-11-2009, 11:52
Beh, direi che ti manca praticamente il 90% del programma... :p

Comunque, considerando anche il fatto della porta seriale, di cosa c'è di là e di come funziona o mal-funziona... E' un po' impossibile per me capire cosa vada storto.
Butto lì un'ipotesi : provare ad eseguire alcuni tentativi temporizzati di lettura, all'avvio del programma, il che significa : leggere N volte ad intervalli di tempo T, finchè la lettura non va a buon fine, ossia usare un Timer...

aduri
27-11-2009, 12:03
Ho stravolto tutto quello fatto fino ad ora comunque l'obbiettivo è lo stesso;
vorrei quindi caricare in un foglio excel le tre serie di 84 punti partendo dalla cella A1-A84, B1-B84 e C1-C84.
Pescando quà e là e mettendoci un pò di mio con VB6 sono riuscito a visualizzare il buffer che arriva dalla seriale e visualizzarlo sulla data.text ora senza errori.
Ho preso un esempio per aprire un file excel e fare un grafico con dati random ed ho caricato i punti nel range di celle suddette.

Quello che vi chiedo è un aiuto per passare i dati del buffer seriale per il caricamento del foglio excel.
Potrebbe essere utile l'uso dello split come da codice dell'ottimo MarcoGG ma stò facendo un pò di caos nel riempimento della matrice.:mc:
Avresti la pazienza di aiutarmi?:rolleyes:

Non capisco come fare, una volta premuto il comando "cancella grafico", a chiudere excel (ho provato in diversi modi commentati in Sub command_2 click ma senza successo).
Ultima cosa, come si fa a scegliere in questa applicazione un grafico a linee anzichè a istogrammi? (ho provato con oChart.chartType = VtChChartType2dLine ma mi da errore 13)

Questo è ciò che ho tirato giù fino ad ora:



Private Sub Command1_Click()

Dim oXL As Object ' Excel application
Dim oBook As Object ' Excel workbook
Dim oSheet As Object ' Excel Worksheet
Dim oChart As Object ' Excel Chart

Dim iRow As Integer ' Index variable for the current Row
Dim iCol As Integer ' Index variable for the current Row

Const cNumCols = 84 ' Number of points in each Series
Const cNumRows = 3 ' Number of Series


ReDim aTemp(1 To cNumRows, 1 To cNumCols)

'Start Excel and create a new workbook
Set oXL = CreateObject("Excel.application")
Set oBook = oXL.Workbooks.Add
Set oSheet = oBook.Worksheets.Item(1)

' Insert Random data into Cells for the three Series:
Randomize Now()
For iRow = 1 To cNumRows
For iCol = 1 To cNumCols
aTemp(iRow, iCol) = Int(Rnd * 50) + 1
Next iCol
Next iRow
oSheet.Range("A1").Resize(cNumRows, cNumCols).Value = aTemp

'Add a chart object to the first worksheet

Set oChart = oSheet.ChartObjects.Add(70, 5, 450, 280).Chart

'oChart.chartType = VtChChartType2dLine

oChart.SetSourceData Source:=oSheet.Range("A1").Resize(cNumRows, cNumCols)

' Make Excel Visible:
oXL.Visible = True
oXL.UserControl = True

End Sub

Private Sub Command2_Click()
'Kill "c:\documents and settings\administrator\documenti\cartel1.xls"
'oXL.Visible = False
'oXL.UserControl = False
End

End Sub

Private Sub Form_Load()
Form1.Caption = "Gestione seriale"
With MSComm1
.CommPort = 1
.Handshaking = 2 - comRTS
.RThreshold = 1
.RTSEnable = True
.Settings = "9600,n,8,1"
.SThreshold = 1
.PortOpen = True
' Leave all other settings as default values.
End With

OutputDisplay.Text = "Infobox"
InformationDisplay.Text = "Databox"
Help.Text = "Helpbox"
Data.Text = ""
Newdata = "" 'initialize to empty

End Sub

Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen = False
End Sub

Private Sub MSComm1_OnComm()

Dim InBuff As String

Dim I As Integer 'used to inspect each incoming character
Dim theChar As String 'each received character
Dim theInfo As String
InformationDisplay.Text = ""
Select Case MSComm1.CommEvent
' Handle each event or error by placing
' code below each case statement.

' This template is found in the Example
' section of the OnComm event Help topic
' in VB Help.

' Errors
Case comEventBreak ' A Break was received.
Case comEventCDTO ' CD (RLSD) Timeout.
Case comEventCTSTO ' CTS Timeout.
Case comEventDSRTO ' DSR Timeout.
Case comEventFrame ' Framing Error.
Case comEventOverrun ' Data Lost.
Case comEventRxOver ' Receive buffer overflow.
Case comEventRxParity ' Parity Error.
Case comEventTxFull ' Transmit buffer full.
Case comEventDCB ' Unexpected error retrieving DCB]

' Events
Case comEvCD ' Change in the CD line.
Case comEvCTS ' Change in the CTS line.
Case comEvDSR ' Change in the DSR line.
Case comEvRing ' Change in the Ring Indicator.
Case comEvReceive ' Received RThreshold # of chars.

InBuff = MSComm1.Input 'received 1 or more characters

For I = 1 To Len(InBuff) 'examine each received character in sequence

theChar = Mid$(InBuff, I, 1) 'extract the next character

If Asc(theChar) = 13 Then 'Look for CR
theInfo = Mid$(Newdata, 2, 1)
'Loads the second letter in the String "Newdata" in "theInfo" is a (I) or (P)

If theInfo = "I" Then
InformationDisplay.SelLength = 0
InformationDisplay.SelStart = Len(InformationDisplay.Text)
InformationDisplay.SelText = Newdata + vbCr + vbLf
'include a CR and LF to separate from next line placed in OutputDisplay
InformationDisplay.SelLength = 0

ElseIf theInfo = "P" Then
OutputDisplay.SelLength = 0
OutputDisplay.SelStart = Len(OutputDisplay.Text)
OutputDisplay.SelText = Newdata + vbCr + vbLf
'include a CR and LF to separate from next line placed in OutputDisplay
OutputDisplay.SelLength = 0

End If

Newdata = ""
'clear NewData so it can assemble the next packet

Data.SelLength = 0
Data.SelStart = 2
Data.SelText = vbCrLf
Data.SelLength = 0

ElseIf Asc(theChar) <> 10 Then 'ignore linefeeds

Newdata = Newdata + theChar
'received a character -- append it to NewData

Data.SelLength = 0
Data.SelStart = Len(Data.Text)
Data.SelText = theChar
Data.SelLength = 0

End If

Next I

Case comEvSend ' There are SThreshold number of
' characters in the transmit buffer.
Case comEvEOF ' An EOF character was found in the
' input stream.
End Select

End Sub

Come avrai capito la programmazione ad oggetti non è il mio forte:muro:

Grazie
Antonio

MarcoGG
27-11-2009, 14:41
Mi spiace, c'è decisamente troppa carne al fuoco per consigli "volanti" free. Personalmente mi fermo qui... ;)

aduri
27-11-2009, 16:04
Hai ragione :rolleyes:
ti ringrazio perchè in ogni caso mi sei stato molto utile.
Era principlmente un problema di variabili da locali a globali.

ciao
Antonio