Voltímetro con el ADC del PIC

Estado
Cerrado para nuevas respuestas.
Yo lo pondría *antes* de la medición.

De esa manera presento inmediatamente el resultado de la conversión (aunque... también es cierto que 50 µs es muy poco tiempo de espera para el usuario).
 
anda muy bien con los led de 7seg ahora consulta como puedo hacer para que la medición sea mas lenta y no se mueva tanto el ultimo digito.
 
Pero... ¿esto qué es?
PHP:
valor_adc=0; 
for(var1=0;var1<500;var1++) 
{ 
    valor_adc=valor_adc+ read_adc(); 
    delay_us(62);   
}
Esto solo sirve para perder el tiempo. El valor almacenado en valor_adc no se usa en el resto del bucle. El único efecto que veo es que hay una espera de 500 * 62 µs = 31 ms. Si a esa espera le sumamos el resto de retrasos, nos sale que los display se repintan unas 30~31 veces por segundo, así que es normal ver que parpadean.

Otra cosa... yo haría la extracción de los dígitos de otra manera:

PHP:
	// Obtener el valor para cada dígito a partir de la tabla para 7 segmentos.
	centenas = voltaje / 100;
	voltaje  = voltaje % 100;
	decenas  = voltaje / 10;
	voltaje  = voltaje % 10;
	unidades = voltaje;

	unidades = tabla_7segs[unidades];
	decenas  = tabla_7segs[decenas ];
	centenas = tabla_7segs[centenas];

	// Multiplexar los displays. 
	output_b(1);            // Activar display 1 y desactivar display 2 y 3 
	output_c(unidades);     // Mostrar unidades. 
	delay_ms(2);            // Retardo para mostrar las unidades. 
	output_b(2);            // Activar display 2 y desactivar Display 1 y 3 
	output_c(decenas);      // Mostrar decenas. 
	delay_ms(2);            // Retardo para mostrar las decenas. 
	output_b(4);            // Activar display 3 y desactivar Display 1 y 2 
	output_c(centenas);     // Mostrar las centenas. 
	delay_ms(2);            // Retardo para mostrar las centenas.
 
Logré separar el número para mostrar el valor en 4 displays de 7 segmentos de una forma sencilla.
PHP:
void entero_a_bcd(int16 valor, int8 digitos_menos_1)
{
int8 i;
   // Limpiar variables del arreglo "display[]".
   for(i=0;i<=digitos_menos_1;i++)
   {
      display[i] = 0;
   }

   i = digitos_menos_1;
   // Separar los números.
   while (valor > 0)
   {
      display[i--] = (valor % 10);
      valor /= 10;
   }
}
Se utiliza un arreglo global para almacenar el valor separado de cada dígito y el formato mostrado es con 2 decimales.

El programa funciona perfectamente durante simulación, pero no lo probé físicamente.
También lo realicé usando una referencia externa de 2.5V con un TL431, modificando el divisor de entrada y la fórmula.
El resultado también fue satisfactorio y al parecer mejor que usando la referencia interna.

Adjunto el proyecto como un aporte, agradeciendo a Cosme y a Joaquín por la colaboración al tema.

Notas:

  • En el programa adjunto se está usando la referencia interna del CAD por simplicidad y es una base que puede servir para realizar programas de este tipo.

  • El programa puede medir hasta 99V y se ha dejado en los 40V que se han venido tratando en este tema.
  • Es muy sencillo cambiar el rango. Solo se debe especificar el voltaje (<99.00) y modificar el divisor.

  • El programa está comentado y basado en un PIC16F887, pero se pueden usar otros, p.e, un PIC16F88.
 

Adjuntos

Es bastante lio, porque tenía un par de display de ánodo común y quería ver como usarlos.
No es ningún problema. El programa tiene una tabla con los valores del 0 al 9 para displays de cátodo común.
O sea, esta: {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
El primer número en hexadecimal: 3F es el 0, el 06 es el 1, el 5B es el 2, etc.
Necesitas cambiarlos por los que serían para ánodo común:
El 0 sería: 0xC0, el 1 sería: 0x9F, el 2 sería: 0xA4, etc.

Y también se necesita invertir la activación de los displays.
Si para cátodo común, el bit 0 corresponde al display 4 (LSB) activado por 1 lógico que después de usar un transistor NPN se obtendrá un 0 por colector para el cátodo.
Entonces invirtiendo este bit, tendríamos que el puerto B tendría la siguiente secuencia (LSB a MSB):
Display unidades = 0b11111110 "0xFE"
Display decenas = 0b11111101 "0xFD"
Display centenas = 0b11111011 "0xFB"
Etcétera.

Y lo haces con output_b(valor); Por ejemplo: output_b(0xFE);
Así se obtendrá un 0 como bit de activación para un transistor PNP por display de ánodo común.
Éste deberá dar un 1 por colector, ya que el emisor deberá estar hacia VCC.
Y también se debe invertir la activación y desactivación del punto.

Lo ves. No es ningún lio. :cool:
 
Última edición:
Ok. Empiezo a ver que puedo hacer y pido ayuda. Gracias.


¿Dónde encuentro la tabla hex con los valores para ánodo común?

Encuentro para cátodo común por todos lados.
 
Última edición por un moderador:
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x98 anodo común seria asi

0b11000000, 0b11111001, 0b10100100, 0b10110000, 0b10011001, 0b10010010, 0b10000010, 0b11111000, 0b10000000, 0b10011000
 
Los bits para el número nueve están mal. Es: "10010000" = 0x90
Se vería mejor de esa forma:

Mira por aquí: PIC To 7 Segments

Con ese programa puedes generar fácilmente los bits para la tabla de displays de 7 segmentos.
 
Última edición:
Buen día, amigo D@rkbytes.
Hace tiempo monté este circuito del amigo Jorge Ansuini, doy crédito porque no es de mi autoría el circuito y funciona muy bien.
Ahora me gustaría saber si se puede hacer que este voltímetro mida el voltaje de su propia fuente para medir el voltaje de la batería de mi carro sin alimentar el pic con otra funte.
Te agradezco la luz que me puedas brindar.
 

Adjuntos

Última edición por un moderador:
Tendrías que poner un divisor de tensión y modificar algo el programa.
El divisor debe entregar 5 voltios cuando se tenga el máximo voltaje de entrada.

En ese programa se usa una suma para obtener un valor final y luego se separa para obtener cada dígito.
Ahí es donde tendrías que usar otro método para leer por ejemplo, 20 voltios máximo.

¿Por qué no usas el proyecto del post #127 y lo adaptas?
Es más sencillo que modificar el programa que adjuntas y aparte muestra los decimales separados por punto.
 
Tendrías que poner un divisor de tensión y modificar algo el programa.
El divisor debe entregar 5 voltios cuando se tenga el máximo voltaje de entrada.

En ese programa se usa una suma para obtener un valor final y luego se separa para obtener cada dígito.
Ahí es donde tendrías que usar otro método para leer por ejemplo, 20 voltios máximo.

¿Por qué no usas el proyecto del post #127 y lo adaptas?
Es más sencillo que modificar el programa que adjuntas y aparte muestra los decimales separados por punto.
muchas gracias por tu respuesta:apreton:
 
Estado
Cerrado para nuevas respuestas.

Temas similares

Arriba