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

CerosYUnos

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.

 

 

 

 

0 pensamientos en “Leer los ceros y unos de un micro-controlador”

  1. Hola Manu,
    El ejemplo se realizo por una peticion, en la que el Micro responde a la peticion utilizando la «R» mas el estado del bit. Asi cuando Recibe la letra «R» responde «R0» o «R1», por lo tanto antes de leer el segundo caracter comparamos que estamos recibiendo la «R» como cabecera de respuesta. En caso contrario se considera que existe un error o no se esta recibiendo correctamente.

    Espero que esto ayude a clarificarlo y muchas gracias por plantear la duda.
    Pep Lluis,

  2. Saludos! Me preguntaba como podria hacer para que el dato recibido se guardara de forma numerica en una variable tipo byte, he usado varios codigos pero no consigo hacerlo.

    Tambien me preguntaba como enviar datos, use writeLine pero los datos enviados aparecian con fallos,el primer dato llegaba vien, pero despues aparecian datos intercalados como si se produjeran conversiones a caracteres o se intercalaran saltos de linea…no sé que sería.

  3. Para la primera pregunta quizas algo similar a esto :

    If SerialPort.BytesToRead > 0 Then
    Dim Mibyte As Byte = SerialPort.ReadByte()
    End If

    Para la segunda, matizar que la unica diferencia entre Write i WriteLine es que este ultimo inserta automaticamente el caracter definido en ‘NewLine’… por ejemplo :

    SerialPort.NewLine = Chr(13)

    A nivel de espacio de nombres seria la primera vez que «envie datos con fallos», pienso que es provable que tengas problemas de driver con el conversor serie (USB-RS232) o el dispositivo que recibe la informacion no es lo suficientemente rapido para procesarla y se esta desbordando a nivel de buffer.

    Saludos,
    Pep Lluis,

  4. excelente ayuda, tengo un circuito que actua de forma similar. este espera recibir de la PC cualkier dato, al ser recibido este por el micro, este responde enviando 2 bytes. pero al recibirlos lo logro en ascci (2 caracteres).

    el 1er byte enviado por el micro debo modificarlo para mostrarlo en pantalla asi
    ((1er byte )X 2) y el resultado convertirlo a decimal.
    el 2do byte solo debo convertirlo a decimal.

    en el micro trabaje con
    bits x seg = 9600
    bits de datos = 8
    paridad = ninguno
    que debo hacer?
    gracias desde ya!!

  5. Hola a todos.
    Os cuento, yo he desarrollado una pequeña pagina web con vb.net 2005.
    En el servidor donde esta alojada la pagina tengo un dispositivo Xbee en el puerto serie (com3).

    Esta es mi default.aspx:
    Imports System.Data
    Imports System.Data.SqlClient
    Imports System.Security.Principal.WindowsIdentity
    Imports System
    Imports System.IO.Ports

    Partial Class XbeePpal
    Inherits System.Web.UI.Page

    Dim WithEvents Port As SerialPort = New SerialPort(«COM3», 9600, Parity.None, 8, StopBits.One)

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    ‘CheckForIllegalCrossThreadCalls = False
    ‘Client_Alert(Port.IsOpen)
    If Port.IsOpen = False Then Port.Open()
    Port.DtrEnable = True
    Port.RtsEnable = True
    ‘Port.CDHolding
    Port.Handshake = Handshake.None
    ‘AddHandler Port.DataReceived, AddressOf Recepcion
    ‘TECNICO.Text = User.Identity.Name()
    End Sub

    Sub Port_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Port.DataReceived
    ‘Exit Sub
    ‘Client_Alert(«recibo»)
    txtReciveText.Text = Port.ReadExisting
    If Port.ReadExisting.Length = 0 Then
    LstReciveText.Items.Add(txtReciveText.Text)
    txtReciveText.Text = «»
    End If
    End Sub

    Private Sub btnSendText_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSendText.Click
    ‘If Port.IsOpen = False Then Port.Open()
    Port.Write(txtSendText.Text & «A»)
    ‘If Port.IsOpen = True Then Port.Close()
    End Sub

    Protected Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Unload
    If Port.IsOpen = True Then Port.Close()
    End Sub
    End Class

    El caso es que puedo enviar datos perfectamente por el puerto serie, pero no me salta el evento cuando se reciben datos.
    Recibir recibo datos, comprobado con un hyperterminal.
    Alguien me puede ayudar?
    MUchas gracias y un saludo

  6. Hola José antonio,
    Esta discusión la tuve con un buen amigo de Sevilla , en cuanto pueda retomamos el tema y te cuento. Pues yo ando un poco flojo cuando hablamos de .aspx

  7. Hola amigos

    pues soy un novato en cuanto a la programacion puerto serail en visual studio,

    la verdad lo unico que necesito es un ejemplo claro que como leer datos por el puerto serial, he intentado de muchas formas y nada, pruebo si realmente estan llenado datos por el hyperterminal y si llega, la trama de datos a recibir es:

    0 numero telefonico 15 ; ejemplo 0 3 1 3 4 5 1 4 5 7 8 15

    necesito recibir esa trama que me la enviar el micro..

    agradezco su pronta colaboracion..
    me puede enviar ejemplos basto.mack10@gmail.com

    Gracias.

  8. Hola Mauricio,
    Has intentado con algun otro ejemplo contenido en el TAG de Puertos Serie?
    Quizas encontraras otro ejemplo que pueda aportar mejor ayuda.

    Saludos,
    PepLluis,

  9. Buenas tardes, amigo PepLuis. Tengo 5 dias investigando y tratando de hacer pequeños modulos para leer el puerto serie de una pesa, pero ninguna de las pruebas me sale, recibo basura, signos de interrogacion, con el metodo readexisting, y con el metodo readline se queda colgado, tambien use el metodo read pero alli me desborda el array y ya no se que paramentros debo tener o que estoy haciendo mal y tengo que entregar ese proyecto pronto. He usado las indicaciones de microsoft y los ejemplos, y otros que he encontrado pero no me sale nada, es la primera vez que trato con este tipo de apliciones, en visual basic .net 2005. Si me puedes proporcionar un mail donde enviarte mi script y las dudas que tengo por favor o escribirme a: aasahito@yahoo.com.ar ,te lo agradeceria mucho tu ayuda, y despues poder compartir esto con el foro. Muchas gracias

  10. Hola Alberto,
    Por los sintomas que detallas, es claro que no tienes los parametros de comunicacion correctamente asignados.Debes mantener la misma configuracion de velocidad, datos, partidad y stop en ambos lados. Revisa antes de efectuar la operacion Open que estas asignando los valores que tienes ajustados a la pesa por ejemplo :
    MiPuertoCom = My.Computer.Ports.OpenSerialPort(«COM4», 19200, IO.Ports.Parity.Even, 7, 2)

    Saludos,
    Pep Lluis,

  11. Hola

    Estoy trabajando con el puerto serial pero no puedo lograr recibir los datos completos del puerto, es decir, la primera vez los recibe bien, pero la segunda solo leo la mitad y despues el resto o de manera asincrona recibo la informacion digamoslo asi dos veces

    Espero puedas ayudarme.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *