System.IO.Ports.SerialPort – Conversiones y Codificaciones.

Considerando interesante y curiosa la cuestión planteada por Favi, me complace compartir con vosotros la resolución.
—- Pregunta ——————————–
Estoy actualizando un programa hecho en vb versión 3 que utiliza un control ‘mscomm’ de 16 bits. Ahora en net lo he transformado utilizando ‘System.IO.Ports.serialport’.
El problema en concreto es, que los caracteres que recibo del buffer se me quedan el más alto al transformarlo a hexadecimal en 3F cuando en la versión vb3 en la misma lectura me indica 8D.
Es decir como si el juego de caracteres interno del objeto ‘serialport’ fuera menor que el juego de caracteres del control ‘mscomm’ de la versión vb 3. Con el control ‘mscomm’ de vb3 se pueden leer caracteres que llegarían 255 decimal FF hexadecimal pero con el ‘serialport’ de net los deja capados en 3F no me interpreta caracteres de valor superior.
No si puede ser, que no utiliza un juego de caracteres extendido o algo así ?
Utilizo el ‘serialport.readexisting’ para recuperar las cadenas

—- Respuesta J  ——————————–
SerialPort1.Encoding = System.Text.Encoding.Default

Por defecto y supongo que aunque discutible la decodificación de los bytes recibidos se realiza utilizando la primera pagina de la tabla de caracteres ASCII, suponiendo que si se utilizan 8 bits para los datos, deberíamos utilizar ambas. Para poder representar el juego de caracteres de ambas paginas deberemos asignar ‘Encoding.Default’ al encoding de nuestro puerto serie.

No dudéis en continuar esta conversión si la consideráis interesante.
Pep LLuis

15 pensamientos en “System.IO.Ports.SerialPort – Conversiones y Codificaciones.”

  1. Ok, peplluis.

    El error queda solucionado, ahora si los caracteres que recibo del buffer son los correctos.

    Pues mira, que le habia dado vueltas al seriaport.encoding, pasandole las constantes que el intellisense me proporcionaba. ASCIIencoding, UTF8ENCODING, UNICODEencoding.. y nada de nada error persistia.

    muchas gracia o moltes gràcies.

  2. Hola Pep Luis soy lorena,

    Sabes implemente lo de asignar ‘Encoding.Default’ al encoding de nuestro puerto serie.

    pero ahora en ves de ponerme el ?, me pone un caracter como cuadrito un cuadrito muy pequeño que en ascii es el 176 .

    Gracias.

  3. Hola Lorena,
    Si te parece puedes contactar conmigo utilizando la opcion ‘contact’ en [This BLOG] al inicio de la pagina.
    Cuentame el con el codigo que estas usando y vemos cual es el problema.
    Saludos,

  4. You also have to keep in mind to set the same baud rate you have on your gps hardware port configuration and establish the automatic gps management.

  5. Hola muy interesante, quiero compartir un problema que realmente nose como soluionarlo y me tiene atrapado, el tema es que estoy codificando la comunicacion por serial port en c# con una impresora hasar 320F, la impresora entiende Ascii Estandar no el extendido y para los comando que superan el hexadecimal 7F, o sea, los comando del reango 80H a FFH me los pide que los enbie en Ascii HExadecimal, probe de todas formas y no me los interpreta alguna solucion mil graciass…. Saludos.

  6. Hola Mariano,
    Prueba con esta…
    this.serialPort1.Encoding=System.Text.Encoding.GetEncoding(«iso-8859-1»);

    Espero tus noticias,
    Pep Lluis,

  7. Hola Pep Lluis,

    Yo tenía el mismo problema para transmitir datos a través del puerto serie, me ha funcionado a medias tu recomendacion:

    this.serialPort1.Encoding=System.Text.Encoding.GetEncoding(«iso-8859-1»)

    Ahora ya no me salen símbolos de interrogación en las vocales acentuadas, pero curiosamente sólo la vocal ‘e’ se transmite acentuada, el acento desaparece de las restantes vocales. Por ejemplo, si envío por el puerto:

    á é í ó ú

    Se recibe en el dispositivo:

    a é i o u

    Ya intenté con distintos mapas (UTF-8, UTF-16, ASCII) y nada que no funciona.

    ¿Tienes alguna recomendación?

    Saludos,

  8. Hola Sergio… mas que recomendacion, deberias verificar utilizando algunos de los ejemplos mios como el «DeCom1ACom3» para verificar que realmente estas enviando el caracter que presupones (pues quizas estas utilizando algun tipo de conversion o adaptacion que lo hace trabajar mal), en todo contacta directamente conmigo y lo hablamos en off.

    Saludos,
    Pep Lluis,

  9. Hola Peplluis

    Tengo un problema, y no estoy seguro de donde…

    Comunico un PIC 16F876 con la PC por el puerto rs232. Envío bytes al PIC desde la PC y los voy almacenando en un buffer. Despues utilizo los datos recibidos para comandar una maquina. El problema es que los datos que guarda el pic en su memoria no se corresponden con los valores que envíe. sin embargo la cantidad de datos que recibo si es correcta.

    Este es un ejemplo de la pieza de codigo que uso para enviar los datos. Envio a modo de prueba los datos almacenados en el arreglo bufferTX.

    Imports System
    Imports System.IO.Ports
    Imports System.Threading

    Public Class Form1

    Dim BufferTX(10) As Byte
    Dim BufferRX(10) As Byte

    Shared _serialPort() As SerialPort

    ‘CONFIGURACIÓN DE PUERTOS
    Public Const Baudrateport As Integer = 9600
    Public Const DataBitsport As Integer = 8
    Public Const StopBitsport As System.IO.Ports.StopBits = 1
    Public Const readtimeoutport As Integer = 500
    Public Const writetimeoutport As Integer = 500

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

    BufferTX(0) = 0
    BufferTX(1) = 230 ‘E6
    BufferTX(2) = 186 ‘BA
    BufferTX(3) = 156 ‘9C
    BufferTX(4) = 128 ’80
    BufferTX(5) = 64 ’40
    BufferTX(6) = 16 ’10
    BufferTX(7) = 8 ‘8
    BufferTX(8) = 2 ‘2
    BufferTX(9) = 2 ‘2
    BufferTX(10) = 1 ‘1

    End Sub

    Private Sub PD_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PD.Click

    Dim ports As String() = SerialPort.GetPortNames()
    Dim port As String
    Dim portnum As Integer = 0

    ReDim _serialPort(ports.Length)
    ComboBox1.Items.Clear()
    ‘ Console.WriteLine(«The following serial ports were found:»)
    ‘ MsgBox(«Los puertos serie existentes son:»)

    ‘ Muestra los puertos disponibles
    For Each port In ports
    ‘ Console.WriteLine(port)
    _serialPort(portnum) = New SerialPort(port)
    _serialPort(portnum).PortName = port
    _serialPort(portnum).BaudRate = Baudrateport
    _serialPort(portnum).DataBits = DataBitsport
    _serialPort(portnum).StopBits = StopBitsport
    _serialPort(portnum).ReadTimeout = readtimeoutport
    _serialPort(portnum).WriteTimeout = writetimeoutport

    ComboBox1.Items.Add(port)
    ‘ MsgBox(portnum & » baud : » & Baudrateport)
    portnum = portnum + 1

    Next port

    If port = Nothing Then
    MsgBox(«No hay puertos serie, o no están disponibles.»)
    End If

    End Sub

    Private Sub T1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles T1.Click

    Try
    _serialPort(ComboBox1.Items.IndexOf(ComboBox1.SelectedItem)).Encoding = System.Text.Encoding.UTF8

    _serialPort(ComboBox1.Items.IndexOf(ComboBox1.SelectedItem)).Open() ‘abre el puerto serial
    _serialPort(ComboBox1.Items.IndexOf(ComboBox1.SelectedItem)).Write(BufferTX, 0, BufferTX.Count) ‘Manda el contenido del buffer al puerto
    ‘_serialPort(ComboBox1.Items.IndexOf(ComboBox1.SelectedItem)).Read(BufferRX, 0, ListaPic.Items.Count) ‘Lee lo que llega por el puerto y lo almacena en BufferRX
    _serialPort(ComboBox1.Items.IndexOf(ComboBox1.SelectedItem)).Close()
    ‘MsgBox(BufferRX(0) & BufferRX(1) & BufferRX(2) & BufferRX(3) & BufferRX(4) & BufferRX(5))
    ‘Exepciones posibles:
    Catch tiempofuera As TimeoutException
    MsgBox(tiempofuera.Message)
    _serialPort(ComboBox1.Items.IndexOf(ComboBox1.SelectedItem)).Close()
    Catch noexiste As ArgumentException
    MsgBox(noexiste.Message)
    Catch nohay As IO.IOException
    MsgBox(«Tu ordenador no dispone de puerto serie o esta en uso»)
    Catch ERROR_MESSAGE As UnauthorizedAccessException
    MsgBox(ERROR_MESSAGE.Message)
    _serialPort(ComboBox1.Items.IndexOf(ComboBox1.SelectedItem)).Close()
    Finally
    End Try

    End Sub

    Hice algunas pruebas. Por ejemplo, envié desde mi programa en VB los datos mediante un simulador de puerto serie a una aplicación que monitorea el puerto serie, y visualicé exactamente los datos que envié. Después usé la aplicacion de monitoreo para enviar los datos manualmente y de a uno al pic, y tenía el mismo problema… pensé que el problema estaba en el programa cargado al PIC. Entonces hice una rutina para que el PIC devuelva todos los datos que recibió(almacenados en un buffer)… y que pasó??? Recuperé los datos enviados!!! Los datos almacenados en el PIC aunque no son los que envié si se corresponden de alguna forma con ellos
    ¿Como hago para que mis datos se envien tal cual como los mando y no sufran transformaciones? en el PIC necesito los datos hexadecimales tal cual los envié!

    Gracias y saludos

  10. SerialPort1.Encoding = System.Text.Encoding.Default

    Hola que tal yo tengo el mismo problema cuando el byte que recibo excede de F ya me muestra 3F
    exactamente donde hay que poner el codigo este que describes al principio de pagina ?deberian hacer un buen manual completo del puerto serie porque a mi parecer para el que quiere empezar esta batante liado y mas si vienes del vb6
    un saludo PepLluis y gracias por tu web

  11. Hola IMASDPIC,

    Bienvenido y gracias por leer mi Blog. Como ya sabras los blogs son herramientas que nos permiten compartir nuestro dia a dia con el resto de la comunidad. Como MVP dedico tanto tiempo como puedo ayudando a personas como tu de forma desinteresa y sin animo de lucro. Comprenderas que es imposible a traves del blog dedicar un manual que cubra las inquietudes de cada uno de los lectores. En ese sentido te aconsejo que visites los foros de MSDN como herramienta de postear preguntas y recibir respuestas. En cuanto al manual la misma MSDN dispone de una completa documentacion describiendo el uso de los puertos serie : http://www.msdn.com

    En tu caso concreto deberias utilizar el mismo juego que este utilizando el DCE o DTE …

           SerialPort1.Encoding = System.Text.Encoding.ASCII

           SerialPort1.Encoding = System.Text.Encoding.UTF7

           SerialPort1.Encoding = System.Text.Encoding.UTF8

           SerialPort1.Encoding = System.Text.Encoding.UTF32

    Saludos,

    PepLluis,

  12. Buenas,
    Muy bueno el POST.
    Ahora, estoy intentando reemplazar el uso del PUTTY por un programa propio que pueda captar lo que recibe el PUTTY pero de manera que estudie los datos que recibe. Ya que actualmente el PUTTY recién graba un archivo de LOG cuando cierran el programa.
    El tema es que el PUTTY captura los datos y muestra los caracteres en forma correcta. Mientras que yo no lo logro y muestra muchos ???
    Probé cambiar el Encodign pero evidentemente no he dado con el correcto…

    Esta es la codificación que uso:

    AddHandler mySerialPort.DataReceived, AddressOf DataReceivedHandler

    mySerialPort.BaudRate = 9600
    mySerialPort.Parity = Parity.Even
    mySerialPort.StopBits = StopBits.One
    mySerialPort.DataBits = 7
    mySerialPort.Handshake = Handshake.None
    mySerialPort.RtsEnable = True
    mySerialPort.Encoding = System.Text.Encoding.Default

    mySerialPort.Open()

    Alguna idea?

    1. Normalmente en configuraciones de 7 bits de datos, son 2 de stop.
      Si continúan recibiendo es la velocidad mal ajustada o el encoding, prueba con System.Text.Encoding.UTF
      Saludos,

Responder a ROBERTO L BOZZACCHI Cancelar la respuesta

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