Escuela Tecnica Superior de Ingenieros de Bilbao Artculos y colaboraciones C#
Cmo controlar el puerto serie usando C# ?
Javier Gmez
Ingeniero de Telecomunicaciones por la Escuela Tecnica Superior de Bilbao Escuela Tecnica Superior de Ingenieros de Bilbao Artculos y colaboraciones C# Cmo controlar el puerto serie usando c# ?
Prerrequisitos
Para poder utilizar el puerto serie, es necesario tener instalada la librera MSComm.ocx. Esta librera 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 necesitarn instalar este archivo. En algunas versiones de Windows se puede encontrar en el directorio de instalacin de Windows (c:/WINNT/system32/ o c:/WINDOWS/system32/). Para usar esta librera se necesita una licencia para componentes ActiveX de Visual Studio 6. Los pasos para instalar la librera y obtener la licencia usando Visual Studio .NET 2003 son los siguientes:
1. Insertar el disco de instalacin 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 versin: 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 All Enterprise Editions Disco 2 Professional Edition Disco 2 Standard Edition Disco 1 Academic Edition Disco 2
2. Ir a Inicio, y luego hacer clic en Ejecutar.... 3. En el cuadro de dilogo Ejecutar, escribir regedit y hacer clic en Aceptar. 4. En el Editor del registro, hacer click en Importar en el men Archivo. 5. Localizar la carpeta \Extras\VB6 Controls en tu CD-ROM de instalacin de Visual Studio .NET, seleccionar el archivo VB6Controls.reg, y luego hacer Escuela Tecnica Superior de Ingenieros de Bilbao Artculos 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.
Aadiendo el control MSComm
Debes aadir 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. Aadir el control MSComm COM/OCX a tu Windows Form. a. Clic con el botn derecho en el Cuadro de herramientas. b. Escoger Agregar o quitar elementos c. Seleccionar y aadir Microsoft Communication Control.
Escuela Tecnica Superior de Ingenieros de Bilbao Artculos y colaboraciones C#
3. Dibujar el nuevo control en el Form(Icono de telfono).
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 carcter 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 (comI nput ModeText ) o arrays de byte (comI nput ModeBi nar y) . Por defecto, el modo es de texto, ms sencillo para poder trabajar, pero menos verstil que el modo binario. Escuela Tecnica Superior de Ingenieros de Bilbao Artculos 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 transmisin que se desea en la comunicacin:
none (NoHandshaki ng): sin control de transmisin. RTS/CTS hardware (Rt sCt s): utiliza los pines RTS (Ready To Send)/CTS (Clear To Send) para controlar la transmisin. Xon/Xoff software (XonXof f ): utiliza los comandos Xon/Xoff.
InBufferCount Devuelve el nmero de caracteres que estn 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 funcin de que el modo de entrada sea texto/binario.
Output Escribe una rfaga de datos en el buffer de salida.. Por ejemplo com.Output=Hola enva Hola a tras del puerto serie.
CommEvent Devuelve una constante MSCommLib.CommEventConstants, una constante MSCommLib.ErrorConstants, o una constante MSCommLib. OnCommConstants representado el error o evento ms 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 nmero 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 Artculos 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 For m( ) { I ni t i al i zeComponent s( ) ; // Inicializa los componentes del Form com. RThr eshol d = 1; // Activa el registro de los eventos cuando se reciba algn dato com. OnComm+= new Syst em. Event Handl er ( t hi s. OnComm) ; /* Asigna el controlador de eventos */ }
private void OnComm( object sender , Event Ar gs e) // MSCommLib OnComm Event Handler { if ( com. I nBuf f er Count > 0) Pr ocessDat a( ( st r i ng) com. I nput ) ; if ( com. CommEvent == MSCommLi b. OnCommConst ant s. comEvCTS) Consol e. Wr i t eLi ne( " Cambi o del CTS" ) ; }
Codigo de ejemplo
// Constructor para el Form con un control AxMSCommLib llamado "comSerial" public Ser i al Ter m( ) { // Inicializa los componentes del Form I ni t i al i zeComponent ( ) ;
// Inicializa el control del Puerto COM I ni t ComPor t ( ) ;
// Enva datos por el Puerto COM comSer i al . Out put = " Ser i al Ter mi nal I ni t i al i zed" ; }
private void I ni t ComPor t ( ) { // Establece com1 como Puerto serie comSer i al . CommPor t = 1;
// Si el puerto est abierto, se cierra para resetearlo. if ( comSer i al . Por t Open) comSer i al . Por t Open = f al se;
// Disparar el evento OnComm cuando se reciban datos comSer i al . RThr eshol d = 1;
// Configurar el puerto a 9600 baudios, sin paridad, 8 bits de datos y un bit de stop comSer i al . Set t i ngs = " 9600, n, 8, 1" ;
Escuela Tecnica Superior de Ingenieros de Bilbao Artculos y colaboraciones C# // Forzar el DTR a nivel alto, usado a menudo por los modems comSer i al . DTREnabl e = t r ue;
// No se usa control de trfico comSer i al . Handshaki ng = MSCommLi b. HandshakeConst ant s. comNone;
// Trabajar slo con cadenas de texto comSer i al . I nput Mode = MSCommLi b. I nput ModeConst ant s. comI nput ModeText ;
// Usar esta lnea para entradas de arrays de bytes. //comSerial.InputMode = MSCommLib.InputModeConstants.comInputModeText;
// Leer todos los datos del buffer de entrada cuando se usa comSerial.Input comSer i al . I nput Len = 0;
// No descartar los bytes nulos, 0x00 es un byte til comSer i al . Nul l Di scar d = f al se;
// Agregar el controlador de eventos comSer i al . OnComm+= new Syst em. Event Handl er ( t hi s. OnComm) ;
// Abrir el puerto comSerial comSer i al . Por t Open = t r ue; }
private void OnComm( object sender , Event Ar gs e) // Controlador de eventos del puerto serie { // Si hay datos esperando en el buffer, procesarlos. if ( comSer i al . I nBuf f er Count > 0) Pr ocessComDat a( ( st r i ng) comSer i al . I nput ) ; }
private void Pr ocessComDat a( string i nput ) { // Enviar los datos recibidos a un Rich Text Box r t f Ter mi nal . AppendText ( i nput + " \ n" ) ; }
Enviando datos con arrays de bytes Generalmente es ms 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 nmeros. Si ests usando un programa con cuadros de texto y ves caracteres extraos, necesitars utilizar arrays de bytes. A continuacin te explico cmo: Escuela Tecnica Superior de Ingenieros de Bilbao Artculos y colaboraciones C# 1. Configurar el comSerial.Input para recibir arrays de bytes. comSerial.InputMode = MSCommLib.InputModeConstants.comInputModeBinary; 2. Cuando recibas datos, gurdalos en un array de bytes. private void OnComm( object sender , Event Ar gs e) // Controlador de eventos { // Recibir datos en un array de bytes, una buena idea para cualquier tipo de datos byt e[ ] i ndat a = ( byt e[ ] ) comSer i al . I nput ;
// Mostrar cada byte en la consola de salida f or each ( byte b i n i ndat a) Consol e. Wr i t eLi ne( " Byt e Dat a: " + b) ; }
Recibiendo paquetes de datos La recepcin de los datos puede ser complicada si no se envan todos a la vez. Si envas "Hola Mundo" por el puerto serie, es posible que en la recepcin aparezca en muchos trozos, como por ejemplo "Ho", "la ", "M", "un", "do". Para evitarlo existen diversas tcnicas. A continuacin se muestra una de ellas: Usar llaves de start y stop Este es el mtodo ms comn. 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 cdigo siguiente es un buen ejemplo de este mtodo: // Usaremos Regular Expressions para las llaves 'start'/'stop' usi ng Syst em. Text . Regul ar Expr essi ons;
// private string ComBuf f er = " " ;
private void OnComm( object sender , Event Ar gs e) // Controlador de eventos { // Aadir al buffer los datos de entrada ComBuf f er += ( st r i ng) comSer i al . I nput ;
// 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 ( Mat ch m= r . Mat ch( ComBuf f er ) ; m. Success; m= m. Next Mat ch( ) ) { Escuela Tecnica Superior de Ingenieros de Bilbao Artculos y colaboraciones C# // Mostrar el resultado por consola Consol e. Wr i t eLi ne( m. Val ue) ;
// Eliminar los datos del buffer ComBuf f er = ComBuf f er . Repl ace( m. Val ue, " " ) ; } }