¿Cómo controlar el puerto serie usando c

Anuncio
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
¿Cómo controlar el puerto serie usando C# ?
Javier Gómez
Ingeniero de Telecomunicaciones por la Escuela
Tecnica Superior de Bilbao
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
¿Cómo controlar el puerto serie usando c# ?
Prerrequisitos
Para poder utilizar el puerto serie, es necesario tener instalada la librería
“MSComm.ocx”. Esta librería viene incluida con el VB del Visual Studio 6 y versiones
anteriores. Aquellos programadores que tengan instalado Visual Studio 2003 .NET y no
tengan las versiones anteriores necesitarán instalar este archivo. En algunas versiones de
Windows se puede encontrar en el directorio de instalación de Windows
(c:/WINNT/system32/ o c:/WINDOWS/system32/). Para usar esta librería se necesita
una licencia para componentes ActiveX de Visual Studio 6. Los pasos para instalar la
librería y obtener la licencia usando Visual Studio .NET 2003 son los siguientes:
1. Insertar el disco de instalación de Visual Studio .NET que contiene el
directorio \Extras\VB6 Controls en el lector de CD o DVD. La siguiente lista
describe que disco es necesario en cada versión:
Visual Studio .NET 2002
•
All Enterprise Editions – Disco 4
•
Professional Edition – Disco 4
•
Standard Edition – Disco 3
•
Academic Edition – Disco 4
Visual Studio .NET 2003
2.
3.
4.
5.
•
All Enterprise Editions – Disco 2
•
Professional Edition – Disco 2
•
Standard Edition – Disco 1
•
Academic Edition – Disco 2
Ir a Inicio, y luego hacer clic en Ejecutar....
En el cuadro de diálogo Ejecutar, escribir regedit y hacer clic en Aceptar.
En el Editor del registro, hacer click en Importar en el menú Archivo.
Localizar la carpeta \Extras\VB6 Controls en tu CD-ROM de instalación de
Visual Studio .NET, seleccionar el archivo VB6Controls.reg, y luego hacer
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
clic en Abrir. Esto introduce todas las claves de licencia de los controles
ActiveX de Visual Basic 6.0 en el registro.
Añadiendo el control MSComm
Debes añadir el control a un Windows form para poder utilizarlo. Para ello,
Visual Studio .NET facilita la tarea siguiendo estos pasos:
1. Crear un Windows Form.
2. Añadir el control MSComm COM/OCX a tu “Windows Form”.
a. Clic con el botón derecho en el Cuadro de herramientas.
b. Escoger “Agregar o quitar elementos…”
c. Seleccionar y añadir “Microsoft Communication Control”.
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
3. Dibujar el nuevo control en el Form(Icono de teléfono).
Propiedades y eventos principales del control MSComm
•
CommPort
Establece u obtiene el puerto serie del ordenador que se va a utilizar. Por
ejemplo, 1 = com1, 2 = com2,…
•
PortOpen
Abre o cierra el puerto.
•
RThreshold
Establece cuantos caracteres deben ser recibidos antes de ejecutar un
evento del tipo OnComm. Establecer un 0 si no se quieren tener eventos.
Poner un 1 si se quiere que aparezca un evento cada vez que se reciba un
carácter por el puerto serie.
•
InputMode
Se le pasa una constante de la clase MSCommLib.InputModeConstants,
con ella le indicamos el tipo de datos que se van a recibir o a enviar.
Pueden ser cadenas de texto (comInputModeText) o arrays de byte
(comInputModeBinary). Por defecto, el modo es de texto, más sencillo
para poder trabajar, pero menos versátil que el modo binario.
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
•
Settings
Se usa para configurar las propiedades del protocolo serie. Así, el
formato utilizado es “baudios, paridad, bits de datos, bits de stop”. Por
ejemplo: “9600,n,8,1” (9600 baudios, paridad no, 8 bits de datos y un bit
de stop).
•
Handshaking
Utilizar las constantes de MSCommLib.HandshakeConstants para definir
el tipo de control de transmisión que se desea en la comunicación:
ƒ
ƒ
ƒ
none (NoHandshaking): sin control de transmisión.
RTS/CTS hardware (RtsCts): utiliza los pines RTS (Ready
To Send)/CTS (Clear To Send) para controlar la
transmisión.
Xon/Xoff software (XonXoff): utiliza los comandos
Xon/Xoff.
•
InBufferCount
Devuelve el número de caracteres que están esperando en el buffer de
entrada.
•
Input
Devuelve los datos que se encuentren en el buffer de entrada y los
elimina de allí. Perrmite comprobar si existen datos en el buffer de
entrada. Devuelve una cadena de texto o un array de bytes en función de
que el modo de entrada sea texto/binario.
•
Output
Escribe una ráfaga de datos en el buffer de salida.. Por ejemplo
com.Output=”Hola” envía “Hola” a traés del puerto serie.
•
CommEvent
Devuelve una constante MSCommLib.CommEventConstants, una
constante MSCommLib.ErrorConstants, o una constante MSCommLib.
OnCommConstants representado el error o evento más reciente. Interesa
comprobarlo en el evento OnComm.
•
NullDiscard
Si su valor es true, el controlador del puerto ignorará todos los caracteres
que sean nulos (0x00).
•
InputLen
Indica el número de caracteres que puede leer del buffer cuando se utiliza
la propiedad Input. Si el valor es 0, entonces se leen todos los caracteres
que se encuentre en el buffer de entrada.
•
Evento OnComm
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
El único evento al que se le llama cuando sucede algo es el OnComm.
Para usarlo, hay que asegurarse de que el RThresold esta a 1. Hay que
comprobar que tipo de evento se ha producido. Por ejemplo:
public Form()
{
InitializeComponents(); // Inicializa los componentes del Form
com.RThreshold = 1; // Activa el registro de los eventos cuando se reciba algún dato
com.OnComm += new System.EventHandler(this.OnComm); /* Asigna el controlador
de eventos */
}
private void OnComm(object sender, EventArgs e) // MSCommLib OnComm Event Handler
{
if (com.InBufferCount > 0) ProcessData((string) com.Input);
if (com.CommEvent == MSCommLib.OnCommConstants.comEvCTS)
Console.WriteLine("Cambio del CTS");
}
Codigo de ejemplo
// Constructor para el Form con un control AxMSCommLib llamado "comSerial"
public SerialTerm()
{
// Inicializa los componentes del Form
InitializeComponent();
// Inicializa el control del Puerto COM
InitComPort();
// Envía datos por el Puerto COM
comSerial.Output = "Serial Terminal Initialized";
}
private void InitComPort()
{
// Establece com1 como Puerto serie
comSerial.CommPort = 1;
// Si el puerto está abierto, se cierra para resetearlo.
if (comSerial.PortOpen) comSerial.PortOpen = false;
// Disparar el evento OnComm cuando se reciban datos
comSerial.RThreshold = 1;
// Configurar el puerto a 9600 baudios, sin paridad, 8 bits de datos y un bit de
stop
comSerial.Settings = "9600,n,8,1";
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
// Forzar el DTR a nivel alto, usado a menudo por los modems
comSerial.DTREnable = true;
// No se usa control de tráfico
comSerial.Handshaking = MSCommLib.HandshakeConstants.comNone;
// Trabajar sólo con cadenas de texto
comSerial.InputMode =
MSCommLib.InputModeConstants.comInputModeText;
// Usar esta línea para entradas de arrays de bytes.
//comSerial.InputMode =
MSCommLib.InputModeConstants.comInputModeText;
// Leer todos los datos del buffer de entrada cuando se usa comSerial.Input
comSerial.InputLen = 0;
// No descartar los bytes nulos, 0x00 es un byte útil
comSerial.NullDiscard = false;
// Agregar el controlador de eventos
comSerial.OnComm += new System.EventHandler(this.OnComm);
// Abrir el puerto comSerial
comSerial.PortOpen = true;
}
private void OnComm(object sender, EventArgs e) // Controlador de eventos
del puerto serie
{
// Si hay datos esperando en el buffer, procesarlos.
if (comSerial.InBufferCount > 0) ProcessComData((string)
comSerial.Input);
}
private void ProcessComData(string input)
{
// Enviar los datos recibidos a un Rich Text Box
rtfTerminal.AppendText(input + "\n");
}
Enviando datos con arrays de bytes
Generalmente es más sencillo usar el modo texto, pero esto puede causar resultados
imprevisibles cuando se usan algunos caracteres especiales. En este caso debe usar
arrays de bytes. Ej: comSerial.Output = new byte[] {0, 0x41, (byte) 'A', 255};
Recibiendo datos como arrays de bytes
A veces, los datos que se reciben por el puerto serie no son ni letras ni números. Si estás
usando un programa con cuadros de texto y ves caracteres extraños, necesitarás utilizar
arrays de bytes. A continuación te explico cómo:
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
1. Configurar el comSerial.Input para recibir arrays de bytes.
comSerial.InputMode =
MSCommLib.InputModeConstants.comInputModeBinary;
2. Cuando recibas datos, guárdalos en un array de bytes.
private void OnComm(object sender, EventArgs e) // Controlador de eventos
{
// Recibir datos en un array de bytes, una buena idea para cualquier tipo de
datos
byte[] indata = (byte[]) comSerial.Input;
// Mostrar cada byte en la consola de salida
foreach (byte b in indata)
Console.WriteLine("Byte Data: " + b);
}
Recibiendo paquetes de datos
La recepción de los datos puede ser complicada si no se envían todos a la vez. Si envías
"Hola Mundo" por el puerto serie, es posible que en la recepción aparezca en muchos
trozos, como por ejemplo "Ho", "la ", "M", "un", "do". Para evitarlo existen diversas
técnicas. A continuación se muestra una de ellas:
Usar llaves de start y stop
Este es el método más común. Se designan unos prefijos y sufijos como
delimitadores del paquete de datos. El receptor los conoce y comprueba la llegada
de los mismos en el buffer. Cuando los reconoce, extrae los datos que se encuentrn
entre las llaves y borra el buffer. El código siguiente es un buen ejemplo de este
método:
// Usaremos Regular Expressions para las llaves 'start'/'stop'
using System.Text.RegularExpressions;
//
private string ComBuffer = "";
private void OnComm(object sender, EventArgs e)
{
// Añadir al buffer los datos de entrada
ComBuffer += (string) comSerial.Input;
// Controlador de eventos
// Ejemplo de contenido de buffer de entrada
// string ComBuffer = "trash---Hello World===trash---How Are
You?===trash";
// Construir una regular expression para delimitar los datos
// starts with '---' and ends with '==='
Regex r = new Regex("---.*?===");
// Realizar bucles para encontrar las llaves
for (Match m = r.Match(ComBuffer); m.Success; m = m.NextMatch())
{
Escuela Tecnica Superior de Ingenieros de Bilbao
Artículos y colaboraciones C#
// Mostrar el resultado por consola
Console.WriteLine(m.Value);
// Eliminar los datos del buffer
ComBuffer = ComBuffer.Replace(m.Value, "");
}
}
Descargar