Usé primero el método de los PNP y el 0 lógico para activar los ánodos y funcionaba mal, al menos en el protoboard.
Así que preferí usar NPN y colector común. Está funcionando así en el pcb y 0 problemas.
Debe funcionar con los transistores PNP. Algo debiste tener mal en el programa o en el diseño.
Ahora bien, en el código pones lectura = (31.0 * read_adc() / 256);
Así cuando hayan 5V en el ADC el valor de read_adc será 255. ¿No debería ese 256 ser 255?
Pues resulta que no y por acá
sobre el mismo tema que mencioné anteriormente se explica el por qué.
Y es precisamente por lo que te aclaró pandacba.
Otra cosa. La diferencia entre el algoritmo que me expones y el mío es que tú le dices al micro que cuando hayan 31V en la entrada, entonces en el RA1 habrán 5V, lo cual lo aseguras con el zenner de 5V1 y calibrándolo mediante un preset, sin duda es una buena idea (Y).
Así es, pero ese divisor de tensión está calculado para que cuando existan 30V en la entrada, en la salida se obtengan 5V, aún sin estar el diodo Zener.
R1 = 56KΩ y R2 debería ser de 11.2KΩ, pero como no existe un valor comercial de 11.2KΩ y para obtener un ajuste del voltaje de entrada, se usó un potenciómetro de 22KΩ en serie con una resistencia de 1KΩ
Entonces el valor medio del potenciometro deberá estar cerca de los 10KΩ para estar próximo a los 11.2KΩ que se requieren.
El diodo Zener es por protección de la entrada del PIC ante un voltaje superior a los 30V en la entrada del divisor de tensión.
Si eso ocurre, el voltaje en la salida del divisor sobrepasará los 5.5V que soporta el PIC como máximo y se dañaría el PIC.
Entonces el diodo Zener se encargará de reducir ese voltaje excedente en 5.1V.
En cambio, yo hago que el microcontrolador calcule el valor a mostrar en términos de R1 y R2, cuyos valores se los paso por software, partiendo sólo de la fórmula de un divisor de tensión y que cuando hay 5V en RA1 read_adc vale 255.
¿Podrías darme alguna sugerencia sobre por que no funciona así como está?
Deberías analizar el resultado que obtendrías con la fórmula que estás usando.
Aparte, ten en cuenta que el PIC está leyendo un voltaje, no una resistencia.
Como no estás usando una referencia de tensión externa, el PIC usará una interna por la configuración que se tiene en
setup_adc(párametros); y ésta será el voltaje de alimentación.
Entonces esa referencia interna será el voltaje con el que estás alimentando al PIC.
Por lo tanto el voltaje de referencia estará en 5V +- o sea, el voltaje que entregue tu fuente de poder.
Así, cuando en la entrada existan 5.0V, el ADC estará en 255 por ser de 8 bits.
Si realizamos un cálculo sobre el valor obtenido mediante la fórmula que empleaste, se obtiene lo siguiente:
r1 = 100
r2 = 10
lectura = 255, que viene siendo cuando ADCIn = 5V.
vi = 1.9607 * ((r1 + r2) / r2) * lectura
vi = 5499.7635
Como "
vi" es una variable de 16 bits, entonces no se toman en cuenta los decimales y el valor queda en 5499
Y ese valor una vez separado será lo que se mostrará en los displays.
Si se coloca el punto en el primer dígito, serán 5.499V.
Y si se coloca en el segundo dígito, serán 54.99V.
Entonces ese valor está muy fuera de los 30V que pretendes leer. ¿No?
Como aporte y parte del tema, adjunto el programa que subí anteriormente, pero ahora para displays de ánodo común.