Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

di il
7 risposte

Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

Buongiorno a tutti,
vi espongo il mio problema:
ho creato un piccolo script per leggere i dati da porta seriale. All'interno del Form ci sono 3 cmd button, 2 richtext e 2 combobox.
Alla pressione del tasto Init apro la porta seriale, tramite il tasto Write posso scrivere dati sulla seriale e li vedo nel box di Output.
Il mio problema riguarda, secondo me, il carattere terminatore vbCr (che su MATLAB è presente e si chiama CR), nel caso io colleghi alla porta seriale un trasmettitore A/D questo mi spara in continuo i dati e li visualizzo nel box di Output. Il problema nasce quando clicco sul tasto Close che lo script si blocca senza errori e l'unico modo per fermare il tutto è premere il tasto STOP sulla console di VB.

Qualcuno può aiutarmi?

In allegato il codice.

Grazie per l'aiuto
Imports System
Imports System.Threading
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.IO

Public Class Form1

    Dim myPort As Array
    Delegate Sub SetTextCallBack(ByVal [text] As String)

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Timer1.Enabled = False
        If SerialPort1.IsOpen Then
            SerialPort1.Close()
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        myPort = IO.Ports.SerialPort.GetPortNames()
        portComboBox.Items.AddRange(myPort)
        writeButton.Enabled = False

    End Sub

    Private Sub initButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles initButton.Click

        SerialPort1.PortName = portComboBox.Text
        SerialPort1.BaudRate = baudComboBox.Text
        SerialPort1.Parity = Parity.None
        SerialPort1.DataBits = 8
        SerialPort1.StopBits = StopBits.One
        SerialPort1.Handshake = Handshake.None
        SerialPort1.ReadTimeout = 500
        SerialPort1.WriteTimeout = 500

        SerialPort1.Open()

        initButton.Enabled = False
        writeButton.Enabled = True
        closeButton.Enabled = True

    End Sub

    Private Sub writeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles writeButton.Click

        SerialPort1.Write(inputTextBox.Text & vbCr)

    End Sub

    Private Sub closeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles closeButton.Click

        SerialPort1.Write(vbCr)
        SerialPort1.Close()
        initButton.Enabled = True
        writeButton.Enabled = False
        closeButton.Enabled = False

    End Sub


    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

        ReceivedText(SerialPort1.ReadExisting())

    End Sub
    Private Sub ReceivedText(ByVal [text] As String)
        If Me.outputTextBox.InvokeRequired Then
            Dim x As New SetTextCallBack(AddressOf ReceivedText)
            Me.Invoke(x, New Object() {(text)})
        Else
            Me.outputTextBox.Text &= [text]
        End If
    End Sub

End Class

7 Risposte

  • Re: Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

    Spiega meglio: questo A/D spedisce dati in continuo, indipendentemente da eventuali comandi che gli dai? Oppure per avere i dati gli devi spedire un CR?
    Dal codice della Close sembrerebbe che per stoppare la spedizione dati dall'A/D tu gli debba spedire un CR...
    Ad ogni modo io ci metterei un controllo nella SerialPort1_DataReceived() per verificare che la porta seriale non sia stata precedentemente chiusa (ovvero è stata arrivano dati, chiudo da pulsante, dopo gestisco il data received che evidentemente si blocca...).
  • Re: Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

    Grazie per la risposta candaluar,
    si questo trasmettitore A/D mi trasmette in continuo il valore del peso sotto forma di Stringa in questo modo: 001968. Il valore continua ad essere sparato sul textBox di Output.
    Si, indipendentemente da qualsiasi comando appena apro la porta seriale io vedo il dato trasmesso, non occorre il CR.
    Nel codice del Close, da come vedi, ho provato a dargli il vbCr, ma in ogni caso alla pressione del pulsante Close, il programma si blocca e devo premere STOP sulla console di Visual Basic 2010.
    Se al posto del trasmettitore collego, per esempio, una scheda relè e dentro al writeButton tolgo "vbCr" in questo modo:
    Private Sub writeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles writeButton.Click
    
            SerialPort1.Write(inputTextBox.Text)
    
        End Sub
    Risco a inserire in Input e leggere in Output il valore di ritorno dello stato del relè (esempio carattere 6 in Input => relè acceso, in Output la scheda risponde "L" sul text di Output), MA alla pressione del tasto Close va tutto in blocco e devo premere STOP sulla console di VB 2010.

    Ripristinando invece il vbCr nel writeButton così:
    Private Sub writeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles writeButton.Click
    
            SerialPort1.Write(inputTextBox.Text & vbCr)
    
        End Sub
    Lasciando sempre la scheda relè tutto funziona e non va in blocco.
    Cosa potrebbe essere secondo te?

    Andre
  • Re: Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

    Indipendentemente da quello che ti fa la scheda Rele, il problema che hai con l'A/D è probabilmente dovuto alla marea di dati che ti invia.
    Come ti suggerivo, probabilmente il problema ce l'hai nel momento in cui chiudi la seriale perchè hai ancora dei caratteri pendenti da ricevere: per questo ti suggerivo di verificare che la seriale sia ancora aperta nella "DataReceived" prima di andare a scaricare il buffer.
  • Re: Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

    Prova anche a metterci un Application.DoEvents dopo Write() e dopo Close() nella closeButton_Click()
  • Re: Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

    Grazie candaluar,
    domattina mi ci metto e ti faccio sapere.
  • Re: Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

    Buongiorno candaluar,
    ho risolto mettendo Application.DoEvents() PRIMA di SerialPort1.Close() all'interno di closeButton_Click. Quando premo il pulsante Close la seriale smette di sparare i dati, lo script non si blocca e posso premere di nuovo il pulsante Init per ricevere di nuovo.
    Imports System.ComponentModel
    Imports System.IO
    
    Public Class Form1
    
        Dim myPort As Array
        Delegate Sub SetTextCallBack(ByVal [text] As String)
    
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Timer1.Enabled = False
            If SerialPort1.IsOpen Then
                SerialPort1.Close()
            End If
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            myPort = IO.Ports.SerialPort.GetPortNames()
            portComboBox.Items.AddRange(myPort)
            writeButton.Enabled = False
    
        End Sub
    
        Private Sub initButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles initButton.Click
    
            SerialPort1.PortName = portComboBox.Text
            SerialPort1.BaudRate = baudComboBox.Text
            SerialPort1.Parity = Parity.None
            SerialPort1.DataBits = 8
            SerialPort1.StopBits = StopBits.One
            SerialPort1.Handshake = Handshake.None
            SerialPort1.RtsEnable = True
            SerialPort1.ReadTimeout = 500
            SerialPort1.WriteTimeout = 500
    
            SerialPort1.Open()
    
            initButton.Enabled = False
            writeButton.Enabled = True
            closeButton.Enabled = True
    
        End Sub
    
        Private Sub writeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles writeButton.Click
    
            SerialPort1.Write(inputTextBox.Text & vbCr)
    
        End Sub
    
        Private Sub closeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles closeButton.Click
    
            Application.DoEvents()    'Ho aggiunto semplicemente questa riga e funziona
            SerialPort1.Close()
            initButton.Enabled = True
            writeButton.Enabled = False
            closeButton.Enabled = False
    
        End Sub
    
    
        Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    
            ReceivedText(SerialPort1.ReadExisting())
    
        End Sub
        Private Sub ReceivedText(ByVal [text] As String)
            If Me.outputTextBox.InvokeRequired Then
                Dim x As New SetTextCallBack(AddressOf ReceivedText)
                Me.Invoke(x, New Object() {(text)})
            Else
                Me.outputTextBox.Text &= [text]
            End If
        End Sub
    
    End Class
    Scusami ma non ho capito bene dove devo mettere SerialPort1_DataReceived(), all'interno del initButton_Click prima di aprire la porta?

    Sapresti consigliarmi un libro che parta dalle basi di Visual Basic 2010 e un libro che spieghi sempre in VB 2010 tutte queste cose sulle porte seriali e magari anche sulla comunicazione Ethernet al posto della USB/Seriale?
    Te ne sarei grato, perchè io ho un vecchio libro di Visual Basic 6.0 "Visual Basic 6.0 in 24 ore" comprato nel 1999 che non è molto completo.

    Andrea
  • Re: Carattere terminatore vbCr: quando chiudo connesione a trasmettitore A/D il programma si blocca

    Ciao PLOTTER_1983, l'aver messo il DoEvents prima della close fa in modo (*probabilmente*) che venga eseguito un eventuale SerialPort1_DataReceived() rimasto "appeso" prima di chiudere la seriale.
    In alternativa potresti provare, con una flag, e chiaramente commentando il DoEvents che fa funzionare di suo il sistema, a gestire un'abilitazione/disabilitazione "logica" della ricezione dati: ovvero nella SerialPort1_DataReceived() controlli che la flag sia attiva, se è disattiva non fai niente ed esci subito. Così dopo aver aperto la seriale attivi la flag e prima di dare la Close la disattivi.
    Sapresti consigliarmi un libro che parta dalle basi di Visual Basic 2010 e un libro che spieghi sempre in VB 2010 tutte queste cose sulle porte seriali e magari anche sulla comunicazione Ethernet al posto della USB/Seriale?
    Purtroppo non saprei cosa consigliarti, eventualmente crea un nuovo thread con questa richiesta
Devi accedere o registrarti per scrivere nel forum
7 risposte