Comunicación Serial Wpf
Bienvenid@ lector/a, en esta nueva entrada veremos cómo leer
y escribir datos a un puerto serial, específicamente el puerto serial corresponderá
al de un Arduino, por lo cual el Puerto COM queda habilitado automáticamente cuando
instalas Arduino IDE.
Primero que todo que es comunicación serial o serie, según es.wikipedia.org la comunicación serie es el proceso de envió de datos de un bit a la vez, de forma secuencial, sobre un canal de comunicación o un bus de datos.
Primero que todo que es comunicación serial o serie, según es.wikipedia.org la comunicación serie es el proceso de envió de datos de un bit a la vez, de forma secuencial, sobre un canal de comunicación o un bus de datos.
Imagen referencia: Señales de comunicación serie.
Empezando crearemos un una nueva solución para WPF tal como
se muestra en el siguiente LINK
A continuación crearemos la interfaz gráfica como se muestra
en la Imagen 1.
Imagen 1: Interfaz gráfica
primaria.
Como paso siguiente crearemos una nueva clase llamada “ScrollingTextBox”,
esta clase se encargara de ir actualizando el TextBox de log (txtRecibe), es
decir, su función es agregar el texto recibido o enviado en el TextBox y además
dejar el Scroll de este mismo en la última línea escrita. Para realizar esto
deben de seguir los pasos de la Imagen 2 e Imagen 3.
Imagen 2: Agregar nueva clase.
Imagen 3: Nombrar la nueva clase y crearla.
Una vez hecho lo anterior deben de pegar el siguiente Código,
el que se encargara de lo antes mencionado.
1: using System;2: using System.Collections.Generic;3: using System.Linq;4: using System.Text;5: using System.Threading.Tasks;6: using System.Windows.Controls;7:
8: namespace Serial9: {
10: public class ScrollingTextBox : TextBox11: {
12:
13: protected override void OnInitialized(EventArgs e)14: {
15: base.OnInitialized(e);16: VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
17: HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
18: }
19:
20: protected override void OnTextChanged(TextChangedEventArgs e)21: {
22: base.OnTextChanged(e);23: CaretIndex = Text.Length;
24: ScrollToEnd();
25: }
26:
27: }
28: }
Luego de realizar el paso anterior nos enfocaremos netamente en el “MainWindows.xaml.cs”, ya que este se encargara de toda la lógica del programa. En primer lugar agregaremos las librerías necesarias para la comunicación Serial.
- System.IO.Ports
- System.Collections.Concurrent
- System.Windows.Threading
- System.Threading
- System.Collections.Generics
Una vez importadas, inicializaremos las variables que se
implementaran.
1: private SerialPort _serialport;
2: private DateTime _datetime;
3: private int[] frecuencias;
4: private String comparacion;
Iniciaremos los valores por defectos de las frecuencias o
baudios que se utilizan para la comunicación serial, y los puertos COM
disponibles en el sistema.
1: frecuencias = new int[]{4800,9600,19200,38400,57600,115200,230400,250000};
2: foreach (String s in System.IO.Ports.SerialPort.GetPortNames())
3: {
4: comboPuertos.Items.Add(s);
5: }
6:
7: comboFrecuencia.ItemsSource = frecuencias;
Enseguida crearemos un método que se encargara de realizar
la conexión serial entre nuestra PC y el dispositivo físico o virtual en cuestión.
1: private void conectar_puertoserial(String puerto, int frecuencia)
2: {
3: _serialport = new SerialPort(puerto, frecuencia, Parity.None, 8, StopBits.One);
4:
5: String formato = string.Format("Conectado");
6: try
7: {
8: _serialport.Open();
9: actualiza_consolaUI(formato);
10: _serialport.DataReceived += new SerialDataReceivedEventHandler(SerialPortDataReceived);
11: }
12: catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error"); }
13: }
El fragmento anterior recibe como parámetro un puerto como
cadena y una frecuencia de baudios en entero, luego se instancia un objeto tipo
SerialPort con los datos recibido y algunos parámetros extras de configuración,
en seguida abre el puerto y enseña visualmente que se conectó, y empieza a
recibir los datos a través del método “SerialPortDataReceived” que se
programara enseguida.
El método “SerialPortDataReceived” como su nombre lo indica
se encarga de recibir todos los datos que se envíen desde el puerto COM
conectado.
1: private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
2: {
3: String reciberx = _serialport.ReadExisting();
4: String formato = string.Format("Recibido:{0}",reciberx.TrimEnd());
5:
6: if (reciberx.Length > 2 && reciberx != comparacion)
7: {
8: actualiza_consolaUI(formato);
9: comparacion = reciberx;
10: }
11: }
El fragmento anterior guarda el dato en una cadena de texto,
solo si existe algo que recibir, es decir si el dispositivo conectado en este
caso Arduino envía datos, en seguida pregunta si el largo de la cadena recibida
tiene un tamaño deseado y es diferente a una variable de comparación. La variable
de comparación se encarga de verificar que la cadena recibida sea diferente a
una anterior, para así liberar carga cuando venga repetida.
El método “actualizar_consolaUI” se encarga de actualizar el
log de lo que se esta realizando, todas las acciones dentro de este método esta
bajo un hilo del sistema, ya que si no se hiciera en segundo plano la modificación
visual de los elementos de WPF estos harían saltar un error de hilos
1: private void actualiza_consolaUI(String s) {
2: Application.Current.Dispatcher.Invoke(
3: DispatcherPriority.Background,
4: new ThreadStart(delegate
5: {
6: _datetime = DateTime.Now;
7: String formato = String.Format("[{0}]{1}\n", _datetime, s);
8: txtrecibe.AppendText(formato);
9: txtrecibe.Focus(); //Obtiene el focus
10: txtrecibe.CaretIndex = txtrecibe.Text.Length; //Obtiene el tamaño de la caja
11: txtrecibe.ScrollToEnd(); //setea scroll al final
12: }));
13: }
A continuación se procede a programar los botones que
realizaran las acciones de: Conectar, Desconectar y enviar datos hacia el
puerto Serial. Como lo primero que se realiza es la conexión empezara por el botón
conectar, el cual básicamente obtiene los valores del puerto y la frecuencia
que se desea utilizar.
1: private void btn_conectar_Click(object sender, RoutedEventArgs e)
2: {
3: String puerto = comboPuertos.Text;
4: int frecuencia = Convert.ToInt32(comboFrecuencia.Text);
5: conectar_puertoserial(puerto, frecuencia);
6: }
El botón desconectar, realiza la función de cerrar y liberar
cualquier puerto COM que se halla ocupado.
1: private void btn_desconectar_Click(object sender, RoutedEventArgs e)
2: {
3: if (_serialport.IsOpen)
4: {
5: _serialport.Close();
6: actualiza_consolaUI("Desconectado");
7: }
8: }
En cuanto al botón enviar, este trabaja en cooperación con
el TextBox txt_enviar, en el cual se envía todo lo que exista en dicha caja de
texto.
1: private void btn_enviar_Click(object sender, RoutedEventArgs e)
2: {
3: String dato_a_enviar = txt_enviar.Text;
4: _serialport.Write(dato_a_enviar);
5: String formato = string.Format("Enviado:{0}", dato_a_enviar);
6:
7: actualiza_consolaUI(formato);
8: }
Pero sin más les dejos la solución de la aplicación en este
LINK
APLICACIÓN DESARROLLADA CON VISUAL STUDIO 2013
Este sitio fue creado en primera instancia como un lugar
donde ir acumulando información y/o apuntes que considere de utilidad para un
futuro cercano, pero a medida que ha avanzado el tiempo este lugar se ha vuelto
un punto de encuentro para muchas personas que se están iniciando en el mundo
de la programación, es por eso que si estás leyendo esto estas invitado a
participar en de esta comunidad que día a día va creciendo.
Si estás dispuesto a cooperar te sugiero que dejes tus
inquietudes, dudas o aportes en la caja de comentario de cualquiera de las
entradas del blog o haciendo directamente desde el formulario de contacto que
puede encontrar en la página de inicio y responderé a la brevedad.
Comentarios
Publicar un comentario
Deja tus comentario