Benemérita Universidad Autónoma de Puebla Facultad de Ciencias de la Electrónica Práctica 3: Lecturas Analógicas Interfaces Alumnos: Miguel Pablo Saavedra Brian Daly López Rodríguez Leonardo Meza Galindo Ever Morales García Profesor: Antonio Michua Camarillo Primavera 2023 Objetivo Entender, desarrollar y crear lenguaje de programación C# con una respectiva interfaz en la plataforma Visual Studio, en donde se controlarán 3 LED por medio de botones virtuales y se realizará la lectura analógica de 3 potenciómetros a los canales analógicos de la tarjeta Arduino UNO. Se creará y desarrollará código para la misma en la plataforma Arduino IDE. Al final de esta práctica, los códigos permitirán la comunicación entre la tarjeta y la computadora. Marco Teórico Se espera que, mediante la creación del código básico vista en clase tanto de Visual Studio como de Arduino, desarrollemos nuestro propio código añadiendo un LED y un potenciómetro más que nos muestre valores analógicos convertidos a digitales siempre y cuando el código no pierda las características que permitan su funcionamiento. Materiales • Software o Visual Studio o Arduino IDE • Tarjeta Arduino UNO • Jumpers • 3 LEDs con 3 resistencias de 220 Ohm • Protoboard • Cable USB-A a USB-B • 3 Potenciómetros Desarrollo Para la realización de esta práctica se requiere la instalación de los siguientes programas de software en una computadora: a. Visual Studio Profesional (De preferencia la 2017) b. Arduino IDE En clase se creó una interfaz de la misma manera vista en las prácticas anteriores, por lo que omitiremos ciertos detalles que pueden ser redundantes a la hora de realizar esta práctica. Nos enfocaremos más en los cambios y modificaciones que se tienen que hacer en el código de Visual, y el código de Arduino. Hay 2 maneras de comenzar la práctica, la primera modificando el código de Visual y la segunda modificando el código de Arduino. Nosotros decidimos modificar primero el código de Arduino debido a que este contiene las instrucciones básicas que deberá realizar la tarjeta al momento de mandarle un dato. Abrimos Arduino IDE, nótese que el programa nos abrirá nuestro archivo anterior de la práctica del Semáforo Dual. Si este es el caso primero copiaremos todo el código de la práctica 2 ya que se reutilizará para agregar modificaciones, seguido debemos dar click en “Nuevo Sketch” Hicimos un nuevo proyecto debido a que queremos mantener los registros de nuestros trabajos de manera individual. En todo caso podemos escribir encima del mismo código, pero se recomienda hacerlo desde 0 para evitar un posible error humano. La primera modificación que se realizó en el código es agregar las variables analógicas con valor de “Unsigned Int 16” y con los nombres del respectivo canal, seguido se eliminaron las variables de los LEDs que no utilizaremos, de la misma manera se modificaron sus nombres para dar referencia a que led se está refiriendo. La modificación es la siguiente: Así mismo se eliminan las condiciones del semáforo que no sean necesarias manteniendo el control de esos 3 leds con comandos de encendido y apagado: Es ahora donde agregaremos el código que nos va a permitir la lectura analógica y el envío de datos de los pines A0, A1 y A2: *Se puede observar que el código cambió a tema claro, no se le debe tomar importancia ya que simplemente cambiamos el tema de Windows temporalmente debido a las condiciones de trabajo en donde nos encontrábamos. Lo que quiere decir este pequeño fragmento de código es que, si enviamos una “x” al Arduino, este habilitará la lectura analógica de los canales A0, A1 y A2 e imprimirá (enviará) los datos mediante el puerto serial en forma de cadena. Para el caso de la interfaz de Visual Studio, agregaremos 6 botones, 9 etiquetas, 9 TextBox y una herramienta nueva llamada “ProgressBar”: El paso que sigue es el más tedioso, ya que debemos configurar cada una de las herramientas con sus propiedades correctas. Simplificaremos en grupos este paso indicando las modificaciones correspondientes: 1 2 3 4 5 6 7 8 9 Texto de las etiquetas Puerto Serial Baudios Datos a Enviar Canal A0 Valor ADC (0-1024) Voltaje A0 Canal A1 Valor ADC (0-1024) Voltaje A1 Canal A2 Valor ADC (0-1024) Voltaje A2 1 2 3 4 5 6 7 8 9 Nombre de los TextBox COM Baudios textBox_EnvDatos textBox_CanalA0 textBox_VoltajeA0 textBox_CanalA1 textBox_VoltajeA1 textBox_CanalA2 textBox_VoltajeA2 1 2 3 4 5 6 - Nombre de los botones button_PUERTO_ON button_PUERTO_OFF button_EnvDatos button_Iniciar_Lectura button_Detener_Lectura SALIR Texto de los botones 1 Abrir Puerto 2 Cerrar Puerto 3 Enviar Datos 4 Iniciar Lectura 5 Detener Lectura 6 Salir - Nombre de las Progressbar 1 progressBar_A0 2 progressBar_A1 3 progressBar_A2 Texto de los TextBox 1 COM3 2 9600 - Una vez realizadas las modificaciones correspondientes, nuestra interfaz debería quedar de la siguiente manera: Ahora tenemos que realizar la configuración correspondiente al código. Agregamos desde nuestro cuadro de herramientas un Timer y nuestro SerialPort: Esto lo hacemos desde el inicio debido a que es muy susceptible olvidar agregar estas herramientas de suma importancia. Son tan básicas pues son las que permiten la comunicación entre la tarjeta y la computadora. Sabiendo que ya hemos realizado prácticas similares con anterioridad, podemos copiar y pegar los códigos de los botones Abrir Puerto, Cerrar Puerto, Salir, y de los TextBox COM y Baudios. Los cambios realizados se muestran a continuación: Para el botón PUERTO_ON: private void button_PUERTO_ON_Click(object sender, EventArgs e) { try { serialPort1.BaudRate = Convert.ToInt16(Baudios.Text); serialPort1.PortName = COM.Text; serialPort1.Open(); MessageBox.Show("El puerto se ha abierto correctamente :D"); button_PUERTO_ON.Enabled = false; button_PUERTO_OFF.Enabled = true; } catch { MessageBox.Show("El puerto no se ha encontrado o no está conectado correctamente D:"); } } Para el botón PUERTO_OFF: private void button_PUERTO_OFF_Click(object sender, EventArgs e) { serialPort1.Close(); button_PUERTO_OFF.Enabled = false; button_PUERTO_ON.Enabled = true; } Para el botón SALIR: private void SALIR_Click(object sender, EventArgs e) { Application.Exit(); } A partir de aquí es donde comenzamos a desarrollar código nuevo para los botones Iniciar Lectura, Detener Lectura y Enviar Datos, los primeros 2 se encargarán de controlar el Timer encendiéndolo o apagándolo respectivamente: Para el botón Iniciar Lectura: private void button_Iniciar_Lectura_Click(object sender, EventArgs e) { timer1.Enabled = true; button_Iniciar_Lectura.Enabled = false; button_Detener_Lectura.Enabled = true; } Para el botón Detener Lectura: private void button_Detener_Lectura_Click(object sender, EventArgs e) { timer1.Enabled = false; progressBar_A0.Value = 0; progressBar_A1.Value = 0; progressBar_A2.Value = 0; button_Detener_Lectura.Enabled = false; button_Iniciar_Lectura.Enabled = true; } Nótese que están también los valores progressBar de los canales A0, A1, y A2. Esto simplemente es para que las barras de carga se reinicien en 0 a la hora de Detener el proceso de lectura. Para el botón Enviar Datos: private void button_EnvDatos_Click(object sender, EventArgs e) { if (serialPort1.IsOpen) { serialPort1.Write(textBox_EnvDatos.Text); textBox_EnvDatos.Text = ""; } } Este apartado nos ayuda a enviar datos a nuestro Arduino escribiéndolo directamente en el cuadro de texto, es decir: escribimos “a” y al momento de presionar el botón de Enviar Datos, el programa leerá lo que haya escrito en el cuadro de texto y lo enviará a la tarjeta, seguido de eso, el programa borrará cualquier cosa que se haya escrito en el cuadro de texto. Este apartado tiene la finalidad de encender y apagar los 3 LEDs en el Arduino, si escribimos “a” el Led 1 prenderá, si escribimos “c”, el segundo lo hará y para “e” será el tercero, para apagar los leds se introducen los valores “b, d, f” utilizándolos respectivamente para cada uno de los LEDs Cabe señalar que en la parte del inicio del código se van a declarar variables que nos permitan identificar Datos de Entrada como lo son los índices, los sensores y voltajes, estos se declaran dentro del siguiente apartado: public partial class Form1 : Form { string DatosEntrada; sbyte indiceA, indiceB, indiceC; string sensor_A0, sensor_A1, sensor_A2; int valorADC; double voltaje; Antes de continuar, debemos agregar un nombre a los datos de entrada, estos serán manejados a través de un hilo, es por ello que en las propiedades del puerto serial en el apartado de eventos, debemos cambiar el nombre de Datos Recibidos por Hilo_Receptor_Serial: Luego de la parte tediosa del proyecto continuamos con la parte compleja de la práctica, y es que se nos enseñó en clase la utilización de “hilos” en este proyecto. La línea del hilo es la siguiente: private void Hilo_Receptor_Serial(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { DatosEntrada = serialPort1.ReadLine(); this.BeginInvoke(new EventHandler(Mifuncion)); } Esto nos permite leer los Datos que provienen de la tarjeta mediante el puerto Serial. Ahora se declara una variable que se llame “MiFunción”. El código es el siguiente: private void Mifuncion(object sender, EventArgs e) { try { MostrarDatos(); } catch(Exception error) { MessageBox.Show(error.Message); } Seguido declaramos la variable: MostrarDatos, esta nos va a permitir que el programa reconozca y reproduzca los datos en los cuadros de texto. En este apartado vamos a agregar las variables que declaramos desde el inicio (índice A, índice B e índice C). Esto significa que utilizaremos el hilo previamente creado: private void MostrarDatos() { indiceA = Convert.ToSByte(DatosEntrada.IndexOf("A")); indiceB = Convert.ToSByte(DatosEntrada.IndexOf("B")); indiceC = Convert.ToSByte(DatosEntrada.IndexOf("C")); No debemos olvidar que en esta función debemos utilizar la lectura de nuestra tarjeta Arduino, es por ello que se agrega el código del sensor A0, A1 y A2. sensor_A0 = DatosEntrada.Substring(0, indiceA); sensor_A1 = DatosEntrada.Substring(indiceA + 1, (indiceB - indiceA) - 1); sensor_A2 = DatosEntrada.Substring(indiceB + 1, (indiceC - indiceB) - 1); Nótese que los datos de entrada vienen en forma de cadena, esto podemos recordarlo con nuestro código de Arduino donde le indicamos que enviara los datos mediante el puerto serial en el apartado: Serial.print((String)canal_A0+"A"+canal_A1+"B"+canal_A2+"C"+"\n"); Regresando al código de Visual, ahora tenemos los datos que necesitamos en las variables correspondientes a los sensores. Para que estos datos se muestren en el programa requerimos indicarlos en los TextBox: textBox_CanalA0.Text = sensor_A0; textBox_CanalA1.Text = sensor_A1; textBox_CanalA2.Text = sensor_A2; Ahora el código para las barras de progreso: progressBar_A0.Value = Convert.ToInt16(sensor_A0); progressBar_A1.Value = Convert.ToInt16(sensor_A1); progressBar_A2.Value = Convert.ToInt16(sensor_A2); La tarjeta Arduino trabaja con un voltaje de 0v a 5v y lee datos de las salidas analógicas que van del 0 al 1023 en forma digital, para convertir estos datos a voltaje requerimos de una operación matemática que también existe en C#: valorADC = Convert.ToInt16(sensor_A0); voltaje = Math.Round((valorADC / 1023.0) * 5.0,2); textBox_VoltajeA0.Text = voltaje.ToString(); Este fragmento de código lo podemos reutilizar para los otros dos sensores restantes, haciendo las modificaciones correspondientes: valorADC = Convert.ToInt16(sensor_A1); voltaje = Math.Round((valorADC / 1023.0) * 5.0, 2); textBox_VoltajeA1.Text = voltaje.ToString(); valorADC = Convert.ToInt16(sensor_A2); voltaje = Math.Round((valorADC / 1023.0) * 5.0, 2); textBox_VoltajeA2.Text = voltaje.ToString(); Como dato adicional, podemos modificar el intervalo de actualización de la comunicación entre la tarjeta y la computadora modificando la propiedad “Intervalo” del Timer: Si todo el código esta escrito de manera correcta, debería ejecutarse sin problemas. Resultados Esta práctica nos sorprendió debido al potencial que nos ofrece la tarjeta Arduino. Los canales analógicos nos permitieron visualizar en la computadora de cantidad de potencia de los potenciómetros, todo esto mediante la comunicación entre la computadora y la tarjeta Arduino. La implementación de los Leds fue la esperada, pues le da un toque de presentación a la práctica. A continuación, se mostrarán fotos del funcionamiento de esta práctica, sin embargo el video completo se puede encontrar en YouTube con el siguiente enlace: https://youtu.be/PW7oZcckrXI La “Evidencia” Gran parte de la práctica la realizamos mediante conexión a internet: