Upload
sbctecnologias-sa-de-cv
View
291
Download
2
Embed Size (px)
Citation preview
Autor: Andrés Gerardo Fuentes Covarrubias 1
Comunicaciones seriales
Caso: Visual C# 2010 Express PIC18F4550 - CCS – PICC
M.C. ANDRÉS GERARDO FUENTES COVARRUBIAS
Materia: Sistemas Embebidos y Control – SEPTIMO SEMESTRE Ingeniero en Sistemas Computacionales Universidad de Colima Facultad de Ingeniería Mecánica y Eléctrica Academia de Arquitectura de Computadoras
Autor: Andrés Gerardo Fuentes Covarrubias 2
Metodología
Creación de una nueva aplicación
Instalación de Virtual Serial Port
toolStrip y componentes básicos
Manejo de los puertos seriales
Apertura de un puerto
Transmisión
Recepción
Autor: Andrés Gerardo Fuentes Covarrubias 3
Virtual Serial Port
Forma comoda de depurar las aplicaciones al crear puertos seriales virtuales pareados
Un puerto serial para la simulación en ISIS Proteus
Un puerto serial para el programa en Visual C# 2010
Autor: Andrés Gerardo Fuentes Covarrubias 4
Creación de una nueva aplicación
Abrir VC# 2010 y elegir “Archivo”->”Nuevo Projecto”
Después “Aplicación de Windows Forms y el botón “Aceptar” después de darle nombre al nuevo proyecto
Autor: Andrés Gerardo Fuentes Covarrubias 5
Manejo de los puertos seriales • Elegir dos controles:
1. Para manejo de los puertos
seriales: “SerialPort”, será el
encargado de manejar todas las propiedades, métodos y eventos relacionados con el puerto o los puertos seriales de la aplicación, crear tantos como puertos seriales se necesite.
• Elegir dos controles:
2. Para manejo de los controles básicos de las comunicaciones seriales, asi como mensajes e indicadores, elija el control “ToolStrip”
Estos controles no son visibles en la forma principal, por lo tanto se colocan en el “Status Strip”
Autor: Andrés Gerardo Fuentes Covarrubias 6
Manejo de puertos seriales
Controles en la aplicación, ToolStrip.
Observe que para .Net el control para puerto serial contiene todas las propiedades para las características de la trama en tiempo de diseño
ComboBox
TextBox Boton Label
Autor: Andrés Gerardo Fuentes Covarrubias 7
Manejo de puertos seriales
Controles en la aplicación, área de trabajo
TabControl
OvalShape
Botones
Label
Autor: Andrés Gerardo Fuentes Covarrubias 8
Código fuente inicial
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.IO.Ports; using System.Threading; using Microsoft.VisualBasic.PowerPacks; namespace consolaSerialCDC { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } }
El código fuente inicial solo describe las librerías a ser utilizadas al momento y el esqueleto inicial para el “namespace” correspondiente a nuestra aplicación.
Agregar estas referencias externas
Autor: Andrés Gerardo Fuentes Covarrubias 9
Manejo de los puertos seriales
if(!serialPort1.IsOpen) { try { serialPort1.Open(); } catch (System.Exception ex) { MessageBox.Show(ex.ToString()); } }
La apertura de un puerto serial en Visual C# es tan sencillo como agregar el siguiente código al botón “Conectar” del ToolStrip:
Las propiedades del control SerialPort se pueden establecer en tiempo de diseño mediante el cuadro de propiedades.
Autor: Andrés Gerardo Fuentes Covarrubias 10
Apertura de un puerto
serialPort1.BaudRate = 9600; // Velocidad de transmisión serialPort1.Parity = Parity.None; //Tipo de paridad serialPort1.DataBits = 8; //Número de bits de datos serialPort1.StopBits = StopBits.One; //Número de bits de parada serialPort1.PortName = toolStripTextBox1.Text; //Use el control adecuado para el usuario serialPort1.Open(); //Abrir el puerto
Siempre se puede abrir un puerto con el código siguiente y tambien establecer las caracteristicas de la trama:
Vincule el código anterior con un botón y podrá abrir el puerto serial capturado en el control “toolStripTextBox1” al presionar el botón “Conectar”
Autor: Andrés Gerardo Fuentes Covarrubias 11
Transmisión •Siempre que haya un puerto serial abierto se puede enviar datos por ese puerto.
•En el TabControl “Terminal”
•Agregue dos controles
•TextBox
•Botón
private void button1_Click(object sender, EventArgs e)
{ if (conectado == true) { if (tbTerminalEnviar.Text.Length > 0) { serialPort1.WriteLine("@" + tbTerminalEnviar.Text + "\r"); } else { MessageBox.Show("MENSAJE VACIO"); } } else { MessageBox.Show("Puerto Serial NO CONECTADO"); } }
Agregue el código del botón
Autor: Andrés Gerardo Fuentes Covarrubias 12
Transmisión
byte[] miBuffer= new byte[1]; miBuffer[0] = 0x62; //Carácter a enviar por el puerto. SP1.Write(miBuffer, 0, miBuffer.Length);
Siempre es posible enviar también un solo caracter por el puerto serial:
// Enviar trama byte[] miBuffer= new byte[3]; // Tres caracteres máximo. miBuffer[0] = 0x74; miBuffer[1] = 0x54; miBuffer[2] = 0x13; SP1.Write(miBuffer, 0, miBuffer.Length);
Por ejemplo, si lo que se desea es enviar una trama completa, entonces:
Autor: Andrés Gerardo Fuentes Covarrubias 13
Transmisión
Tambien se puede vincular código a otros controles de usuario:
strBufferOut = "1"; //Buffer de transmisión serialPort1.DiscardOutBuffer(); //Limpiamos el buffer de transmisión serialPort1.Write(strBufferOut); //Enviar caracteres
Cada control incluye código:
Indicadores con el control Ovalshape para simular leds.
Salidas por botón
Autor: Andrés Gerardo Fuentes Covarrubias 14
Recepción
El proceso de recepción de datos es un proceso un poco mas complejo, ya que es necesario instalar el vector de interrupción del evento “DataReceived” y crear un nuevo Thread (hilo) que atienda al manejador de ese evento.
Autor: Andrés Gerardo Fuentes Covarrubias 15
Recepción Crear un nuevo control TextBox, que sea multilinea, con ScrollBar vertical y ajustado a la parte inferior del formulario. Este control va a operar como nuestra consola del usuario, para desplegar mensajes de la aplicación, los datos enviados y los recibidos.
Autor: Andrés Gerardo Fuentes Covarrubias 16
Recepción
1. Codigo de al cargar el formulario:
public Form1() {
txtRecibidos.Text = ""; strBufferIn = ""; serialPort1.DataReceived += new SerialDataReceivedEventHandler( serialPort1_DataReceived);
}
Para crear un manejador, se debe agregar un nuevo manejador de eventos, y vincularlo con el método apropiado del control “serialPort”, el procedimiento consta de tres pasos:
Autor: Andrés Gerardo Fuentes Covarrubias 17
Recepción 2. El codigo del manejador de eventos private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{ strBufferIn = ""; //Debemos hacer una pausa, para que el buffer se llene por completo //y pueda cargar todos los datos. //Si esta pausa no se realiza, no carga las lineas por completo y solo //nos muestra parte del mensaje enviado. Thread.Sleep(250); strBufferIn += serialPort1.ReadExisting(); if (serialPort1.BytesToRead > 0) strBufferIn += serialPort1.ReadExisting(); String Linea; Linea = strBufferIn; //Guardamos la cadena original para "Split" //Posterior this.Invoke(new EventHandler(Actualiza_textbox)); }
Autor: Andrés Gerardo Fuentes Covarrubias 18
Recepción
2. El codigo del “delegado” private void Actualiza_textbox(object s, EventArgs e) { txtRecibidos.Text += strBufferIn + "\r\n"; }
Autor: Andrés Gerardo Fuentes Covarrubias 19
Status Strip
Siempre es posible manejar la barra de estado de nuestro formulario:
•Barra de estado
•Menú de opciones
Autor: Andrés Gerardo Fuentes Covarrubias 20
Status strip
Agregue un control “timer”
Para agregar el reloj del sistema a la barra de estado:
Configure las propiedades
Autor: Andrés Gerardo Fuentes Covarrubias 21
Status strip
Ejecute los siguientes pasos en el orden indicado:
Agregar el código al control del timer:
private void timer1_Tick(object sender, EventArgs e) { statusStrip1.Items[0].Text = DateTime.Now.ToLongTimeString(); }
1 2 3
Cambie la propiedad “Text” a “hh:mm:ss”
Autor: Andrés Gerardo Fuentes Covarrubias 22
Caso de estudio
Interfaz serial RS232C Max232
Circuito LM35z a °C
Registrador de temperaturas
Graficador de 2 canales
Base de datos sqlServer
Autor: Andrés Gerardo Fuentes Covarrubias 23
ESQUEMATICO VERSION 1
Autor: Andrés Gerardo Fuentes Covarrubias 24
Controles para el modelado en Proteus ISIS
ComPim: Para salida de datos por medio de un Virtual Port
Monitoreo por medio de la Terminal Virtual
Autor: Andrés Gerardo Fuentes Covarrubias 25
LoopBack serial Isis Proteus
Interconecta por “cable cruzado” la terminal virtual y el control ComPim
Por medio de un programa de hiperterminal se puede monitorear la actividad serial RS232C
No se necesita convertidor de protocolo MAX232
Autor: Andrés Gerardo Fuentes Covarrubias 26
Modelo de programación del microcontrolador PIC18F4550 para comunicaciones seriales
Comunicaciones Full-Duplex
Compatibilidad 9600, 8 , N, 1
Programable en ensamblador y lenguaje de alto nivel
BaudRate totalmente configurable
Capaz de manejar e identificar paridad
Autor: Andrés Gerardo Fuentes Covarrubias 27
Pinout del Pic18F4550
Autor: Andrés Gerardo Fuentes Covarrubias 28
Comunicaciones en CCS
La inicialización de interfases seriales, tanto Hardware como Software se llevan a cabo por medio de la instrucción:
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)
La salida de datos y caracteres ahora pueden llevarse a cabo por medio de la instrucción printf(), respetando todos los formatos de dicha instrucción.
Tambien se puede usar la instrucción putchar() para sacar un carácter individual en cualquier momento
La lectura de caracteres se puede llevar a cabo por medio de la instrucción getchar()
Autor: Andrés Gerardo Fuentes Covarrubias 29
Ejemplo de salida de datos
Autor: Andrés Gerardo Fuentes Covarrubias 30
Codigo de salida de datos
lcd_putc("Terminal Serial "); printf("Terminal Serial %c%c",13,10); while(1) // Ciclo infinito { lcd_gotoxy(1,2); // Posicionamos cursor renglon 2 printf(lcd_putc,"%u",a); // Desplegar el valor de a printf("%u %c %c",a,13,10); // Sacamos por el puerto serial + CrLf output_bit(LED,1); // Encendemos el Led delay_ms(500); // Retardo de 500 milisegundos prendido output_bit(LED,0); // Apagamos el Led delay_ms(500); // Retardo de 500 milisegundos apagado a++; // Incrementamos en 1 la variable if(input(Boton)==0) // Se presiono el Boton? { delay_ms(100); // Retardo para quitar el rebote if(input(Boton)==0) // Todavia esta presionado? procesar { lcd_gotoxy(1,1); // Posicionamos cursos renglon 1 printf(lcd_putc,"Presiono Boton"); // Desplegamos el mensaje while(input(Boton)==0); // Ahi esperamos hasta que se suelte el Boton output_bit(LED,0); // Apagamos el Led lcd_putc('\f'); // Borramos la pantalla a=0; // Limpiamos la variable } printf(lcd_putc,"Hola Mundo"); // Dejamos el LCD como estaba antes del Boton } if(valor=="1") output_toggle(LED1); }
Autor: Andrés Gerardo Fuentes Covarrubias 31
Entrada de datos en CCS
Recomendable usar interrupciones para el puerto serial
Por cada carácter recibido, meterlo a un buffer y procesar cuando sea necesario
Autor: Andrés Gerardo Fuentes Covarrubias 32
Ejemplo de entrada de datos • Monitorear por medio de Terminal Virtual.
• Entrada de datos por medio del control ComPim
Autor: Andrés Gerardo Fuentes Covarrubias 33
Tipos de interrupciones en CCS #INT_xxx - Indica que la función que le sigue (en el código fuente CCS) es una
función de interrupción. Estas funciones no deben tener parámetros. Por supuesto,
no todos los PICs soportan todas las directivas disponibles:
INT_AD Conversión A/D finalizada. I NT_ADOF Conversión A/D timeout. INT_BUSCOL Colisión en bus. INT_BUTTON Pushbutton. INT_CCP1 Unidad CCP1. INT_CCP2 Unidad CCP2. INT_COMP Comparador. INT_EEPROM Escritura finalizada. INT_EXT Interrupción externa. INT_EXT1 Interrupción externa #1. INT_EXT2 Interrupción externa #2. INT_I2C Interrupción por I2C. INT_LCD Actividad en el LCD.
INT_LOWVOLT Bajo voltaje detectado. INT_PSP Ingreso de datos en el Parallel
Slave Port. INT_RB Cambios en el port B (B4-B7). INT_RC Cambios en el port C (C4-C7). INT_RDA Datos disponibles en RS-232. INT_RTCC Desbordamiento del Timer 0
(RTCC). INT_SSP Actividad en SPI o I2C. INT_TBE Buffer de transmisión RS-232
vacío. INT_TIMER0 Desbordamiento del Timer 0
(RTCC). INT_TIMER1 Desbordamiento del Timer 1. INT_TIMER2 Desbordamiento del Timer 2. INT_TIMER3 Desbordamiento del Timer 3.
Autor: Andrés Gerardo Fuentes Covarrubias 34
Las interrupciones por el puerto serie
Cada que llega un carácter al puerto serie por medio de la linea [RC7/RX/DT/SDO (26)] el microcontrolador, mediante la lógica de interrupciones, transfiere el control del flujo del programa a la primera instrucción
despues de la etiqueta #int_rda
Por medio de las interrupciones no es necesario sondear en la función main() el estado de la linea de recepción de datos seriales.
Autor: Andrés Gerardo Fuentes Covarrubias 35
Código de la rutina de servicio a interrupción (ISR)
#int_rda //Rutina de servicio a interrupcion void serial_isr() { valor=getchar(); //Leer el carácter recibido del buffer //de recepcion }
• Activar la recepción de interrupciones globales y por el puerto serial:
//------------------------------------------------------------------------------------------------ //Inicialización del microcontrolador //----------------------------------- enable_interrupts(global); //Habilitar las interrupciones globales enable_interrupts(int_rda); //Habilitar la interrupcion por recepcion //de caracteres en el puerto serial setup_adc_ports(NO_ANALOGS); //Las entradas analogicas configuradas como digitales set_tris_b(0); //Todas salidas puerto B set_tris_d(0b00000001); //RD0 salida de led de estado output_b(0); //Apagamos todos los leds
Autor: Andrés Gerardo Fuentes Covarrubias 36
Ejemplo de entrada de datos Consulte el código siguiente, para
recepción de datos por medio del método de interrupción:
#include "18f4550.h" #device adc=10 //Resolucion del ADC 8/10 bits //---------------------------------------------------------------------------------------------------- //Bits de configuración #fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN, WRTB,CPB //---------------------------------------------------------------------------------------------------- //USES de configuracion de perifericos //Configuración del oscilador del CPU #use delay(clock=48000000) #include <stdlib.h> #include <LCD.c> //Configuracion de la USART1 #use rs232(baud=9600,parity=N,RCV=PIN_C7,XMIT=PIN_C6,bits=8) #use standard_io(e) #use standard_io(d) #use standard_io(c) #use standard_io(b) #use standard_io(a)
Autor: Andrés Gerardo Fuentes Covarrubias 37
//---------------------------------------------------------------------------------------------------- //Redireccionamiento de los vectores de interrupción para adaptarlos al HidBootloader //#build(reset=0x1000,interrupt=0x1008) //#org 0x0000,0x0FFF {} //---------------------------------------------------------------------------------------------------- //Definición de simbolos y variables globales #define LED1 PIN_B0 #define LED2 PIN_B1 #define LED3 PIN_B2 #define LED4 PIN_B3 #define LED5 PIN_B4 #define LED6 PIN_B5 #define LED7 PIN_B6 #define LED8 PIN_B7 #define LED PIN_E0 char valor; char flagIsr; char flagAnalogo; int muestra; float voltaje; float temperatura; int canal=1; int ADC_ACQT_2TAD=0x1;
Autor: Andrés Gerardo Fuentes Covarrubias 38
//---------------------------------------------------------------------------------------------------- //Rutinas de servicio a interrupcion #int_rda void serial_isr() { valor=getc(); /Leemos el caracter recibido del buffer de recepcion output_toggle(LED); //Mostramos mediante un Led que hay actividad en el delay_ms(100); //canal de datos output_toggle(LED); flagIsr=1; //Activamos la bandera de recepcion //-Segun el caracter recibido activamos la alarma correspondiente switch(valor) { case '1': output_toggle(LED1); break; case '2': output_toggle(LED2); break; case '3': output_toggle(LED3); break; case '4': output_toggle(LED4); break; case '5': output_toggle(LED5); break;
Autor: Andrés Gerardo Fuentes Covarrubias 39
case '6': output_toggle(LED6); break; case '7': output_toggle(LED7); break; case '8': output_toggle(LED8); break; case '0': output_b(0); break; case '@': output_b(255); break; case '#': flagAnalogo=1; break; } }
Autor: Andrés Gerardo Fuentes Covarrubias 40
//---------------------------------------------------------------------------------------------------- //Programa principal void main(void) { //------------------------------------------------------------------------------------------------ //Variables y constantes del programa //------------------------------------------------------------------------------------------------ //Inicialización del microcontrolador //----------------------------------- enable_interrupts(global); //Habilitar las interrupciones globales enable_interrupts(int_rda); //Habilitar la interrupcion por recepcion //de caracteres en el puerto serial setup_vref(FALSE); setup_adc_ports( AN0 || VSS_VDD ); //Inicializamos el puerto analogico AN0 setup_adc(ADC_CLOCK_DIV_64 || ADC_ACQT_2TAD ); set_tris_b(0); //Todas salidas puerto B set_tris_e(0b00000001); //RD0 salida de led de estado output_b(0); //Apagamos todos los leds lcd_init(); //Inicializamos el lcd lcd_putc('\f'); //Borramos la pantalla del lcd
Autor: Andrés Gerardo Fuentes Covarrubias 41
//------------------------------------------------------------------------------------------------ //Rutina principal //------------------- printf("Terminal Serial %c%c",13,10); while(1) // Ciclo infinito { if(flagIsr==1) { //printf("Recibido:%c %c %c",valor,13,10); //Desplegamos el caracter recibido por la consola para //monitorear la recepcion correcta+ CrLf flagIsr=0; //Preparamos la bandera de entrada a ISR para solo //desplegar el valor cuando haya caracter recibido } if(flagAnalogo==1) { disable_interrupts(global);//Habilitar las interrupciones globales disable_interrupts(int_rda);//Habilitar la interrupcion por recepcion set_adc_channel(0); //Seleccionamos el canal a muestrear muestra= read_adc(); //Una lectura por el ADC delay_us(10); //Delay para espera termino de conversion
Autor: Andrés Gerardo Fuentes Covarrubias 42
voltaje = 5.0*muestra / 1024.0; //Convertimos a voltaje otra vez temperatura=voltaje/0.010; //Ahora a temperatura 10mV/°C lcd_putc('\f'); //Borramos la pantalla primero lcd_gotoxy(1,1); printf(lcd_putc,"v=%01.2f", voltaje); lcd_gotoxy(1,2); printf(lcd_putc,"%04d",muestra); printf("1,%01.2f,%01.2f;",temperatura,voltaje); //Enviar al datalogger flagAnalogo=0; enable_interrupts(global);//Habilitar las interrupciones globales enable_interrupts(int_rda);//Habilitar la interrupcion por recepcion } } }
Autor: Andrés Gerardo Fuentes Covarrubias 43
Principales mandatos para manejar el puerto serial CCS
Inicialización del puerto serial
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)
Recepción de datos c = GETC() //Todas son equivalentes y básicamente esperan por un carácter c = GETCH() // a ser recibido por la patilla RC6/RX del puerto serial c = GETCHAR() Ejemplo:
printf("Continuar (s,n)?");
do
{
respuesta=getch();
} while(respuesta!='s'&& respuesta!='n');
GETS(char *string) //Esta función lee caracteres (usando GETC()) de la cadena (string) //hasta que encuentra un retorno de carro(valor ASCII 13). La cadena //se termina con un 0.
Autor: Andrés Gerardo Fuentes Covarrubias 44
Principales mandatos para manejar el puerto serial CCS
KBHIT()
Esta función devuelve TRUE si el bit que se está enviando al pin RCV de un dispositivo RS232, es el bit de inicio de un carácter. Es preciso utilizar la directiva #USE RS232 antes de la llamada a esta función para que el compilador pueda determinar la velocidad en baudios y la patilla utilizada.
Ejemplo: keypress=' '; while ( keypress!='Q' ) //Entramos al bucle while { if ( kbhit () ) keypress=getc(); //En la variable keypress se guardan los
//caracteres if (keypress==‘1’) //Inicio del envío de un byte output_high(PIN_B3); else output_low(PIN_B3) }
Autor: Andrés Gerardo Fuentes Covarrubias 45
Principales mandatos para manejar el puerto serial CCS
Transmisión serial
PUTC() //Ambas instrucciones son equivalentes, basicamente
PUTCHAR() //envían un carácter a la patilla XMIT(RC7/TX) de //del dispositivo RS232 del microcontrolador.
Ejemplo:
if (checksum==0)
putchar(ACK);
else
putchar(NAK); // NAK carácter de respuesta negativa
PUTS(string) //Esta función envía cada carácter de string a la //patilla XMIT del dispositivo RS232. Una
//vez concluido el envío de todos los caracteres la //función envía un retorno de carro CR o RETURN (ASCII 13)
//y un avance de línea LF o LINE-FEED (ASCII 10).
Ejemplo: puts( " | HOLA |" );
Autor: Andrés Gerardo Fuentes Covarrubias 46
Principales mandatos para manejar el puerto serial CCS Función printf() y modificadores
La función de impresión formateada printf() saca una cadena de caracteres al puerto serie RS-232 (previamente inicializado mediante #use rs232…), o a una función especificada (por ejemplo lcd_putc()). El formato está relacionado con el argumento que ponemos dentro de la cadena (string).
Sintaxis: printf([function], string, [values])
Los modificadores de formato se incluyen dentro de “string” e inician con el carácter %, opcionalmente se puede redirigir la salida de printf() hacia una función de manejo de flujo de caracteres como lcd_putc() que envia flujo de caracteres hacia un lcd alfanumérico o gráfico.
Ejemplos:
byte x,y,z; printf (" Hola "); printf("RTCCValue=>%2x\n\r",get_rtcc()); printf("%2u %X %4X\n\r",x,y,z); printf(lcd_putc, "n=%c",n);
Autor: Andrés Gerardo Fuentes Covarrubias 47
Manejo del buffer de recepción en Visual C#
Control mas efectivo sobre los caracteres delimitadores
Posibilidad de hacer parsing en línea
Autor: Andrés Gerardo Fuentes Covarrubias 48
Manejo del buffer de recepción (código)
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
recibidos = "";
carSerial = (char) 0;
while(carSerial!=';')
{
carSerial = (char) serialPort1.ReadChar();
if (carSerial == ';')
break;
recibidos += carSerial.ToString();
}
this.Invoke(new EventHandler(Actualiza_textbox));
}
Autor: Andrés Gerardo Fuentes Covarrubias 49
Split Tokens en C#
Use un delimitador de campo, por lo general es el caracter “,”
Use un delimitador de cadena, por lo general es el caracter “;”
Use el método Split
Procese los tokens encontrados
Autor: Andrés Gerardo Fuentes Covarrubias 50
Código
public Form1() { InitializeComponent(); } private void btSplit_Click(object
sender, EventArgs e) { str = txtCadena.Text; string[] parts = str.Split(seps); for (int i = 0; i < parts.Length;
i++) cadenaSplit +=
parts[i]+"\r\n"; txtConsola.Text = cadenaSplit; } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace splitCampos { public partial class Form1 : Form { string str; char[] seps={','}; string cadenaSplit;
Autor: Andrés Gerardo Fuentes Covarrubias 51
Manejo del buffer de recepción (código para separar tokens)
private void Actualiza_textbox(object s, EventArgs e)
{ string[] parts = recibidos.Split(seps); //Tokenizamos la trama if (parts.Length == 3) //Validamos numero de //tokens encontrdos, deben ser 3 { lblTemp.Text = parts[1]; //Actualizamos etiquetas lblVolt.Text = parts[2]; } lblRecibido.Text = recibidos; //Visualizamos trama actual txtRecibidos.Text += recibidos+"\r\n"; //Actualizamos el textBox consola }
Autor: Andrés Gerardo Fuentes Covarrubias 52
Principales mandatos para manejar el puerto serial
'Definir las características de la comunicación Serie.BaudRate = 19200 'Fijar velocidad de comunicaciones Serie.DataBits = 8 'Longitud en bits para Byte de datos Serie.Parity = Parity.Even 'Asignar paridad(enumeration parity) Serie.StopBits = StopBits.Two 'Bits parada después byte de datos 'Abrir/Control/Liberar Puerto Serie.Open() 'Abrir el puerto Serie Serie.Close() 'Cerrar el Puerto Serie Serie.Dispose() 'Liberar objeto Dim SiNo As Integer SiNo = Serie.IsOpen 'El Puerto esta abierto? Dim Puerto As String Puerto = Serie.PortName 'Nombre del puerto
Autor: Andrés Gerardo Fuentes Covarrubias 53
Principales mandatos para manejar el puerto serial
'Manejo y Control de señales
Dim Estado As Boolean 'True=Activa / False=Inactiva
Estado = Serie.CDHolding 'Estado de la señal carrier detect Estado = Serie.CtsHolding 'Señal Clear to Send Estado = Serie.DsrHolding 'Señal Data Set Ready Serie.DtrEnable = True 'Activar de Data Terminal Ready Serie.RtsEnable = True 'Activar Request To Send
'Control Transmission/Recepcion Serie.ReadBufferSize = 1024 'Dimensionar tamaño buffer recepción Serie.WriteBufferSize = 1024 'Dimensionar tamaño buffer envío Serie.ReadTimeout = 10 'Fuera de tiempo para las lecturas Serie.WriteTimeout = 10 'Fuera de tiempo para las escrituras Serie.Handshake = Handshake.XOnXOff 'Tipo control para recepción/envío Serie.DiscardInBuffer() 'Borrar el buffer de entrada Serie.DiscardOutBuffer() 'Borrar el buffer de salida
Autor: Andrés Gerardo Fuentes Covarrubias 54
Principales mandatos para manejar el puerto serial Visual C#
'Enviar datos Contador = Serie.BytesToWrite 'Bytes en espera de ser escritos Serie.Write("Hola Mundo") 'Enviar una cadena de caracteres Serie.WriteLine("Hola Mundo") 'Enviar una línea 'Leer datos Contador = Serie.BytesToRead 'Bytes en espera de ser leídos Serie.ReadByte() 'Leer un byte Serie.ReadChar() 'Leer un char Serie.ReadLine() 'Leer una línea Serie.ReadExisting() 'Leer los datos existentes en buffer
Autor: Andrés Gerardo Fuentes Covarrubias 55
Uso de ZedGraph
ZedGraph es uno de los controles mas utilizados en ingeniería para desplegar gráficos de puntos o líneas.
Como es un control externo es necesario instalarlo como un componente adicional.
Autor: Andrés Gerardo Fuentes Covarrubias 56
Uso de ZedGraph
La primera parte consiste en su inicialización
La segunda parte ocurre tambien en tiempo de ejecución y consiste en la impresión de los puntos recibidos y unirlos mediante lineas.
Autor: Andrés Gerardo Fuentes Covarrubias 57
1. Creación del control:
Autor: Andrés Gerardo Fuentes Covarrubias 58
2. Inicialización
Consiste en la inicialización del control
Generalmente se efectua al cargar la forma principal por primera vez
Se puede usar una función de usuario
1. Definir un objeto tipo lista:
PointPairList list1 = new PointPairList();
2. Crear la función de usuario:
private void inicializaGrafico(ZedGraphControl zgc)
{
GraphPane myPane = zgc.GraphPane;
// Titulos
myPane.Title.Text = "Gráfico de temperaturas";
myPane.XAxis.Title.Text = "Muestra";
myPane.YAxis.Title.Text = "Temperatura";
myPane.YAxis.Scale.Max = 150;
// Inicializa una curva con diamantes en cada muestra
// la palabra "temperatura" como titulo de la muestra
LineItem myCurve = myPane.AddCurve("Temperatura",
list1, Color.Red,
SymbolType.None);
}
3. Inicializarla dentro de Form_Load1
4. No olvidar referenciar el NameSpace ZedGraph con el Using correspondiente
Autor: Andrés Gerardo Fuentes Covarrubias 59
3. Código del usuario private void Form1_Load(object sender, EventArgs e) { UpdateSerialPorts(); inicializaGrafico(graficoTemp); }
private void inicializaGrafico(ZedGraphControl zgc) { GraphPane myPane = zgc.GraphPane; // Titulos myPane.Title.Text = "Gráfico de temperaturas"; myPane.XAxis.Title.Text = "Muestra"; myPane.YAxis.Title.Text = "Temperatura"; myPane.YAxis.Scale.Max = 150; // Inicializa una curva con diamantes en cada muestra tomada // la palabra "temperatura" como titulo de la muestra LineItem myCurve = myPane.AddCurve("Temperatura", list1, Color.Red,
SymbolType.None); }
Autor: Andrés Gerardo Fuentes Covarrubias 60
4. Función de recepción con Split campos
La recepción debe cambiar ya que tradicionalmente se procesa el buffer de recepción en conjunto.
Ahora deberá procesarse carácter a carácter hasta obtener un carácter de fin de trama = “;”
Despues de recibir el fin de trama deberá separarse los campos con el método Split
Autor: Andrés Gerardo Fuentes Covarrubias 61
private void Actualiza_textbox(object s, EventArgs e) { string[] parts = strBufferIn.Split(seps); if (parts.Length == 3) { lblTemp.Text = parts[1]; temperaturaCanal1 = Convert.ToSingle(parts[1]); numMuestra++; float x = (float)numMuestra; float y = (float)temperaturaCanal1; list1.Add(x, y); graficoTemp.AxisChange(); graficoTemp.Refresh(); lblVolt.Text = parts[2]; } txtConsola.Text += strBufferIn + "\r\n"; }
Autor: Andrés Gerardo Fuentes Covarrubias 62
RESOLUCIÓN DE DUDAS
Facebook: /Andres.FuentesCovarrubias