Leer los ceros y unos de un micro-controlador
En muchas situaciones, sobre todo cuando hablamos de PIC’s se plantean cuestiones en torno como manejar un simple aplicación de intercambio de datos utilizando el IO.Ports.
A falta de un ejemplo concreto os facilito este código, aunque en anteriores Post’s podéis aprender algunas observaciones y consideraciones a tener en cuenta.
El siguiente ejemplo, envía una petición al micro-controlador cada 100ms, siempre y cuando no este ocupado esperando una respuesta. La respuesta se compone del Byte enviado mas un ‘0’ o un ‘1’, por lo tanto después de identificar la respuesta añadiremos el estado a un ‘Label1’ que acumulara todas las respuestas o dicho de otro modo todos los Ceros y Unos J

No dudéis en seguir la conversación si os interesa discutir algún aspecto en concreto. Pero como siempre estos ejemplos son muy ligeros, pretendiendo ser una idea inicial para demostrar que es posible, aunque distan mucho de ser la solución completa o ideal.
Saludos,
Pep Lluis,
Public Class Form1
Private PuertoSerie As New IO.Ports.SerialPort
Private Temporizado As New System.Timers.Timer
Private IOEncurso As Boolean = False
Delegate Sub ActualizarTexto(ByVal Texto As String)
Private Sub Form1_Load(….) Handles MyBase.Load
Temporizado.Interval = 100
'cada 100ms ejecutar la funcion TareasTemporizadas
AddHandler Temporizado.Elapsed, AddressOf TareasTemporizadas
'Abrir el puerto serie
PuertoSerie = My.Computer.Ports.OpenSerialPort("COM1", 115200, IO.Ports.Parity.Even, 7, IO.Ports.StopBits.Two)
'ejecutar la funcion recepcion al recibir datos
AddHandler PuertoSerie.DataReceived, AddressOf Recepcion
Temporizado.Start()
End Sub
'Buffer de recepcion
Private Dato(1) As Byte
Sub Recepcion()
Try
'Añadir la recepcion actual al buffer
If PuertoSerie.BytesToRead > 1 Then
'Leer dos bytes
PuertoSerie.Read(Dato, 0, 2)
'Verificar que el primero identifica inicio
Select Case Chr(Dato(0))
Case "R"
'añadir el status leido (0 o 1) al Label
Actualizar_Etiqueta(Label1.Text + Chr(Dato(1)))
Case Else
'descartar el contenido del buffer
'pues el dato(0) no corresponde a inicio
PuertoSerie.DiscardInBuffer()
End Select
'Dar por finalizada la respuesta
IOEncurso = False
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
IOEncurso = False
End Try
End Sub
'
'Utilizamos el INVOKE de LABEL1 Para evitar error..
' Operación no válida a través de subprocesos:
' Se tuvo acceso al control 'Label1' desde
' un subproceso distinto a aquel en que lo creó.
Private Sub Actualizar_Etiqueta(ByVal [texto] As String)
'Mostrar los bytes recibidos en el Label1
If Me.Label1.InvokeRequired Then
Dim delegado As New ActualizarTexto(AddressOf Actualizar_Etiqueta)
Me.Invoke(delegado, New Object() {[texto]})
Else
Me.Label1.Text = [texto]
End If
End Sub
'
'Controlar el envio de peticiones
' en nuestro caso cada 100ms
Sub TareasTemporizadas()
'Solo enviar una nueva peticion
'si se ha completado la anterior
If Not IOEncurso Then
PuertoSerie.Write("R")
IOEncurso = True
End If
End Sub
End Class
Para finalizar y dar otros puntos de vista, según las escuelas pueden utilizarse formas tales como:
Dim PuertoSerie As New IO.Ports.SerialPort
PuertoSerie = My.Computer.Ports.OpenSerialPort("COM1")
….
….
PuertoSerie.Write("Peticion")
System.Threading.Thread.Sleep(100) 'Dar tiempo al dispotivo
Dim Resultado() As Byte(Longitud)
PuertoSerie.Read(Resultado, 0, Longitud, 10000)
' donde 10000 es el timepo predefinido para
' que el puerto serie dispare una excepcion
' por tiempo de expera excedido
A pesar de que en mi opinión, utilizar ‘Sleeps’ y técnicas de esperar un fuera de tiempo no cumple con las expectativas de un programa que se precie. Pero esto ultimo no deja de ser una opinión muy personal.