TAREA 1 IMPLEMENTACIÓN DE UN VOLTÍMETRO DC (RANGO: 0-33 VCC APROX)

Dependencies:   mbed I2CLCD TextLCD

Implementación de un Voltímetro Digital para voltajes DC (Rango : 0-33Vcc Aprox) utilizando STM32 y Pantalla LCD

Se trata de disponer de una pantalla de bajo costo que nos muestre la tensión que está entregando la fuente de alimentación:

Vamos a necesitar los siguientes componentes:

R1=1Mohms - R2=100kOhms 1 Microcontrolador STM32F407 Una pantalla LCD de 20 Espacios X 4 Filas con controlador

Los voltímetros digitales operan mediante la conversión del valor analógico leído, a un valor digital mediante un convertidor analógico a digital (ADC). Nosotros vamos a utilizar un micro STM32 que tiene varios de estos convertidores en él, con una precisión que será suficientemente precisa para este cometido, en este tutorial veremos cómo leer voltajes de entradas analógicas en el micro y construir un voltímetro que mide voltajes DC.

El esquema es muy sencillo, ya que se reduce a un divisor de tensión básico el cual constituirá en si mismo la impedancia de entrada (R1) y cuya salida es la tensión que aplicaremos a un pin analógico (PB_0 escogido en nuestro caso) . En la figura siguiente se muestra el divisor de tensión a implementar con sus respectivas conexiones para una pantalla sin controlador . https://os.mbed.com/media/uploads/ramirezcar/esquema_2.png

para una pantalla con controlador las conexiones son como siguen: https://os.mbed.com/media/uploads/ramirezcar/conexiones_con_controlador_2.png

Las entradas analógicas del STM32 pueden medir hasta 3,3.V (cuando se utiliza la tensión de referencia analógica incorporada). Incluso cuando sólo se conecta a un circuito de 3,3V, debe utilizar las resistencias para ayudar a proteger el micro de cortocircuitos o sobrecargas de tensión inesperadas (ojo en el program se usa 3,0V, ya que este es el valor real medido "real").

Se trata de un circuito divisor de tensión que consta de dos resistencias (R1 y R2) en serie que, se encargan de dividir el voltaje de entrada, para adaptarlo a la ventana de tensiones que pueden leer las entradas analógicas del Arduino (3,3V nominal; 3,0 en nuestro caso). El divisor entrega una tensión al pin analógico ( PB_0); éste convierte en un formato digital que puede ser procesada por el microcontrolador. En este caso, la tensión entrada (vin) después de pasar por el divisor de tensión descrito, El voltaje vout es el que se aplica al pin PB_0 (usted puede utilizar otro pin).

El circuito con los valores mostrados para R1 de 1MΩ en serie con R2 de 100KΩ representa una impedancia de entrada de 1MΩ + 100kΩ = 1, 1M; que reduce en un factor de 11 que es adecuado para la medición de voltajes de DC hasta aproximadamente 36V si el voltaje de referencia es 3,3 (en nuestro caso es 33 ).

Principios de funcionamiento. Impedancia de entrada.- Si un voltímetro tiene una baja impedancia de entrada baja, digamos 10kΩ y se está midiendo un voltaje a extremos de una resistencia de 10kΩ, el multímetro está cambiando efectivamente el valor de la resistencia a 5KΩ ( ya que dos resistencias de 10kΩ en paralelo = resistencia 5kΩ). Por consiguiente, el voltímetro ha cambiado los parámetros del circuito, y realmente, está leyendo una tensión errónea. Esas dos resistencias forman un divisor de potencial que se utiliza para bajar el voltaje que se mide a un nivel que el microcontrolador lo pueda leer, además de ser la impedancia de entrada.

Un multímetro digital para medir voltaje DC típicamente tendrá una impedancia de entrada de 10MΩ o superior. Esto significa que la resistencia entre las dos sondas o terminales del multímetro es de 10MΩ o más. Así pues, es deseable una alta impedancia de entrada para un voltímetro (o multímetro en la escala de voltaje). Cuanto mayor impedancia de entrada, menos probable es que el multímetro influya o cambie lo que está midiendo del circuito.

Por lo anterior necesitamos una alta impedancia de entrada en nuestro circuito divisor de tensión, para que la impedancia de este «voltímetro» no vaya a influir en el circuito que se esté bajo prueba. Sin embargo, como regla general, un dispositivo de alta impedancia de entrada será generalmente propenso a recoger más ruido o interferencias (EMI) que un dispositivo de baja impedancia de entrada, por ese motivo se recomienda adaptar un filtro de paso alto.

La fórmula para calcular los valores en un divisor de tensión es: Vout = (R2 / (R1 + R2)) * Vin

Por lo tanto, puesto que la tarjeta STM32 admite un Vmax de 3.3V en sus entradas analógicas (3,0 en nuestro caso), si el divisor está funcionando correctamente, entonces el Vout será de un máximo de 36,3 V (33,0 V).

Nota:

- Para una mayor precisión las resistencias deben ser del 1% de precisión si es posible o mejor. - En la línea 18 como comentarrio del programa se incializa una pantalla sin controlador con su respectiva librería

Prueba 1 La Implementación del sistema y la visualización de la medición de valores solo en PC (se usa una batería nueva de 9Vcc) para su comprobación se contrasta con multímetro https://os.mbed.com/media/uploads/ramirezcar/implementacion.png https://os.mbed.com/media/uploads/ramirezcar/medicion_sin_vin.png https://os.mbed.com/media/uploads/ramirezcar/medicion_bateria.png https://os.mbed.com/media/uploads/ramirezcar/voltaje_vout_en_ain.png https://os.mbed.com/media/uploads/ramirezcar/voltaje_multimetro.png https://os.mbed.com/media/uploads/ramirezcar/vin_con_stm32.png

Prueba 2 Se implementan las siguientes mejoras: Lectura vía LCD. Mensajes de Inicialización de pantalla (secuencia de Inicialización líneas 42 a 55 del programa). Encerado de pantalla esto debido a pequeñas perturbaciones que se dan cuando no hay nada conectado, línea 77 del programa).

https://os.mbed.com/media/uploads/ramirezcar/mensaje_de_inicicilizacion.jpg https://os.mbed.com/media/uploads/ramirezcar/lcd_encerada.jpg https://os.mbed.com/media/uploads/ramirezcar/valor_medido_mostrado_en_pc_y_pantalla_lcd.jpg

Committer:
ramirezcar
Date:
Sat Feb 15 06:11:46 2020 +0000
Revision:
6:7fc832967ad6
Parent:
5:32b535d709ed
Nuevos comentarios para explicar la configuracion de LCD sin controlador linea 18

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ramirezcar 0:30ca677ffd0d 1 // Voltimetro DC con STM32
ramirezcar 0:30ca677ffd0d 2 //Carlos Ramírez Quiroga
ramirezcar 0:30ca677ffd0d 3 //3.02.2020
ramirezcar 2:eba513d94574 4 //Utiliza divisor de voltaje para obtener valores a ser medidos
ramirezcar 0:30ca677ffd0d 5 #include "mbed.h"
ramirezcar 1:9c84e7a34b10 6 #include "TextLCD.h" // Incluye la libreria para LCD
ramirezcar 2:eba513d94574 7 #define DEFAULT 0//no
ramirezcar 2:eba513d94574 8 #define ADAFRUIT 0//no
ramirezcar 2:eba513d94574 9 #define DFROBOT 0
ramirezcar 2:eba513d94574 10 #define LCM1602 0
ramirezcar 2:eba513d94574 11 #define YWROBOT 0
ramirezcar 2:eba513d94574 12 #define GYLCD 0//no
ramirezcar 2:eba513d94574 13 #define MJKDZ 0//no
ramirezcar 2:eba513d94574 14 #define SYDZ 1
ramirezcar 2:eba513d94574 15 #define WIDEHK 0//no
ramirezcar 2:eba513d94574 16 #define LCDPLUG 0//no
ramirezcar 2:eba513d94574 17
ramirezcar 6:7fc832967ad6 18 //TextLCD lcd(PC_8, PC_9, PD_3, PD_6, PD_11, PD_12, TextLCD::LCD 16x2); //Inicilizar la pantalla LCD sin controlador(se considera una pantalla de 16 caracteres X 2 Filas
ramirezcar 1:9c84e7a34b10 19 AnalogIn ain(PB_0);// Inicializar pin PB_0 como entrada análoga
ramirezcar 1:9c84e7a34b10 20 Serial device(PA_2,PA_3,115200);
ramirezcar 5:32b535d709ed 21 I2C i2c_lcd(PB_9, PB_8); // SDA, SCL (Configuración de LCD con controlador)
ramirezcar 2:eba513d94574 22 TextLCD_I2C lcd(&i2c_lcd, 0x4E, TextLCD::LCD20x4);
ramirezcar 0:30ca677ffd0d 23
ramirezcar 1:9c84e7a34b10 24 double vin=0.0;//voltaje de entrada a ser medido
ramirezcar 1:9c84e7a34b10 25 double vout=0.0; //voltaje en entrada análoga
ramirezcar 0:30ca677ffd0d 26 float R1=1000000;// 1 Mohms
ramirezcar 0:30ca677ffd0d 27 float R2=100000;//100 Kohms
ramirezcar 1:9c84e7a34b10 28 float value=0;
ramirezcar 0:30ca677ffd0d 29
ramirezcar 4:a4a4dd8d1f04 30 void setup()
ramirezcar 4:a4a4dd8d1f04 31 {
ramirezcar 2:eba513d94574 32 lcd.setBacklight(TextLCD::LightOn); // Retroiluminación de pantalla
ramirezcar 2:eba513d94574 33 lcd.setCursor(TextLCD::CurOff_BlkOn);//Seteo cursor
ramirezcar 2:eba513d94574 34 lcd.setUDC(0, (char *) udc_0);
ramirezcar 2:eba513d94574 35 lcd.putc(0);
ramirezcar 2:eba513d94574 36 lcd.setUDC(1, (char *) udc_1);
ramirezcar 2:eba513d94574 37 lcd.putc(1);
ramirezcar 2:eba513d94574 38 lcd.cls();//limpia pantalla
ramirezcar 2:eba513d94574 39 int col = 0;//definición columna
ramirezcar 2:eba513d94574 40 int row = 0;//definición fila
ramirezcar 2:eba513d94574 41 lcd.locate(col,row);//Ubiación del cursor
ramirezcar 2:eba513d94574 42 lcd.printf("Inicializando...");// mensaje de Inicialización de pantalla
ramirezcar 2:eba513d94574 43 wait(2);//Espere 2 segundos
ramirezcar 4:a4a4dd8d1f04 44 //Secuencia de Incilización
ramirezcar 2:eba513d94574 45 row++;
ramirezcar 2:eba513d94574 46 lcd.locate(col,row);
ramirezcar 2:eba513d94574 47 lcd.printf("Inicializando...");
ramirezcar 2:eba513d94574 48 wait(2);
ramirezcar 2:eba513d94574 49 row++;
ramirezcar 2:eba513d94574 50 lcd.locate(col,row);
ramirezcar 2:eba513d94574 51 lcd.printf("Inicializando...");
ramirezcar 2:eba513d94574 52 wait(2);
ramirezcar 2:eba513d94574 53 row++;
ramirezcar 2:eba513d94574 54 lcd.locate(col,row);
ramirezcar 2:eba513d94574 55 lcd.printf("Inicializando...");
ramirezcar 2:eba513d94574 56 }
ramirezcar 4:a4a4dd8d1f04 57 void mostrar(double vin)
ramirezcar 4:a4a4dd8d1f04 58 {
ramirezcar 2:eba513d94574 59 lcd.setBacklight(TextLCD::LightOn);
ramirezcar 2:eba513d94574 60 lcd.cls();
ramirezcar 2:eba513d94574 61 lcd.locate(0, 0);
ramirezcar 2:eba513d94574 62 lcd.printf("Voltaje de Entrada:");
ramirezcar 2:eba513d94574 63 lcd.locate(0, 1);
ramirezcar 2:eba513d94574 64 lcd.printf("%2.2f", vin);
ramirezcar 2:eba513d94574 65 }
ramirezcar 4:a4a4dd8d1f04 66 int main()
ramirezcar 4:a4a4dd8d1f04 67 {
ramirezcar 2:eba513d94574 68 setup();
ramirezcar 1:9c84e7a34b10 69 while (1) {
ramirezcar 1:9c84e7a34b10 70 value=ain; //Lectura de entrada analoga escogida para divisor de voltaje
ramirezcar 2:eba513d94574 71 device.printf ("ain V=%2.2f\r\n",value);//Lectura entrada análoga puerto serial
ramirezcar 2:eba513d94574 72 vout=(value*3.0);//formula para convertir el valor de ADC a voltios
ramirezcar 3:f045443dff50 73 device.printf ("vout V=%2.2f\r\n",vout);//Lectura entrada análoga puerto serial
ramirezcar 1:9c84e7a34b10 74 vin=vout/(R2/(R1+R2));//formula del voltaje de entrada a ser leído
ramirezcar 3:f045443dff50 75 device.printf ("vin V=%2.2f\r\n",vin);//Lectura entrada análoga puerto serial
ramirezcar 4:a4a4dd8d1f04 76 if(ain<0.09) {
ramirezcar 4:a4a4dd8d1f04 77 vin=0.0;//si el voltaje leído en ain es menor a 0.09 Vcc setee en 0 el valor de Vin; esto representa 0,1V de Vin solo se presentará valores mayores a este
ramirezcar 4:a4a4dd8d1f04 78 device.printf ("vin\r\n");
ramirezcar 1:9c84e7a34b10 79 }
ramirezcar 2:eba513d94574 80 mostrar(vin);
ramirezcar 1:9c84e7a34b10 81 wait(0.5);//espere 0,5 segundos
ramirezcar 0:30ca677ffd0d 82 }
ramirezcar 0:30ca677ffd0d 83 }
ramirezcar 0:30ca677ffd0d 84