Cambiar los ‘SerialPort Settings’ en tiempo de ejecución.

Atendiendo a una consulta de los foros de MSDN, me complace compartir con vosotros una solución para asignar los ajustes de apertura del puerto serie al vuelo.

Entendiendo que en algunas situaciones, puede ser ventajoso poder cambiar la velocidad, paridad, bits... etc, ‘On Line’. Aunque para la mayoría de comunicaciones con dispositivos dichos parámetros son ajustados en tiempo de puesta en marcha y no acostumbran a variar en el transcurso del tiempo.

Esperando os sea útil… Saludos,
Pep Lluis,

PD. Si queréis podéis descargaros la solución de ejemplo en ‘attachments’.

using System;

using System.IO.Ports;

using System.Windows.Forms;

 

namespace SerialPortSettings

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

            // Asignar las Velocidades seleccionables al Combo

            object[] Velocidades = { 19200, 9600, 4800, 2400, 1200 };

            this.comboBox_bits_por_segundo.Items.AddRange(Velocidades);

           

            // Asignar Paridades Seleccionables desde la enumeracion

            foreach (string s in Enum.GetNames(typeof(Parity)))

            {

                this.comboBox_paridad.Items.Add(s);

            }

           

            // Seleccionar los items por defecto

            this.comboBox_bits_por_segundo.SelectedIndex = 0;

            this.comboBox_paridad.SelectedIndex = 0;

            // Abrir el puerto serie con los items por defecto

            SeleccionCambiada(sender,e);

            // Asignar la funcion a ejecutar por disparo de evento al cambio de indice en el combobox

            this.comboBox_bits_por_segundo.SelectedIndexChanged += new System.EventHandler(this.SeleccionCambiada);

            this.comboBox_paridad.SelectedIndexChanged += new System.EventHandler(this.SeleccionCambiada);

        }

 

       

        private void SeleccionCambiada(object sender, EventArgs e)

        {

            // Deberemos añadir un control de excepciones si queremos capturar posibles errores

 

            // Para reasignar valores... primero cerrar el puerto

            this.serialPort1.Close();

            // Asignar los nuevos Settings

            this.serialPort1.BaudRate = Convert.ToInt16(comboBox_bits_por_segundo.Text);

            this.serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), comboBox_paridad.Text);

 

            this.serialPort1.Open();

            // Ver las asignaciones actuales.

            this.Velocidad.Text = this.serialPort1.BaudRate.ToString();

            this.Paridad.Text = this.serialPort1.Parity.ToString();

        }

 

    }

}

 

Comments

# re: Cambiar los ‘SerialPort Settings’ en tiempo de ejecución.

Tuesday, September 22, 2009 2:17 PM by Leolaz

Buenas tardes pepluis gracias por el gran aporte pero brindas sobre todo gratis por tu blog me a servido de mucho en mi trabajo. Sin embargo, tengo una pregunta; cuando se recibe la data de un puerto virtual la configuracion y el codigo debe cambiar?porque tengo un programa que en un puerto fisico recibe la data normal, pero cuando le pongo para que reciba de un puerto virtual no me recibe nada.O tambien si habria alguna manera de compartir el flujo de datos de un puerto. Gracias de antemano.

compartir el flujo de datos de un puerto COM .

p.d: Todo esta hecho en vb 2005

# re: Cambiar los ‘SerialPort Settings’ en tiempo de ejecución.

Wednesday, September 23, 2009 1:29 AM by peplluis

Hola Leolaz,

Gracias por tus amables palabras.

En teoria un puerto serie "Virtual" deberia comportarse identicamente igual que uno fisico. Aunque se me hace dificil entender que puede estar ocurriendo por desconocer los detalles. Creo que en ese sentido que el fabricante de la aplicacion "Virtual" deberia darte instrucciones precisas de su funcionamiento y/o compatibilidades.

Lamento no tener mayor conocimiento en este campo.

Saludos,

Pep Lluis,

# re: Cambiar los ‘SerialPort Settings’ en tiempo de ejecución.

Wednesday, September 23, 2009 1:51 PM by Leolaz

Gracias por tu ayuda, mira en unos ejemplos que tiene microsoft sobre puerto hay un modo diferente de acceder a ellos, ya logre capturar la informacion, pero solo al levantar la aplicacion por mas que le pongo en el timer para que lo haga cada segundo no pasa nada sigue mostrando la misma información . Si fueras tan amable de corregirme aqui te dejo los metodos.

C:

Load

=========================

    CommPort.Open(6, 9600, 8, RS232.DataParity.Parity_None, _

            RS232.DataStopBit.StopBit_1, 4096)

       Me.Timer1.Enabled = True

       Me.Timer1.Interval = 1000

TimerTick

===============================

 While (CommPort.Read(1) <> -1)

WriteMessage(Chr(CommPort.InputStream(0)), False)

 End While

WriteMessage

===============================

Me.TextBox1.Text += message

  If linefeed Then

      Me.TextBox1.Text += vbCrLf

   End If

# re: Cambiar los ‘SerialPort Settings’ en tiempo de ejecución.

Thursday, September 24, 2009 9:05 AM by peplluis

Disculpa Leolaz,

Deberias especificarme la version de VB que estas utilizando y el control... se trata del antiguo MSCOMM32.OCX?

Puedes tambien contactar conmigo a traves de la opcion [Contact] al inicio de esta pagina.

Espero tus noticias,

Pep Lluis,

# ‘SerialPort Settings’ en tiempo de ejecución sin cerrar el puerto

Tuesday, October 06, 2009 4:59 AM by luistope

Hola. Me gustaría saber como debe hacerse en .NET el cambio de paridad mientras se está enviando. La intención es enviar una trama en modo multiprocesador (con los 2 bytes de dirección con la paridad en marca y el resto paridad espacio) para comunicar con un microcontrolador que utiliza este tipo de comunicación. Toda la trama debe ir seguida sin pausas ni cortes. En Visual 6.0 y con mscomm lo que hacía y me funcionaba era:

s.Format(_T("%d,%C,%d,%d"), 9600, (TCHAR)'M', 8, 1);// Pongo el bit multiprocesador. Cambio a uso de MARCA

m_COM.SetSettings(s);

memcpy(pchBuffer, (LPSTR)buffer.GetData(), 2);

MultiByteToWideChar(CP_ACP, 0, pchBuffer, 2, pchData, 2);

var.vt = VT_BSTR;

var.bstrVal = ::SysAllocStringLen(pchData, 2);

// Send data to comm port.

// bytes_sended=2; // apunto los datos que voy a dejar sin procesar

m_COM.SetOutput(var);

SysFreeString(var.bstrVal);

// char a1 = buffer.GetAt(0);

// char a2 = buffer.GetAt(1);

buffer.RemoveAt(0,2);

Sleep(1); // Retardo necesario para que se envíen los 2 primeros bits. Si se pone sleep más grande ya no funciona.

s.Format(_T("%d,%C,%d,%d"), 9600, (TCHAR)'S', 8, 1);// Pongo el bit multiprocesador. Cambio a uso de ESPACIO

m_COM.SetSettings(s);

memcpy(pchBuffer, (LPSTR)buffer.GetData(), nBytes-2);

MultiByteToWideChar(CP_ACP, 0, pchBuffer, nBytes-2, pchData, nBytes-2);

//buffer.InsertAt(0,a2);

//buffer.InsertAt(0,a1);

var.vt = VT_BSTR;

var.bstrVal = ::SysAllocStringLen(pchData, nBytes-2);

// Send data to comm port.

El sleep lo que hace es darle tiempo a salir a los 2 primeros bytes con marca. Y luego se cambia a espacio. El problema es que los dispositivos a los que les envío la trama deben recibirla seguida, sin cortes entre los 2 bytes de dirección y el resto de la trama por eso si se pone el sleep más largo no funciona. La opción de cerrar el puerto, que yo no hago, y que tu planteas en el ejemplo en .NET, no sé si daría algún problema con los datos que se están enviando mientras tanto y no sé si sería demasiado lento el cierre y apertura de nuevo del COM. Tengo que probarlo. Otra cosa que he visto es que el mismo código en esta función para 6.0 compilado en VS2005 no funciona. Seguramente porque el código final generado no mantiene los mismo tiempos que tuve que ajustar para 6.0.

# re: Cambiar los ‘SerialPort Settings’ en tiempo de ejecución.

Wednesday, October 07, 2009 2:09 AM by peplluis

Hola Luis,

Quizas no funcione... pero has intentado algo similar a esto :

Dim Direccion(1) As Byte

Direccion(0) = &H30

Direccion(1) = &H32

PuertoSerie.Parity = IO.Ports.Parity.Mark

PuertoSerie.Write(Direccion, 0, 2)

PuertoSerie.Parity = IO.Ports.Parity.None

PuertoSerie.Write("El Resto de Trama")

# Habilitar un temporizador en el evento DataReceived

Wednesday, October 28, 2009 12:23 PM by Matías

No me habilita un temporizador dentro del evento DataReceived pero tampoco me tira error:

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

       leido = True

       Me.Timer1.Enabled = True

   End Sub

   Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

       MsgBox("Pasó por acá")

   End Sub

# re: Cambiar los ‘SerialPort Settings’ en tiempo de ejecución.

Monday, November 02, 2009 3:01 AM by peplluis

Hola Matias,

Prueba este codigo...

Imports System.IO.Ports

Public Class Form1

   WithEvents PuertoSerie As New SerialPort("COM2")

   Dim MiTemporizador As New System.Timers.Timer

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

       MiTemporizador.Interval = 1000

       MiTemporizador.Enabled = False

       AddHandler MiTemporizador.Elapsed, AddressOf Temporizar

       PuertoSerie.Open()

   End Sub

   Sub recepcion() Handles PuertoSerie.DataReceived

       MiTemporizador.Enabled = True

       Dim Recibidos As String = PuertoSerie.ReadExisting

   End Sub

   Sub Temporizar()

       MiTemporizador.Enabled = False

       MessageBox.Show("Hace Un segundo que recibi datos")

   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

       PuertoSerie.Write("Hola")

   End Sub

End Class

Saludos,

Pep Lluis,

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above: