comunicaciones seriales c# 2012

55
Caso: Visual C# 2012 Express MICROCHIP MCP2200 Por: M.C. ANDRÉS GERARDO FUENTES COVARRUBIAS 1 Sistemas Digitales Avanzados

Upload: gerardo-c

Post on 17-Dec-2014

3.803 views

Category:

Education


3 download

DESCRIPTION

Recurso Didáctico para la Materia Sistemas Embebidos y Control

TRANSCRIPT

Page 1: Comunicaciones seriales c# 2012

Caso: Visual C# 2012 ExpressMICROCHIP MCP2200

Por:

M.C. ANDRÉS GERARDO FUENTES COVARRUBIAS

1

Sistemas Digitales Avanzados

Page 2: Comunicaciones seriales c# 2012

Instalación de Virtual Serial PortCreación de una nueva aplicación en

C# 2012 toolStrip y componentes básicosManejo de los puertos serialesApertura de un puertoTransmisiónRecepción

Autor: Andrés Gerardo Fuentes Covarrubias 2

Page 3: Comunicaciones seriales c# 2012

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# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 3

Page 4: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 4

Abrir VC# 2012 y elegir“Archivo”->”Nuevo Proyecto”

Después “Aplicación de Windows Forms y el botón “Aceptar” después de darle nombre al nuevo proyecto

Page 5: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 5

• 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.

2. Para manejo de los controles básicos de las comunicaciones seriales, así 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”

Page 6: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 6

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

Page 7: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 7

Controles en la aplicación, área de trabajo

TabControl

OvalShape

Botones

toolStrip

Page 8: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 8

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.

Por lo general, este esqueleto de Clase principal es creada por VisualStudio al momento de inicializar el nuevo proyecto.

Finalmente el desarrollador debe indicar explícitamente las referencias externas con instrucciones “using” seguidas del “namespace” relacionado con la librería.

Agregar estas referenciasexternas

Page 9: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 9

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.

Page 10: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 10

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”

Sin embargo, es recomendable usar los controles adecuados que listen los recursos reconocidos por el sistema y que los pongan a disposición del usuario de la aplicación, para eso se agregaran en el toolStrip.

Page 11: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 11

•Siempre que haya un puerto serial abierto se puede enviar datos por ese puerto.

•En el TabControl “Consola”, 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

Page 12: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias12

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 tramabyte[] 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:

Page 13: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 13

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

También se puede vincular código a otros controles de usuario:

Page 14: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 14

El control comboBox nos permite listar los recursos hardware de comunicaciones seriales.

También mediante un control “textBox” se puede visualizar el puerto serial seleccionado, posteriormente mediante un “Botón” ejecutar el código vinculado con la apertura del puerto.

Un control adicional tipo “Label” se puede visualizar si el puerto seleccionado esta en estado “Conectado” o “No Conectado”, también cambiar la propiedad “ForeColor” a Green o Red respectivamente.

Page 15: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 15

private void UpdateSerialPorts() { toolStripComboBox1.Items.Clear();

// Añadir solo los puertos válidos try { foreach (String d in SerialPort.GetPortNames()) { toolStripComboBox1.Items.Add(d);} } catch { UpdateSerialPorts(); return; }

toolStripComboBox1.SelectedIndex = toolStripComboBox1.Items.Count - 1; if (toolStripComboBox1.Items.Count > 0) { toolStripComboBox1.SelectedIndex = 0; toolStripTextBox1.Text = toolStripComboBox1.Items[toolStripComboBox1.SelectedIndex].ToString(); } }

Page 16: Comunicaciones seriales c# 2012

private void btActualizar_Click(object sender, EventArgs e)

{ UpdateSerialPorts(); }

Autor: Andrés Gerardo Fuentes Covarrubias 16

El código de “Actualizar” nos permite atender un evento de “Conexión en caliente”. Es decir cuando un usuario conecta una nueva interfaz serial USB cuando nuestra aplicación se esta ejecutando, de esta manera se puede actualizar la colección de datos del control “comboBox” y el usuario podrá localizar en esta su interfaz.

Page 17: Comunicaciones seriales c# 2012

Invocar la función UpdateSerialPorts() en nuestra función Form_Load1() para que la colección de nombres de puertos sea actualizada en el mismo momento de la carga de la forma principal.

private void Form1_Load(object sender, EventArgs e) { UpdateSerialPorts();

lblEstadoPuerto.Text = "No Conectado"; lblEstadoPuerto.ForeColor = Color.Red; conectado = false;

}

Autor: Andrés Gerardo Fuentes Covarrubias 17

Page 18: Comunicaciones seriales c# 2012

Agregar un evento para actualizar el textBox del toolStrip cada vez que el nombre de puerto serial cambie, de esta manera se podrá conectar el puerto serial correcto al presionar el botón “Conectar”

private void toolStripComboBox1_TextChanged(object sender, EventArgs e)

{ toolStripTextBox1.Text =

toolStripComboBox1.Items[toolStripComboBox1.SelectedIndex].ToString();

}

Autor: Andrés Gerardo Fuentes Covarrubias 18

Page 19: Comunicaciones seriales c# 2012

Agregue una variable booleana tipo bandera para el manejo del estado del puerto serial, de esta manera será mas cómoda la validación del estado de la interfaz de comunicaciones.

public Boolean conectado;

Autor: Andrés Gerardo Fuentes Covarrubias 19

Page 20: Comunicaciones seriales c# 2012

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 20

Page 21: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 21

Crear un nuevo control TextBox, que sea multilínea, 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.

Page 22: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 22

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:

Page 23: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 23

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)); }

Page 24: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 24

2. El codigo del “delegado”

private void Actualiza_textbox(object s, EventArgs e) { txtRecibidos.Text += strBufferIn + "\r\n"; }

Page 25: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 25

Siempre es posible manejar la barra de estado de nuestro formulario:

•Barra de estado

•Menú de opciones

Page 26: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 26

Agregue un control “timer”

Para agregar el reloj del sistema a la barra de estado:

Configure las propiedades

Page 27: Comunicaciones seriales c# 2012

Ejecute los siguientes pasos en el orden indicado:

Autor: Andrés Gerardo Fuentes Covarrubias 27

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”

Page 28: Comunicaciones seriales c# 2012

Control mas efectivo sobre los caracteres delimitadores

Posibilidad de hacer parsing en línea

Autor: Andrés Gerardo Fuentes Covarrubias 28

Page 29: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 29

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)); }

Page 30: Comunicaciones seriales c# 2012

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 SplitProcese los tokens encontrados

Autor: Andrés Gerardo Fuentes Covarrubias 30

Page 31: Comunicaciones seriales c# 2012

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; } }}

Autor: Andrés Gerardo Fuentes Covarrubias 31

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;

Page 32: Comunicaciones seriales c# 2012

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 32

Page 33: Comunicaciones seriales c# 2012

'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 33

Page 34: Comunicaciones seriales c# 2012

'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 34

Page 35: Comunicaciones seriales c# 2012

'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 35

Page 36: Comunicaciones seriales c# 2012

Interfaz serial RS232C MCP2200Circuito LM35z a °CRegistrador de temperaturasGraficador de 2 canales

Autor: Andrés Gerardo Fuentes Covarrubias 36

Page 37: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 37

El hardware de interfaz consta de un convertidor de protocolo serial – paralelo a USB, lo que lo hace muy atractivo para estas aplicaciones.

El circuito esta basado en el MCP2200 de Microchip, este cuenta con una DLL (librería) muy rica en funciones para configuración de patillaje, entrada de niveles digitales y salidas de control.

Page 38: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 38

Principales características:

•Modo full – duplex hasta 1Mbps•Manejo de la conexión en modo Virtual Serial Port bajo todas las versiones de Windows, Linux y Mac•Soporta Control de flujo•Hasta 8 pines de propósito general •Memoria de usuario de 256 bytes de propósito general•Leds de actividad para el monitoreo del bus

•Totalmente programable en lenguajes visuales mediante DLL de usuario.

Page 39: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 39

Page 40: Comunicaciones seriales c# 2012

Para la implementación del modelo de programación basta con instalar la referencia externa en el proyecto a la DLL provista por el fabricante.

Invocación de los objetos y métodos dentro del código del proyecto

Autor: Andrés Gerardo Fuentes Covarrubias 40

Page 41: Comunicaciones seriales c# 2012

bool ClearPin(pinNumber) Pone en nivel 0 “pinNumber”

bool SetPin(pinNumber) Pone en nivel 1 “pinNumber”

bool ReadPin(pinNumber, *pinValue) Lee el nivel lógico en la entrada “pinNumber”

y lo refleja en la variable booleana “pinValue” int ReadPinValue(pinNumber)

Lee el nivel lógico en la entrada “pinNumber”

Autor: Andrés Gerardo Fuentes Covarrubias 41

Page 42: Comunicaciones seriales c# 2012

bool ReadPort(*portValue) Lee el valor completo del puerto GPx

como int y lo refleja en la variable “portValue”

bool ReadPort(*portValue)

bool WritePort(portValue)

Autor: Andrés Gerardo Fuentes Covarrubias 42

Page 43: Comunicaciones seriales c# 2012

void InitMCP2200(VID, PID)bool ConfigureIO(mask)

Autor: Andrés Gerardo Fuentes Covarrubias 43

Page 44: Comunicaciones seriales c# 2012

bool IsConnected() int ReadEEPROM(uiEEPAddress) int WriteEEPROM(uiEEPAddress,

ucValue)

Autor: Andrés Gerardo Fuentes Covarrubias 44

Page 45: Comunicaciones seriales c# 2012

ComPim: Para salida de datos por medio de un Virtual Port

Monitoreo por medio de la Terminal Virtual

Autor: Andrés Gerardo Fuentes Covarrubias 45

Page 46: Comunicaciones seriales c# 2012

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 46

Page 47: Comunicaciones seriales c# 2012

Comunicaciones Full-DuplexCompatibilidad 9600, 8 , N, 1Programable en lenguaje de alto

nivelBaudRate totalmente configurableCapaz de manejar e identificar

paridad

Autor: Andrés Gerardo Fuentes Covarrubias 47

Page 48: Comunicaciones seriales c# 2012

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 48

Page 49: Comunicaciones seriales c# 2012

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 49

Page 50: Comunicaciones seriales c# 2012

Autor: Andrés Gerardo Fuentes Covarrubias 50

Page 51: Comunicaciones seriales c# 2012

Consiste en la inicialización del control

Generalmente se efectúa 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_Load14. No olvidar referenciar el NameSpace ZedGraph con

el Using correspondiente

Autor: Andrés Gerardo Fuentes Covarrubias 51

Page 52: Comunicaciones seriales c# 2012

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 52

Page 53: Comunicaciones seriales c# 2012

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 53

Page 54: Comunicaciones seriales c# 2012

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 54

Page 55: Comunicaciones seriales c# 2012

[email protected] [email protected] [email protected]:

/Andres.FuentesCovarrubias

Autor: Andrés Gerardo Fuentes Covarrubias 55