(http://www.webtutoriales.com/tutoriales/images/2/content_tabla_ascii.gif)
1)El programa espera la recepciòn de un ENQ(05 Hex) o STX(02 Hex)
2) Si recibo lo del paso 1 , le envìo un ACK(06 Hex)
3)Luego de enviado el ACK leo todo lo que me manda la maquina externa, si es distinto de cualquier caracter de control, lo muestro.
4) Si recibo un EOT(04 Hex) mando un enter en la pantalla de recepcion para diferenciar las lineas.
5) Si recibo un ETX(03 Hex) le respondo con un ACK.
Supongo que en este caso se podrìa hacer un if o un select preguntando lo recibido, el tema es que no se como leer de manera correcta y poder comparar que es lo que se recibio para poder ejecutar la tarea necesaria segun lo que llega.
Imports System.IO.Ports
Imports System.Text
Public Class Form1
Dim recibidos As String
Dim stx As String = ASCIIEncoding.ASCII.GetString(New Byte() {2})
Dim etx As String = ASCIIEncoding.ASCII.GetString(New Byte() {3})
Dim eot As String = ASCIIEncoding.ASCII.GetString(New Byte() {4})
Dim enq As String = ASCIIEncoding.ASCII.GetString(New Byte() {5})
Dim ack As String = ASCIIEncoding.ASCII.GetString(New Byte() {6})
Public Sub New()
InitializeComponent()
If Not SerialPort1.IsOpen Then
Try
SerialPort1.Open()
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End If
AddHandler SerialPort1.DataReceived, AddressOf recepcion
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If SerialPort1.IsOpen Then
SerialPort1.Close()
End If
End Sub
Private Sub recepcion(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
recibidos = Chr(SerialPort1.ReadChar)
If recibidos = stx Or recibidos = enq Then
SerialPort1.Write(ack)
Else
If recibidos <> stx And recibidos <> etx And recibidos <> enq And recibidos <> ack And recibidos <> eot Then
Me.Invoke(New EventHandler(AddressOf actualizar))
Else
If recibidos = eot Then
Me.Invoke(New EventHandler(AddressOf actualizarenter))
Else
If recibidos = etx Then
SerialPort1.Write(ack)
End If
End If
End If
End If
End Sub
Private Sub actualizar(ByVal s As Object, ByVal e As EventArgs)
textbox_visualizar_mensaje.Text = textbox_visualizar_mensaje.Text & recibidos
End Sub
Private Sub actualizarenter(ByVal s As Object, ByVal e As EventArgs)
textbox_visualizar_mensaje.Text = textbox_visualizar_mensaje.Text & vbLf
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
StatusStrip1.Items(0).Text = DateTime.Now.ToLongTimeString
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
SerialPort1.Encoding = System.Text.Encoding.Default
End Sub
End Class
uf, estás utilizando malas prácticas de programación en todos los rincones del código xD.
Prueba así (no lo he testeado, ni tampoco se si he entendido correctamente las condiciones que dices que se deben dar al recibir los datos, pero desde luego puedes simplificar ese IF anidado de tú código en un Switch/Select Case):
#Region " Imports "
Imports System.IO.Ports
#End Region
Public NotInheritable Class Form1 : Inherits Form
#Region " Objects / Constants-ReadOnly / Properties "
' Estos objetos los inicializo en el constructor del Form solo para poder compilar este ejemplo.
Private WithEvents sp As SerialPort
Private ReadOnly ss As StatusStrip
Private ReadOnly tb As TextBox
' ***********************************************
Private WithEvents tmr As New Timer
Private ReadOnly charStx As Char = Convert.ToChar(&H1)
Private ReadOnly charEtx As Char = Convert.ToChar(&H3)
Private ReadOnly charEot As Char = Convert.ToChar(&H4)
Private ReadOnly charEnq As Char = Convert.ToChar(&H5)
Private ReadOnly charAck As Char = Convert.ToChar(&H6)
''' <summary>
''' Gets the next character from the device's input buffer.
''' </summary>
''' <value>The next character from the device's input buffer.</value>
Private ReadOnly Property NextChar As Char
Get
Return Convert.ToChar(Me.sp.ReadChar)
End Get
End Property
#End Region
#Region " Constructors "
Public Sub New(ByVal sp As SerialPort, ByVal ss As StatusStrip, ByVal tb As TextBox)
MyClass.InitializeComponent()
Me.sp = sp
Me.ss = ss
Me.tb = tb
End Sub
Public Sub New()
MyClass.InitializeComponent()
End Sub
#End Region
#Region " Event-Handlers "
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _
Handles Me.Load
Me.OpenPort(Me.sp)
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) _
Handles Me.FormClosing
Me.ClosePort(Me.sp)
End Sub
Private Sub Serialport1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) _
Handles sp.DataReceived
Me.ProcessChar(Me.NextChar)
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) _
Handles tmr.Tick
ss.Items(0).Text = DateTime.Now.ToLongTimeString
End Sub
#End Region
#Region " Private Methods "
Private Sub OpenPort(ByVal sp As SerialPort)
If Not sp.IsOpen Then
Try
sp.Open()
Catch ex As Exception
MessageBox.Show(ex.ToString &
Environment.NewLine &
ex.StackTrace, "error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
End Sub
Private Sub ClosePort(ByVal sp As SerialPort)
If sp.IsOpen Then
Try
sp.Close()
Catch ex As Exception
MessageBox.Show(ex.ToString &
Environment.NewLine &
ex.StackTrace, "error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
If sp IsNot Nothing Then
sp.Dispose()
End If
End Try
End If
End Sub
Private Sub ProcessChar(ByVal chr As Char)
Select Case chr
Case Me.charStx, Me.charEnq, Me.charEtx
sp.Write(Me.charAck)
Case Me.charAck
' Do Nothing?.
Case Me.charEot
Me.ThreadSafeAppendText(Me.tb, chr & ControlChars.Lf)
Case Else
Me.ThreadSafeAppendText(Me.tb, chr)
End Select
End Sub
Private Sub ThreadSafeAppendText(ByVal tb As TextBox, ByVal str As String)
SyncLock tb
If tb.InvokeRequired Then
tb.Invoke(Sub() tb.AppendText(str))
Else
tb.AppendText(str)
End If
End SyncLock
End Sub
#End Region
End Class
Nota:
En mi modificación no modifico la codificación de entrada del dispositivo, ya que puedes hacerlo de la siguiente manera, al declarar e inicializar el puerto de serie:
Dim sp As New SerialPort With
{
.Encoding = Encoding.Default
}
Saludos