# [Aporte] Capacímetro Autorango con PIC16F628A



## D@rkbytes (Nov 18, 2013)

En esta ocasión les traigo un capacímetro autorango con una respuesta desde 3pF hasta 2600uF.
El circuito funciona en base a un microcontrolador PIC16F628A, unos pocos componentes y un LCD 16x2
Para su funcionamiento únicamente se necesita realizar un ajuste sobre un potenciómetro multivueltas.

*Armado y puesta en marcha del circuito:*
El circuito debe ser montado preferentemente sobre una placa de fibra de vidrio, aunque funciona muy bien sobre placas fenólicas, e incluso sobre tarjetas perforadas y protoboards.

Después de colocar y soldar perfectamente todos los componentes, se debe colocar el potenciómetro a la mitad de su recorrido y se verifica que las terminales de prueba no estén en corto circuito.

Al encender el aparato por primera vez, deberá mostrar una capacidad muy lejana a 0.00 pF.
Entonces se debe presionar el botón AUTOCAL para que el microcontrolador comience a realizar una autocalibración del sistema dejándolo en 0.00pF y almacenar el valor de calibración en la memoria interna del microcontrolador.

Una vez realizado este procedimiento se necesitará tener algún capacitor de valor conocido, ó mejor aún, un capacitor con baja tolerancia (1%) de los llamados capacitores patrón.

Se coloca este capacitor sobre los terminales de prueba y se reajusta nuevamente el potenciómetro hasta conseguir una lectura lo más aproximada al valor del capacitor de valor conocido.

Si al retirar el capacitor se muestra en la pantalla una capacidad parásita del algunos pocos pico faradios, se presiona nuevamente el botón AUTOCAL para reajustar la desviación.

Con éstos pasos ya debemos tener calibrado nuestro capacímetro y listo para medir capacitores de valor desconocido ó alterados.


Podrán notar que la precisión del circuito es muy elevada y será una herramienta muy útil en su taller.

Adjunto 4 diagramas y su correspondiente programa ejecutable *.hex, que corresponden a dos tipos de oscilador y a dos tipos de pantallas LCD 16x2, para que armen el circuito que más le convenga.

*Notas:*
Los archivos LCD Estándar son para pantallas genéricas 16x2 del tipo de controlador HD44780.
Y los archivos LMG-162-STN son para este tipo de pantalla China que es muy económica.
La precisión de las lecturas del circuito con oscilador interno es también muy elevada.
Los LED's de muestreo sirven para mostrar actividad del circuito en capacidades altas y bajas.
No se adjuntan los programas ni tampoco los circuitos impresos, quedando en sus manos su diseño.

Espero que este aporte sea de su completo agrado y utilidad.

Saludos y suerte. ​


----------



## D@rkbytes (Ene 23, 2014)

Me han preguntado sobre si este proyecto se puede simular.
La respuesta es; no se pueden simular los programas, ya que el simulador agrega una desviación de 0.5 pF
y al no poder encontrarse el valor de 0.00 pF para la calibración durante la simulación, el programa entrará en un bucle al no poder ajustarse a ese valor.

Para lograr que el programa funcione bajo simulación se tuvo que hacer un cambio al programa.

Si desean ver el funcionamiento del capacímetro autorango en simulación,
aquí adjunto el diseño simulable en ISIS de PROTEUS con el cambio requerido para tal efecto.

Suerte.


----------



## silicon blood (Ene 28, 2014)

Hola D@rkbytes Esta muy bueno el proyecto. Muchas gracias por compartir. Una pregunta, acaso el principio de funcionamiento es mediante un TAC (time to amplitude converter) conformado por los dos transistores?


----------



## D@rkbytes (Ene 29, 2014)

elpanaqute dijo:


> Hola D@rkbytes Esta muy bueno el proyecto. Muchas gracias por compartir. Una pregunta, acaso el principio de funcionamiento es mediante un TAC (time to amplitude converter) conformado por los dos transistores?


Funciona simplemente cargando y descargando el capacitor y tomando el tiempo con el Timer1 del PIC.
Luego se hace una comparación sobre desbordamiento y cálculos sencillos para obtener el valor.


----------



## silicon blood (Ene 29, 2014)

Ah ya entiendo. Es mas simple de lo que pensé . Solo me confundió que la salida de voltaje del capacitor esta a un pin que puede ser entrada analógica y al parecer cuando trabajas con x, todo tiene x.


----------



## luis2000 (Abr 1, 2014)

*H*ola D@rkbytes me puedes de*C*ir el comando *PARA* el pic en basic o en c para la comparacion del del tiempo de car*a*ga del  capacitor


----------



## D@rkbytes (Abr 1, 2014)

luis2000 dijo:


> *H*ola D@rkbytes me puedes de*C*ir el comando *PARA* el pic en basic o en c para la comparacion del del tiempo de car*a*ga del  capacitor


No es un comando, es un set de instrucciones las que se realizan.

El programa hace lo siguiente.

Se configura el registro CMCON para trabajar con un comparador independiente (CM<2:0> = 101)

Inicia Bucle.
Se descarga el capacitor.
Se configura el TMR1 con el prescaler  1:1
Se carga el capacitor.
Se verifica si existe un cambio en comparador (CMCON.7 = C2OUT)
Si no hay cambio se toma el tiempo del TMR1, se realiza un cálculo y se muestra el valor.
Si existe cambio, se  configura el TMR1 con el prescaler 1:8 (Cambio de rango)
Se toma una nueva lectura y si no existe desborde se realiza otro cálculo y se muestra el valor.
Si existe desborde del TMR1 se notifica como fuera de rango.
Reanudar el bucle.

Esto es resumidamente lo que hace el programa, en realidad es más complejo.
Como mencioné anteriormente, el código está escrito en Basic de Proton IDE, en C no lo tengo y por ahora no tengo pensado subirlo.

Saludos.


----------



## luis2000 (Abr 2, 2014)

Gracias, me ayudaste bastante


----------



## D@rkbytes (Abr 25, 2014)

D@rkbytes dijo:


> Tal vez algún día me anime a subirlo.



Para aquellos que les interese saber cómo es que funciona este sencillo capacímetro, aquí está el código fuente.

Está escrito en PICBasic con Proton IDE.

Espero sea de utilidad.

Saludos.


----------



## trifoncar (Abr 25, 2014)

¡Muchas gracias por compartirlo!

Un saludo


----------



## josue010101 (May 1, 2014)

Hola  amigo soy nuevo en esto de los microcontroladores ,programando en c con  pic c compiler .
Podrias facilitarme el archivo punto c para así entender mejor el programa xfa 
De antemano te agradesco la atención gracias


----------



## D@rkbytes (May 1, 2014)

Cómo he mencionado en los post anteriores, el código está escrito en PICBasic con Proton IDE.
*NO* está escrito en C.

El código en basic se encuentra en el post #11

Saludos.


----------



## luisdlahuerta (Jun 1, 2014)

Hola chicos,
Muchisimas gracias por compartir este medidor, es una pasada.
Me encanta , yo que estoy empezando con los pics y todo este mundillo, agradezco mucho esta información y como no, esa magnífica simulación para proteus.
Que maravilla
De los componentes necesarios para realizar el proyecto sólo me falta encontrar los transistores, tengo 548 y 557 pero no los que vienen el diagrama... habrá que pasarse por la tienda de eletrónica 
Saludos


----------



## D@rkbytes (Jun 1, 2014)

luisdlahuerta dijo:


> De los componentes necesarios para realizar el proyecto sólo me falta encontrar los transistores, tengo 548 y 557 pero no los que vienen el diagrama.


También puedes usar el BC557 o cualquier otro transistor PNP de uso general y pequeña señal.
Puse como referencia esos transistores por ser de fácil adquisición, pero no son críticos.

Suerte.


----------



## D@rkbytes (Jun 8, 2014)

Como a muchas personas les gusta programar en C, me decidí por trasladar el programa a este lenguaje.
Cuando decidí escribir el programa una de las mejores opciones de entorno que pensé usar fue Proton.
Motivos:
Uso directo de los registros sin hacer referencias.
Manejo de variables del tipo Float y Double Word (32 Bits) en PIC16
Posibilidad de controlar la pantalla sin usar el pin RW (Ahorro de un pin)
Funciones nativas como el uso de Button y otras más que en permiten mejoras en el código.
Y algo muy notorio e importante; buena optimización de código , algo que en C es difícil conseguir. 

Al usar C el resultado final fue el mismo, pero con la desventaja de que me quedé sin memoria ROM.
El programa final ocupó el 98.8% de memoria ROM y el 19.2% de memoria RAM.
Tamaño total del archivo hex: 11.1Kb.

En Proton el programa final ocupó el 71.78% de memoria ROM y el 26.34% de memoria RAM.
Un poco más de memoria RAM, pero sin memoria ROM ya no hay programa. 
Tamaño total del archivo hex: 8.10Kb.

Resultados de compilación en C. (PICC PCWHD Compiler)


Resultados de compilación en PICBasic (Proton)



Este mismo programa en ensamblador, (MPLAB v8.92 con MPASM v5.51) ofrece estos resultados.

Tamaño total del archivo hex: 2.81Kb.

Como podrán ver, la diferencia es notoria entre un lenguaje y otro.
Mientras más alto nivel se maneje, más consumo de recursos tendrá.
​ Adjunto el programa en PICC de CCS compilado con PCWHD Compiler v5.021 y el nuevo archivo de simulación.

Saludos.​


----------



## ManBarCob (Jun 8, 2014)

No puedo descargarme los ficheros rar, me los descarga como php.
¿Cómo los puedo descargar?


----------



## J2C (Jun 8, 2014)

ManBarCob

 Pues cambiales el nombre usando "*Guardar como ...*", así elijes donde guardarlos y que nombre ponerles.


 Saludos, JuanKa.-


----------



## Miembro eliminado 356005 (Jun 8, 2014)

Esta es otra versión del código escrito en C, dirigida a reducir el tamaño del código final.

```
/******************************************************************************
 * ; Programa: CapMeter JHD 162A.c
 * ; Versión: 1.0
 * ; Autor: D@rkbytes
 * ; Compañia: Digitek
 * ; Fecha: 01/06/2014
 * ; Hora: 20:56:36 p.m.
 * ; Notas: Capacímetro Autorango 3pF a 2600uF. Con autocalibración
 * ;******************************************************************************/
#include <16f628a.h>
#fuses NOBROWNOUT, PROTECT
#use delay(internal = 4MHz)
#opt 11					// Según esto, optimiza el código pero no noté cambios :/

// Configuración de pines para la pantalla
#define LCD_ENABLE_PIN	PIN_A6
#define LCD_RS_PIN	PIN_A7
#define LCD_RW_PIN	PIN_A0
#include <lcd.c>

#byte PIR1 = getenv("SFR:PIR1")		// Referencia hacia el registro PIR1
#bit  TMR1IF = PIR1.0			// Referencia hacia el bit TMR1IF

// Constantes - Configuración
int1  Flag_Simular = 1;			// Bandera para simulación

// Declaración de variables globales
int16 Valor_Cap;
int8  Valor_Calib;
int16 Tiempo_Descarga;

// Declaración de funciones.
void Descargar_Cap (void);
void Muestreo_Bajo (void);


void main (void) {
    setup_comparator(NC_NC_A1_A2);	// Activar un comparador independiente
    port_b_pullups(true);		// Activar resistencias pull-up en puerto B
    output_high(pin_b0);		// Q1 y Q2 en corte
    output_high(pin_b1);

    lcd_init();				// Inicializar la pantalla
    lcd_putc("\f<CAPCHECK>  v3.0");

    if (!Flag_Simular) {		// Si voy a simular, omito el mensaje y el retardo
	lcd_gotoxy(3,2);
	lcd_putc("DIGITEK 2013");
	delay_ms(2000);
    }

    Tiempo_Descarga = 250;		// Iniciar el muestreo de Cx en períodos de 250 ms
    Descargar_Cap();			// Descargar Cx
    Valor_Calib = read_eeprom(1);	// Leer el valor de calibración

    while (true) {
	if (!input(pin_b3)) {		// Si RB3 es 0...
	    if (Valor_Cap != 0) {		// Si Valor_Cap no es 0.0...

		Tiempo_Descarga = 1;			// Disminuir el tiempo de descarga

		while (true) {
		    Valor_Calib += 1;				// Incrementar el valor de calibración.
		    Muestreo_Bajo();

		    // Mostrar el valor de calibración en hexadecimal
		    lcd_gotoxy(1,1);
		    printf(lcd_putc,"CALIBRANDO: 0x%02X", Valor_Calib);

		    if (Valor_Cap == 0) {			// Cuando Valor_Cap sea 0...
			write_eeprom(1,Valor_Calib);		// Guardar el valor de calibración
			delay_ms(1000);
			break;
		    }
		}
	    }

	    // Calibrado:
	    lcd_putc("\f<CAPCHECK>  v3.0");	// Mostrar que se ha calibrado el equipo
	    lcd_gotoxy(1,2);
	    lcd_putc("*CALIBRACION OK*");
	    delay_ms(1000);
	    Tiempo_Descarga = 250;		// Reestablecer el tiempo de descarga a 250 ms
	}
	Muestreo_Bajo();
    }
}


void Muestreo_Bajo (void) {
    Descargar_Cap();				// Descargar Cx
    clear_interrupt(INT_TIMER1);		// Limpiar la bandera de interrupción del TMR1 (TMR1IF)
    set_timer1(0x00);				// Limpiar valores de TMR1H y TMR1L
    setup_timer_1(T1_DISABLED);			// Prescaler 1:1, TMR1 = OFF
    output_low(pin_b1);				// RB1 en 0 para cargar Cx. (Q2 en saturación)
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);	// Habilitar el Timer1 para medir el tiempo de carga de Cx

    // Esperar_Carga:
    while (!TMR1IF) {				// Mientras TMR1 no desborde
	if (C2OUT) {					// Si C2OUT no es cero
	    // Calculo_Bajo:
	    setup_timer_1(T1_DISABLED);			// Deshabilitar el Timer1 para medir el tiempo de carga de Cx
	    output_high(pin_b1);			// Detener la carga de Cx. (Q2 en corte)

	    Valor_Cap  = get_timer1();
	    Valor_Cap *= 100;				// Para hacer todas las operaciones enteras, hasta el printf
	    Valor_Cap /= 2;				// Corrección para la calibración
	    Valor_Cap -= Valor_Calib * 100;

	    if (Flag_Simular) {				// Si voy a simular entonces resto 0.5
		Valor_Cap -= 50;
	    }

	    lcd_gotoxy(1,2);				// Mostrar el valor del capacitor en pF
	    printf(lcd_putc,"Cx = %0.2f %cF    ", Valor_Cap / 100.0, 0xE6);	// p
	    return;
	}
    }

    // Tiempo_OK:
    clear_interrupt(INT_TIMER1);		// Limpiar la bandera de interrupción del TMR1
    output_high(pin_b1);			// Detener la carga de Cx

    // Muestreo_Alto:
    Descargar_Cap();				// Descargar Cx

    setup_timer_1(T1_DISABLED);			// Deshabilitar TMR1
    set_timer1(0x00);				// Limpiar valores de TMR1
    clear_interrupt(INT_TIMER1);		// Limpiar la bandera de interrupción del TMR1
    output_low(pin_b0);				// RB0 en 0 para cargar Cx
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);	// Habilitar el Timer1 para medir el tiempo de carga de Cx

    // Esperar_Carga2:
    while (!TMR1IF) {				// Mientras TMR1 no desborde
	if (C2OUT) {					// Checar si VCx es > 0.632V
	    // Calculo_Alto:
	    setup_timer_1(T1_DISABLED);			// Detener TMR1 para obtener el tiempo leído
	    output_high(pin_b0);			// Detener la carga de Cx

	    Valor_Cap = get_timer1();
	    Valor_Cap *= 100;				// Para hacer todas las operaciones enteras, hasta el printf
	    Valor_Cap /= 25;				// Dividir el tiempo medido por 25 (8 us/200 Omhs = 1/25)

	    lcd_gotoxy(1,2);				// Mostrar el valor del capacitor en uF
	    printf(lcd_putc,"Cx = %0.2f %cF    ", Valor_Cap / 100.0, 0xE4);	// u
	    return;
	}
    }

    // Tiempo2_OK:
    clear_interrupt(INT_TIMER1);		// Si, limpiar la bandera de interrupción del TMR1
    output_high(pin_b0);			// Detener la carga de Cx
    lcd_gotoxy(1,2);				// Mostrar el mensaje de error en la pantalla por método de tabla
    lcd_putc("!FUERA DE RANGO!");
    delay_ms(1000);				// Esperar 1 segundo
    return;
}


void Descargar_Cap (void) {
    output_low(pin_a2);				// RA2 en 0 para descargar Cx
    delay_us(10);				// 10 us de retardo para tiempo de reestablecimiento
    delay_ms(Tiempo_Descarga);			// Retardo para descargar Cx completamente (250 ms)
    output_float(pin_a2);			// RA2 como entrada
    delay_us(10);				// 10 us de retardo para tiempo de reestablecimiento
}
```
Se han eliminado los _goto_ y una variable. Además, retrasar el uso de punto flotante hasta el final.

Lo malo es que no puedo probarlo a ver si funciona...


----------



## D@rkbytes (Jun 14, 2014)

JoaquinFerrero dijo:


> Esta es otra versión del código escrito en C, dirigida a reducir el tamaño del código final.
> Se han eliminado los _goto_ y una variable. Además, retrasar el uso de punto flotante hasta el final.
> 
> Lo malo es que no puedo probarlo a ver si funciona...


Saludos Joaquín, siento decirte que el código que expones, no funciona.
Muestra valores que no tienen nada que ver con el programa en Protón, ni con el que fue migrado a C.

Sé que el código en C se puede optimizar, sin embargo esa no fue la intención al haberlo pasado a C.
La verdadera intención fue que sea entendido por las personas que usan este lenguaje, y en PICC de CCS.
También entiendo que el uso de GoTo en C no es bien visto, sin embargo no es una instrucción prohibida.

Traté de hacer una transcripción lo más directa del código en PICBasic y por ese motivo omití los GoTo.

Lo que traté también de demostrar, es como los compiladores afectan a un programa en cuanto al tamaño final cuando se usan variables del tipo Float. (Mis respetos para Proton IDE)

Gracias Joaquín por tomarte el tiempo para reducir el tamaño del código, sé que a muchos les será de ayuda para una mejor comprensión del programa.


----------



## Miembro eliminado 356005 (Jun 15, 2014)

Era obvio que no funcionaría a la primera, ya que voy a ciegas.

Mi objetivo no era tanto eliminar los goto, sino intentar reducir el tamaño del programa una vez compilado, ya que según lo que mostrabas antes, estaba a punto de llenarse la memoria para programas.

Naturalmente, el trabajo con punto flotante es muy oneroso en cuestión de instrucciones a ejecutar. Y por eso, cuando tenemos la memoria limitada, es interesante conocer técnicas para reducir el costo.

Aunque no funcione, sí que tengo curiosidad en saber si el tamaño del programa se ha reducido o no. En el programa lo dejé con dos llamadas para conversión y división a punto flotante. Según lo bueno que fuera el compilador debería haber ahorrado algunos bytes.

Saludos.


----------



## D@rkbytes (Jun 17, 2014)

JoaquinFerrero dijo:


> Era obvio que no funcionaría a la primera, ya que voy a ciegas.


Puedes usar el archivo de simulación en proteus para ver los resultados de la programación.


JoaquinFerrero dijo:


> Aunque no funcione, sí que tengo curiosidad en saber si el tamaño del  programa se ha reducido o no. En el programa lo dejé con dos llamadas  para conversión y división a punto flotante. Según lo bueno que fuera el  compilador debería haber ahorrado algunos bytes.


Era obvio que el tamaño se redujera, pues se omitieron las variables float.
No muy drásticamente pero si se obtuvo reducción, aunque no buenos resultados.

Tampoco se mejoró el porcentaje de memoria ROM usada con Proton IDE (71.78% Usando variables Float)

Dejo adjuntos los cambios obtenidos.


----------



## Miembro eliminado 356005 (Jun 17, 2014)

Bueno... al menos lo hemos conseguido reducir en 300 bytes...

Me he bajado la simulación y funciona perfectamente con el cof, pero al ejecutarlo con el cof que viene con el fuente en C, no sale nada, y se ve por las señales que está en una especie de bucle sin fin.

No puedo hacer una compilación nueva, porque no tengo el mismo compilador que el tuyo, pero podría adaptarlo al mío (SDCC + GPUtils).


----------



## luisdlahuerta (Jun 29, 2014)

Hola de nuevo chicos
ayer monté la pcb y funciona muy bien.
estoy pensando como montarla en una cajita o similar para finalizar el montaje.

Una duda que tengo es a la hora de calibrar no llega a cero, a no ser que le ponga las puntas en las manos, ¿hay que conectarle un condensador para esto? si es asi, ¿de que valor?.

Muchas gracias de nuevo Darkbytes.

Os dejo una captura de pantalla de como queda mas o menos la placa, estoy aprendiendo a usar Proteus, asi que disculpad si los packages no están muy bien




>


----------



## D@rkbytes (Jun 29, 2014)

luisdlahuerta dijo:


> Hola de nuevo chicos
> ayer monté la pcb y funciona muy bien.
> estoy pensando como montarla en una cajita o similar para finalizar el montaje.
> 
> ...


El procedimiento de calibración está en el *post #1*.
Para calibrar el capacímetro no tiene que tener ningún capacitor conectado en las terminales de prueba.
Se supone que se debe calibrar a 0.00pF. 
Revisa bien las conexiones de los transistores, que no estés usando el archivo *.hex de simulación y verifica bien el correcto funcionamiento del preset multivueltas.
También se puede usar un preset normal pero cuesta más trabajo el ajuste y con el tiempo se puede desajustar.

Suerte.


----------



## Miembro eliminado 356005 (Jun 29, 2014)

Darkbytes, ¿has mirado lo que te ponía en mi último mensaje? ¿O es que quizás no funciona el diseño del proteus para los dos .cof publicados?

Gracias.


----------



## D@rkbytes (Jun 29, 2014)

JoaquinFerrero dijo:


> Darkbytes, ¿has mirado lo que te ponía en mi último mensaje? ¿O es que quizás no funciona el diseño del proteus para los dos .cof publicados?
> 
> Gracias.


Compilé el código que subiste y lo probé tanto en simulación como físicamente.
En ambos casos muestra valores incorrectos y no se puede lograr la autocalibración.
Se puede decir que tan solo funciona la lectura del capacitor de 47nF.
El capacitor de 470uF lo mide como 24.xxuF. El de 1000uF. como 4.xx y el de 2200uF. como 0.xxuF.

Con el código que subí en C si funciona el *.cof,  si se puede lograr la autocalibración y los valores mostrados en simulación y en físico son correctos.

Nota:
Ahora he logrado reducir el código a un 79.8% aún con float y funciona a la perfección.


----------



## Miembro eliminado 356005 (Jun 29, 2014)

No, no me refiero a mi código, que sabemos que está mal. Se trata del último comentario que hice (#24) sobre que no era capaz de correr uno de tus cof en tu propia simulación del Proteus (los dos publicados antes).

Es decir: el cof que acompaña a la simulación, funciona, pero el cof que acompaña al código C publicado, no. O al menos, en la simulación, no funciona.

Voy a probar este último aporte que has subido.

Gracias.

Edito: ya lo he probado y funciona bien. Como también has subido el código en C, ya puedo intentar mejorarlo (si puedo).

Este es otro intento. Sólo he cambiado un par de cosillas de sitio, así que no creo que haya mucho ahorro. Lo interesante es que funcione igual y el siguiente intento.


----------



## D@rkbytes (Jun 29, 2014)

JoaquinFerrero dijo:


> No, no me refiero a mi código, que sabemos que está mal. Se trata del último comentario que hice (#24) sobre que no era capaz de correr uno de tus cof en tu propia simulación del Proteus (los dos publicados antes).
> 
> Es decir: el cof que acompaña a la simulación, funciona, pero el cof que acompaña al código C publicado, no. O al menos, en la simulación, no funciona.


Tal vez fue porque utilizaste un archivo de simulación anterior, recuerda que en PICC se tiene que usar el pin RW de la pantalla y en los esquemas anteriores este pin está conectado hacia Vss.
No existe otra razón para que no funcionen los coff, ya que son los que he usado para las simulaciones.


JoaquinFerrero dijo:


> Este es otro intento. Sólo he cambiado un par de cosillas de sitio, así  que no creo que haya mucho ahorro. Lo interesante es que funcione igual y  el siguiente intento.


Si funciona bien, no hay ahorro pero ya se ven menos GoTo.


----------



## Miembro eliminado 356005 (Jun 30, 2014)

Siguiente versión. Tampoco hay ahorro de espacio, pero cambiados algunos goto por bucles while o subrutinas.


----------



## D@rkbytes (Jul 1, 2014)

JoaquinFerrero dijo:


> Siguiente versión. Tampoco hay ahorro de espacio, pero cambiados algunos goto por bucles while o subrutinas.


Ya está mejor la versión en C y funciona bien 
Gracias Joaquín por seguir mejorando esta versión del código.


----------



## Miembro eliminado 356005 (Jul 1, 2014)

Otra versión. Vamos poco a poco, pero al menos vamos seguros de que funciona.

Esta versión tiene más limpieza del código, algún comentario más y algún comentario recortado. También están formateados con tabuladores, que ayuda en la edición de las sentencias que les preceden.

Hay también un par de cambios importantes, que es posible que lo hagan fallar, sobre todo el bucle de la línea 144 a 162.

Se ha sacado aparte el procedimiento de Calibrado.

Si tuviera claro el funcionamiento de esas líneas, creo que se podrían simplificar un poco más.

Si me dices que esta versión funciona, entonces el siguiente paso será quitar el uso de punto flotante, donde se debería apreciar ahorro de bytes.


----------



## D@rkbytes (Jul 1, 2014)

JoaquinFerrero dijo:


> Se ha sacado aparte el procedimiento de Calibrado.
> 
> Si tuviera claro el funcionamiento de esas líneas, creo que se podrían simplificar un poco más.


Ese procedimiento sirve para no hacer una recalibración cuando Cx = 0.00 pF.
Únicamente ha faltado declarar este procedimiento en la cabecera, pero agregándolo ya se puede compilar.


JoaquinFerrero dijo:


> Si me dices que esta versión funciona, entonces el siguiente paso será  quitar el uso de punto flotante, donde se debería apreciar ahorro de  bytes.


Si funciona correctamente y los valores mostrados son correctos.
También se ha mejorado la resolución en la escala baja.


----------



## Miembro eliminado 356005 (Jul 1, 2014)

Otra versión. Y ésta seguro que falla. 

Ponme el error que salga.

He comenzado a simplificar código creando más subrutinas.

La duda que tengo es en el paso de valores por las subrutinas. Lo he escrito en C estándar.

¿La librería lcd.c es pública? O mándame un enlace si está por Internet.

¿Cómo se define una variable de 32 bits? ¿long, long int, int32?


----------



## D@rkbytes (Jul 1, 2014)

JoaquinFerrero dijo:


> Otra versión. Y ésta seguro que falla.
> 
> Ponme el error que salga.
> La duda que tengo es en el paso de valores por las subrutinas. Lo he escrito en C estándar.


Aparece error en la rutina *void* Pinta_Txt (*char* *Texto)
**** Error 90 "CapMeter JHD 162A.c" Line 81(41,42): Attempt to create a pointer to a constant*
Y es porque *char *acepta únicamente 8 bits (*unsigned int8*) y no una cadena de caracteres.


JoaquinFerrero dijo:


> ¿La librería lcd.c es pública? O mándame un enlace si está por Internet.


Es la que viene por defecto con el compilador.


JoaquinFerrero dijo:


> ¿Cómo se define una variable de 32 bits? ¿long, long int, int32?


Se define como* int32*
Adjunto los tipos y la librería actual.


----------



## Miembro eliminado 356005 (Jul 1, 2014)

No, eso no es lo que quiere decir el error. Ya sé que char es para 8 bits, lo que he puesto en la declaración de la función Pinta_Txt es char *, que es la forma estándar para definir punteros a cadenas de caracteres.

Lo que dice el mensaje de error es que no se puede crear un puntero a una cadena de caracteres constante.

Entrando en la web de CSS, dice que hay que poner 'const' delante del 'char *' para indicar que se va a apuntar a texto que está en la memoria del programa.

Prueba a poner

const char *

tanto en la declaración de función en la línea 34, como en la definición de función de la línea 179.

Si no funciona, entonces pon esta línea al principio y vuelve a probar:

#device PASS_STRINGS=IN_RAM

y nos cuentas qué tal.

Lo he sacado de aquí: https://www.ccsinfo.com/content.php?page=compiler-features


----------



## D@rkbytes (Jul 1, 2014)

JoaquinFerrero dijo:


> Prueba a poner
> 
> const char *
> 
> ...


Con poner *#device PASS_STRINGS=IN_RAM* ya compila.
Pero ahora se ha elevado el consumo de ROM a 93% y el de RAM a un 34%

El nuevo procedimiento *Pinta_Txt* sigue sin funcionar, muestra una tilde "*'*" en vez de "**CALIBRACION OK**"
Y un 8 en vez de "*!FUERA DE RANGO!*"

No lo veo necesario, pero eso es lo que está pasando ahora.

Edit:
También utilicé const char calib[] = "*CALIBRACION OK*"; y pasando esta cadena a la rutina, sin éxito.


----------



## Miembro eliminado 356005 (Jul 2, 2014)

He intentado instalar la demo del compilador, pero no me funciona con el emulador de Windows que tengo.

He dado un paso atrás y he quitado la Pinta_txt() hasta que sepamos cómo abreviarlo.

Aquí hay otra versión, en la que debería desaparecer el código relativo al punto flotante, y notarse más el aumento de velocidad y el ahorro de bytes.


----------



## D@rkbytes (Jul 2, 2014)

JoaquinFerrero dijo:


> Aquí hay otra versión, en la que debería desaparecer el código relativo al punto flotante, y notarse más el aumento de velocidad y el ahorro de bytes.


Si disminuyó el uso de ROM a 59% y el de RAM a un 17% pero ahora dejó de funcionar el muestreo bajo.
Los valores leídos inferiores a 47 nF muestran 0.00 pF.

Por ahora de los códigos que has modificado, el que mejor va es el del _*post #33*_

Aquí unas fotos de las pruebas del código funcional sobre protoboard.


----------



## Miembro eliminado 356005 (Jul 2, 2014)

Aquí va una versión basada en la #33, pero con alguna mejora, y con la parte de flotante puesta de nuevo.

Estoy intentando conseguir un CCS para Linux


----------



## D@rkbytes (Jul 3, 2014)

JoaquinFerrero dijo:


> Aquí va una versión basada en la #33, pero con alguna mejora, y con la parte de flotante puesta de nuevo.


Esta versión también funciona bien, mejor en físico que en simulación, pero finalmente es de lo que se trata.
76% de ROM y 17% de RAM.


JoaquinFerrero dijo:


> Estoy intentando conseguir un CCS para Linux


Por aquí hablan sobre eso: *Compilador CCS con Wine*


----------



## Miembro eliminado 356005 (Jul 3, 2014)

Instalé una versión 5.018, pero no funciona nada. Me valdría con el compilador de línea de comandos para Linux, pero cuesta 150 $, y como que no voy a pagar eso.

Entonces... te mando la última versión, con el cambio de float a _fixed(3), y si funciona, pues ya lo dejamos así.

Se podría ahorrar unos pocos bytes más, unificando la salida de mensajes, como intentamos antes, pero no creo que merezca más esfuerzo.

Ya me dirás.

Saludos.


----------



## D@rkbytes (Jul 3, 2014)

JoaquinFerrero dijo:


> Instalé una versión 5.018, pero no funciona nada. Me valdría con el compilador de línea de comandos para Linux, pero cuesta 150 $, y como que no voy a pagar eso.
> 
> Entonces... te mando la última versión, con el cambio de float a _fixed(3), y si funciona, pues ya lo dejamos así.
> 
> ...


En esta nueva versión tampoco funciona la escala baja, capacitores entre 1nF a 1uF no pueden medirse correctamente.
Otro detalle ahora, es que los decimales solo muestran ceros sobre cualquier lectura y aparecen 3.
El uso de ROM si bajó considerablemente a 57% pero surge ese detalle sobre las lecturas.

Pienso que con la versión del post 33 ya quedó más que bien el código en C.

Saludos.


----------



## Miembro eliminado 356005 (Jul 4, 2014)

¿Puedes publicar el hex o cof de la última versión que te he mandado?

El caso es que si consigues hacer cambiar la variable float por la int _fixed(3), lo tienes resuelto, ya que, según la documentación, se trata de una variable entera en que el compilador sabe que las últimas cifras son en realidad decimales (3 en este caso).

Lo que no sé entonces es por qué no salen. Las operaciones matemáticas son sencillas.

Voy a ver la documentación, otra vez.

*Edito:* En la carpeta de ejemplos, hay uno que se llama ex_fixed.c donde se muestra el método para sacar un valor de punto flotante con un valor fijo de decimales, almacenado en un entero:

```
void print_fp_2(unsigned int16 value) {
   byte i,digit;
   unsigned int16 divisor;

   divisor=10000;
   for(i=0;i<5;++i) {
      digit    = value/divisor;
      value   -= digit*divisor;
      divisor /= 10;
      putc(digit+'0');
      if(i==2)
        putc('.');
   }
}
```
Este método es también más rápido que usar float, por lo que también es una buena opción.

Y el caso es que esto es justamente lo que hace el atributo _fixed(2) aplicado a las variables enteras.

El último cambio que se me ocurre es la desplegar las operaciones matemáticas, para ver si así las realiza bien:

```
Valor_Cap  = get_timer1();
            Valor_Cap /= 2;
            Valor_Cap -= Valor_Calib;
```


```
Valor_Cap  = get_timer1();
            Valor_Cap /= 25;
```


----------



## D@rkbytes (Jul 4, 2014)

JoaquinFerrero dijo:


> ¿Puedes publicar el hex o cof de la última versión que te he mandado?


Aquí lo adjunto.


JoaquinFerrero dijo:


> El caso es que si consigues hacer cambiar  la variable float por la int _fixed(3), lo tienes resuelto, ya que,  según la documentación, se trata de una variable entera en que el  compilador sabe que las últimas cifras son en realidad decimales (3 en  este caso).


Traté de incorporar el procedimiento del ejemplo ex_fixed.c pero no logré obtener buen resultado.
Anteriormente ya había tratado de hacer algo similar usando divisiones para eliminar variables float pero surgía el problema que tiene este nuevo código con algunas lecturas.
Como quiera el código funcional del post #33 ya tiene optimización y se mejoraron varias cosas.

Saludos.


----------



## Miembro eliminado 356005 (Jul 4, 2014)

He probado el coff... pero no corresponde al último código que te envié...

En fin... que es un rollo no tener el compilador a mano.

Para próximos proyectos, te recomiendo que mires con detalle el uso del _fixed(), porque esa es la clave para no tener punto flotante. Lo único que hay que tener en cuenta es si usar un int8, un int16 o un int32 con el _fixed(), según el rango de números queremos usar.


----------



## D@rkbytes (Jul 4, 2014)

JoaquinFerrero dijo:


> He probado el coff... pero no corresponde al último código que te envié...
> 
> En fin... que es un rollo no tener el compilador a mano.


Pues es la compilación del post 43, que es el último código que has modificado.
Aquí lo adjunto otra vez pero con los archivos del proyecto para que no haya dudas.


JoaquinFerrero dijo:


> Para próximos proyectos, te recomiendo que mires con detalle el uso del  _fixed(), porque esa es la clave para no tener punto flotante. Lo único  que hay que tener en cuenta es si usar un int8, un int16 o un int32 con  el _fixed(), según el rango de números queremos usar.


Lo veré. Ya hice un programa para hacer pruebas especificas sobre este procedimiento.

Gracias Joaquín.


----------



## Miembro eliminado 356005 (Jul 5, 2014)

Ya encontré el problema 

Para el tema de *Fuera de rango*, me estaba rompiendo la cabeza hasta que me di cuenta de que el esquema y el programa están limitados a 2600 µF, y resulta que en la simulación C5 tiene 2700 µF, así que es normal que dé el aviso.

Luego, para el tema de los nF...

Resulta que si el condensador está cerca de los 33 nF, se produce un muestro bajo:

cuenta máxima del Timer1: ~65536
resultado en pF: 65536 / 2 - Valor_Calib ≃ 32768 pF ≃ 33 nF

Pero a partir de ahí, se produce un muestre alto (cambiando los parámetros de cuenta del Timer1).

Para valores del condensador entre los ≃ 33 nF y los ≃980 nF, el contador del Timer1 llega a tener valores entre 1 y 25.

Y llegamos a la fatídica línea 141 del programa:

*Valor_Cap = get_timer1() / 25;*

get_timer1() devuelve un entero (el valor del Timer1), y 25 es otro entero, así que al final tenemos una división entera, que siempre será 0 mientras el numerador sea inferior a 25.

Entonces... se me ocurren dos posibles soluciones para que Valor_Cap, siendo _fixed(3), se entere de que tiene que guardar un número decimal menor que 1 (1/25 = 0.04).

El primer intento es el código que te adjunto, donde (aparte de otros pequeños cambios), la línea se convierte en esto:

*Valor_Cap  = get_timer1();
Valor_Cap /= 25;*

Y esperar a que el compilador se entere.

Si eso no funciona, cambias las líneas para que realice una operación de punto flotante:

*Valor_Cap = get_timer1() / 25.0;*

El tema es ese: conseguir que Valor_Cap almacene los valores correctos entre 0.040 y 1.000.


----------



## D@rkbytes (Jul 5, 2014)

OK. Pues ya está listo el programa y al parecer ahora si ya se puede considerar la versión final.
En este último código que subiste, no funcionaba el procedimiento *Muestreo_Bajo*
Ya se podían medir capacitores en el rango de 33nF. a 980nF. pero en capacitores inferiores siempre mostraba 0.00pF.

Esto se solucionó modificando la estructura de la fórmula involucrada para este cálculo.

Se modificó:
*Valor_Cap  = get_timer1();
Valor_Cap /= 2;
Valor_Cap -= Valor_Calib;*
Por:
*Valor_Cap  = ((get_timer1() /2) - Valor_Calib);*

Con este cambio y los anteriores, ya se puede leer todo el rango sin problemas.
El consumo de *ROM* usando *_fixed(X)* ahora es de *59%* y el de *RAM* es de *17%*

También modifiqué el procedimiento para comprobar si se está en modo de simulación,
ya que no se tomaba en cuenta el valor sobre la definición *SIMULACION
*Así que, lo dejé como lo establecí inicialmente para sólo cambiar un valor booleano.
Eliminé también la declaración de optimización de código, ya que nunca se optimizó nada con ella.

Joaquín, te agradezco bastante por haber colaborado con esta versión del código en C. 
He aprendido bastante viendo las mejoras que has realizado al programa y sé que también a muchos les servirá para poder optimizar programas que requieran el uso de punto flotante sin usar variables del tipo FLOAT.

Adjunto la nueva versión que considero como final, esperando que lo aquí expuesto les sirva a muchos.

Gracias nuevamente Joaquín, y también saludos a todo el Foro desde México.


----------



## mandigula (Ago 8, 2014)

Hola queria hacer una consulta estoy intentando montar el capacimetro pero tengo una duda con las resistencias R5 y R7 que una es de 200 ohm y 2M ohm, pero en el diagrama has colocado 2x1m ohm me podrias explicas¿? desde ya muchas gracias soy nuevo en esto de la electronica jaja los RV1 y RV2 puedo usar multivueltas¿?


----------



## ricbevi (Ago 8, 2014)

mandigula dijo:


> Hola queria hacer una consulta estoy intentando montar el capacimetro pero tengo una duda con las resistencias R5 y R7 que una es de 200 ohm y 2M ohm, pero en el diagrama has colocado 2x1m ohm me podrias explicas¿? desde ya muchas gracias soy nuevo en esto de la electronica jaja los RV1 y RV2 puedo usar multivueltas¿?



Hola...Los preset pueden ser multi-vueltas(es un desperdicio para RV2 pero...) y la aclaración de 2X "valor" es para hacer el "valor final de resistencia" que necesita el circuito ya que comercialmente de forma standar no vienen ... por ejemplo se  colocan en serie dos resistencias de los valores indicados y se llega a ese valor final.

Saludos.

Ric.


----------



## mandigula (Ago 8, 2014)

ricbevi dijo:


> Hola...Los preset pueden ser multi-vueltas(es un desperdicio para RV2 pero...) y la aclaración de 2X "valor" es para hacer el "valor final de resistencia" que necesita el circuito ya que comercialmente de forma standar no vienen ... por ejemplo se  colocan en serie dos resistencias de los valores indicados y se llega a ese valor final.
> 
> Saludos.
> 
> Ric.



Mucho gracias por tu respuesta, termine colocando 2 preset comun y perdon por la duda tonta de las resistencias jaaja muchas gracias, ahora con paciencia a soldar todo  esperemos qe funciones jajaja



otraaaaa consulta se puede alimentar con 9 volt¿? o es estrictamente a 5volt¿?


----------



## ricbevi (Ago 8, 2014)

mandigula dijo:


> Mucho gracias por tu respuesta, termine colocando 2 preset comun y perdon por la duda tonta de las resistencias jaaja muchas gracias, ahora con paciencia a soldar todo  esperemos qe funciones jajaja
> 
> 
> 
> otraaaaa consulta se puede alimentar con 9 volt¿? o es estrictamente a 5volt¿?



Con 5Vdc si no quieres quemar algo!!!.

Ric.


----------



## mandigula (Ago 9, 2014)

mi ultima duda, en el diagrama no salen los pines 15 y 16 que son lo de la iluminacion del display los puedo conectar directamente a los 5 volt¿?, y el pin RW en la simulacion esta conectado a la pata 17 del pic pero en los diagramas el pin RW esta conectada a masa, a que se debe esto¿? muchas gracias, y disulpen por las molestias


----------



## D@rkbytes (Ago 9, 2014)

Para que no continúes con tantas dudas, te recomiendo que leas detenidamente el tema.
Verás que se han posteado versiones diferentes y debes utilizar el esquema correspondiente con cada versión
Dependiendo del programa utilizado, se deberá colocar o no el pin RW a negativo. (VSS)
Y la alimentación del display si debe ser la misma que la del microcrontrolador. (5VDC)


----------



## ricbevi (Ago 9, 2014)

mandigula dijo:


> mi ultima duda, en el diagrama no salen los pines 15 y 16 que son lo de la iluminacion del display los puedo conectar directamente a los 5 volt¿?, y el pin RW en la simulacion esta conectado a la pata 17 del pic pero en los diagramas el pin RW esta conectada a masa, a que se debe esto¿? muchas gracias, y disulpen por las molestias



Agrego a lo que contesto el amigo D@rkbytes que a la iluminación del display(pines 15 y 16) le puedes disminuir el consumo de corriente mediante una resistencia en serie en alguno de ellos y esta la debes buscar a gusto tuyo Ej:10ohms, 27ohms, etc...a mayor valor de la resistencia menor sera el consumo y la iluminación disminuira.

Ric.


----------



## esneiderlg (Abr 22, 2015)

Buenas tardes una duda en los pines 15 y 16 donde va el crystal los tienes ocupados para la lcd entonces funciona sin el crystal o con el crystal interno.
Gracias compañeros es un gran proyecto quedo atento a respuestas


----------



## D@rkbytes (Abr 22, 2015)

Inicialmente subí dos versiones sin código fuente, una con oscilador interno y la otra con oscilador a cristal.
Esas versiones eran también para dos tipos de pantallas LCD.
Como ahora ya se encuentran los códigos fuente para Proton Compiler y PIC C Compiler, ya puedes modificar el código y seleccionar los pines para pantalla y también decidir si lo prefieres usar con oscilador interno o con cristal.
Ambos tipos funcionan satisfactoriamente.


----------



## esneiderlg (Abr 25, 2015)

Hola muchas gracias por la respuesta; Si ya los modifique muchas gracias por tu ayuda gran proyecto


----------



## cristian76 (Jun 12, 2015)

gracias darkbytes , lo necesitaba con urgencia en el taller , una consulta tu crees que se pueda ampliar el rango de medicion sin afectar la precision del instrumento?


----------



## D@rkbytes (Jun 12, 2015)

No. Ya no se puede incrementar el rango porque se está usando el máximo valor soportado por el Timer 1.


----------



## Miembro eliminado 356005 (Jun 13, 2015)

Quizás llevando las veces que el timer1 ha "dado la vuelta"


----------



## cristian76 (Jun 20, 2015)

gracias por la respuesta darkbytes , por la red encontre que con el mismo pic se puede hacer un inductometro y capacimetro a la vez http://www.e-radiocontrol.com.ar/?Circuitos_de_medicion_y_pruebas:Capacimetro_e_inductometro_con_PIC16F84_o_PIC16F628 , se podria añadir el inductometro a tu proyecto? con tu respuesta ya no te molestaria mas  igual muchas gracias es un buen proyecto para todos .


----------



## D@rkbytes (Jun 20, 2015)

cristian76 dijo:


> ¿Se podría añadir el inductometro a tu proyecto?


Claro que se puede, pero hay dos inconvenientes.


Se tendría que cambiar el PIC16F628A por el PIC16F648A, porque ya no cabría el otro programa.
El programa que mencionas está en ensamblador y éste está realizado en PICBasic y en C
Ese programa que mencionas ya es obsoleto pues ya tiene una versión "mejorada" sin el comparador externo.
Busca capacímetros  por el Foro y encontrarás que muchos ya han realizado ese proyecto y su variante.

Si quieres hacer el intento de incluirlo a este proyecto, va a ser algo que te lleve algún tiempo, pues resultaría más fácil escribir otro programa para la función de inductómetro, que trasladar ese.

Suerte.


----------



## cristian76 (Jul 6, 2015)

pcb terminado , si alguien pudiera hacerla mas compacta estaria muy agradecido , cualquier error favor de avisar , editado en pcb wizard .
no consegui el multivuelta de 22k , por lo que  enserie cada extremo con una resistencia de 1k .
Ver el archivo adjunto capacimetro.rar


----------



## D@rkbytes (Jul 6, 2015)

El valor del potenciómetro no es tan crítico, sirve para tomar una tensión de referencia y puede estar en el rango de 5 KΩ a 50 KΩ


----------



## cristian76 (Jul 17, 2015)

funciona de maravilla  , el unico detalle es que cuando enciende por primera vez es muy lento tuve que regrabarlo como 3 veces  , a la hora de calibrarlo me paso lo mismo todo iva lento , sin embargo , una vez calibrado todo lo demas quedo atras , simplemente muy preciso y rapido . muchas gracias .
Algunas fotos , prueba del instrumento midiendo un capacimetro de 120 uf . Ver el archivo adjunto fotos capacimetro.rar


----------



## ismadl (Jul 29, 2015)

Cual versión sirve mejor.. ayuda.. 

Arme la primera version "CapMeter LCD Stándar Int_Osc".. pero no me muestra los valores precisos..

solo me muestra el valor exacto del capacitor con el cual lo calibre.. que es de 1uF me muestra 1.00uF

luego con uno de 220uF me muestra 240uF.. con uno de 470nF me muestra 0.52uF=520nF.. y asi..

ah.. es normal que los leds "hi y low" parpaden todo el tiempo cuando hago la medida??


----------



## D@rkbytes (Jul 29, 2015)

Cualquiera de las versiones funcionan bien, en sí todas son funcionales.
Las versiones del primer post son para usar oscilador a cristal u oscilador interno y para dos tipos de pantalla.

Y es normal que siempre te muestre el valor exacto del capacitor con el que realizaste la calibración, porque ese capacitor fue tomado como referencia.
Los capacitores, al igual que las resistencias, tienen un rango de tolerancia y no siempre vas a obtener una lectura igual a la que viene impresa.

Lo que debes tener en cuenta, es qué tan lejos de tolerancia se encuentra el valor leído sobre el valor impreso.
Los capacitores electrolíticos tienen ± 20 % de tolerancia.

También es normal que los LEDs destellen cuando se está realizando la lectura.
Mientras más alta sea la capacidad, más lento destellarán y viceversa.

Puedes probar éste otro, que fue la versión final: *CapMeter PICC Final*


----------



## ismadl (Jul 30, 2015)

Gracias D@rkbytes ahora pruebo esta version.. una consulta ya lo calibre y todo..
pero nunca se me queda en 0.00pF? siempre esta variando.. a que se debe esto o es normal??

cuando lo calibro, cuando estoy en cerca de "fuera de rango" suena el probador de forma continua..
cuando me alejo un poco, suena pero de forma discontinua como pitidos.. me alejo mas, pero nunca deja de sonar completamente.. eso también es normal?


----------



## D@rkbytes (Jul 30, 2015)

Podría ser por las siguientes causas:


 Porque las pistas del circuito impreso son muy delgadas y con falta de plano de tierra.
Porque las puntas de prueba tienen el cable demasiado largo.
Porque el voltaje de alimentación no es estable o no está bien filtrado.
 
Lo de pitido que mencionas, lo desconozco.
El circuito no tiene ninguna parte que pueda producir sonidos.
Tal vez sea la fuente de poder que estás usando la que produce ese sonido, por ser conmutada y de baja corriente.

No estaría mal que adjuntaras algunas fotos del montaje.


----------



## ismadl (Ago 9, 2015)

*H*ola D@rkbytes*,* pues lo del pitido es del tester en modo de continuidad o diodos.. lo pongo en las puntas de prueba del Cx y ahi pasa lo que te dije.. 
*Y* esta en protoboard no en placa ggg

Sera que puedes subir un vídeo de como calibrar el capacimetro? creo que ahi esta mi error *por_*fa*vor*..

*L*o que esta armado ahorita en la foto es la versión final CapMeter PICC Final


----------



## D@rkbytes (Ago 9, 2015)

No tengo ningún capacímetro armado por el momento, pero la calibración es de lo más fácil.
Recuerda que una vez calibrado, todo el proceso de este capacímetro es automático.

Para calibrarlo, tan sólo debes de mantener las puntas o terminales de prueba al aire. (Sin nada conectado y el potenciómetro de ajuste a la mitad)
Después presionas el botón "AutoCal" y automáticamente debe empezar la calibración hasta quedar en 0.00 pF.
Posteriormente debes realizar un ajuste con el potenciómetro, colocando un capacitor de valor conocido.
Esto se debe hacer con los llamados capacitores patrón que tienen una baja tolerancia.
Si no consigues este tipo de capacitores, mide alguno con algún capacímetro de marca y toma ese valor como referencia.

Cuando ya tengas un capacitor de valor conocido, lo colocas en las puntas de prueba y debes ajustar el potenciómetro hasta que obtengas una lectura lo más próxima al valor del capacitor de referencia.

Tras éste ajuste es posible que en la lectura ya no se obtengan los 0.00 pF cuando se retire el capacitor.
Para corregir ésto, nuevamente se tiene que presionar el botón "AutoCal"

Eso es todo. Suerte.


----------



## magomac (Ago 11, 2015)

PCB V1.0 (100x50mm)  CapMeter PICC Final.





Sugerencias:
-Usen PIN-Header  para el LCD que ayuda mucho para darle cierta altura respecto de la placa.
-Acuesten los transistores.
-Pueden usar un zócalo de 8 pines partido por la mitad para conectar los cap a medir.
-Alimenten con *no más* de 12v dc.
-En lugar del puente que va al pin 15 del LCD, algunos le intercalan una R de 33Ω 1/4W.

El conector de entrada coincide con Jack DC para pcb perfectamente.
Si encuentran algo susceptible de mejorar o corregir, me comentan y la hacemos..

Agradecimientos a D@rkbytes por este excelente aporte y a Joaquin Ferrero
por su valiosa colaboración.

slds.


----------



## Ballestero (Nov 26, 2015)

D@rkbytes dijo:


> En esta ocasión les traigo un capacímetro autorango con una respuesta desde 3pF hasta 2600uF.
> El circuito funciona en base a un microcontrolador PIC16F628A, unos pocos componentes y un LCD 16x2
> Para su funcionamiento únicamente se necesita realizar un ajuste sobre un potenciómetro multivueltas.
> 
> ...



Buenas amigo disculpa si la pregunta resulta tonta pero me interesa hacer este proyecto y el pic que dispongo es el PIC16F628A, es lo mismo con la A al final que sin la A? O habrá alguna diferencia. Gracias por tu aporte.

Ah y la otra pregunta es, habría mucho cambio en el código si decido usar display en vez de lcd?


----------



## D@rkbytes (Nov 26, 2015)

Ballestero dijo:


> Buenas amigo disculpa si la pregunta resulta tonta pero me interesa hacer este proyecto y el pic que dispongo es el PIC16F628A, es lo mismo con la A al final que sin la A? O habrá alguna diferencia.


Según las hojas de datos, no hay diferencia en cuanto a sus características.
Tal vez el PIC16F628A sea una versión mejorada en otros aspectos, pero sí lo puedes usar para éste proyecto.
 
Siempre que tengas éste tipo de dudas, te recomiendo que leas las hojas de datos.​


Ballestero dijo:


> Ha, y la otra pregunta es, ¿habría mucho cambio en el código si decido usar display en vez de lcd?


Si hablas de displays LED de 7 segmentos, si existe mucha diferencia.
No es lo mismo escribir un programa para esos displays con sistema multiplex, que usar una pantalla LCD.


Ballestero dijo:


> Gracias por tu aporte.


Por nada. Espero que tengas buenos resultados.


----------



## cristian76 (Mar 7, 2016)

una consulta , se podria usar el pic 16f84a ?


----------



## D@rkbytes (Mar 8, 2016)

Saludos.
No, no se puede usar el PIC16F84A porque no tiene comparadores, y en el PIC16F628A son la base de este proyecto.


----------



## Josnaro (Abr 29, 2016)

Hola compañeros.

Soy nuevo en el mundo de los pic. Estoy intentando grabar el pic con pickit2 y al leer el HEX me sale en rojo Code protect.
Le doy a grabar parece que todo esta bien me aparece "Programming Successful", pero cuando le doy a verificar me dice " Verification of Program Memory failed at address 0X000000 " y logicamente al darle Leer me sale todo "0000"

Gracias.


----------



## D@rkbytes (Abr 29, 2016)

Josnaro dijo:


> Hola compañeros.
> 
> Soy nuevo en el mundo de los pic. Estoy intentando grabar el pic con pickit2 y al leer el HEX me sale en rojo Code protect.
> Le doy a grabar parece que todo esta bien me aparece "Programming Successful", pero cuando le doy a verificar me dice " Verification of Program Memory failed at address 0X000000 " y lógicamente al darle Leer me sale todo "0000"
> ...


Eso es normal, porque el programa se grabó con protección de código.
Entonces el PICkit no puede comparar el programa ingresado con el programa leído, porque leerá ceros.
Por eso falla la verificación desde la dirección 0x000000.

En éste caso, eso no quiere decir que el programa en el PIC esté corrupto.
Ya te apareció "Programming Successful" y eso es lo que importa.


----------



## Josnaro (Abr 29, 2016)

Entonces se supone que se grabó, yo es para empezar con la placa, que estoy deseando probarlo.

Enviado desde mi Spectrum ZX


----------



## D@rkbytes (Abr 29, 2016)

Si, el PIC ya se grabó bien.
Arma el circuito. Si lo realizas correctamente, debe funcionar sin problemas.

Suerte.


----------



## Josnaro (Abr 30, 2016)

Si señor, hay esta el pedazo de capacimetro. Muchas gracias.

Ahora estoy pensando en algun proyecto nuevo para hacer.

Lo dicho, muchas gracias.


----------



## moises92 (Dic 14, 2016)

Hola que tal soy nuevo en el forum....copie los códigos y los adapte para un pico 16f876a pero no me corre


----------



## D@rkbytes (Dic 14, 2016)

moises92 dijo:


> Copié los códigos y los adapté para un PIC16F876A, pero no me corre.


¿Y cómo quieres que sepamos por qué no te funciona?
Pública lo que has hecho, por favor.


----------



## moises92 (Dic 14, 2016)

Ok bueno yo deje el código tal cual solo cambie la donde dice incluye <16f628a> por el pic que tengo por el 16f876a y me arroja 32 errores y en la parte del diagrama en proteus redefinir los puertos equivalentes del diseño original por los del 16f876a allí le dejo las imágenes



la verdad estoy empezando y me gusta cualquiere apoyo se los agradezco


----------



## D@rkbytes (Dic 14, 2016)

No publiques imágenes, adjunta el proyecto dentro de un archivo comprimido, por favor.


----------



## moises92 (Dic 15, 2016)

solo cambie la libreria de <16f628a>  por 16f876a y redefini los puertos

en el diagrama de proteus cambie los puertos equivalentes al 16f876a

me refiero al archivo .c


----------



## D@rkbytes (Dic 16, 2016)

Pues muy mal. Siempre debes tener en cuenta esos detalles.
No puedes migrar un programa de un PIC a otro PIC sin tener en cuenta sus características.
Primero debes leer la hoja de datos y ver si en todo son compatibles.
Si lo son, cómo en éste caso, únicamente cambia los parámetros y puertos para ese PIC.


----------



## moises92 (Dic 16, 2016)

Lo migre porque vi que eran similares ahora como solucionó los errores del código ya modificado??


----------



## D@rkbytes (Dic 16, 2016)

A ver. Ya lo expliqué. Acomoda los puertos y registros conforme al PIC16F876A.


----------



## juanma2468 (Dic 17, 2016)

D@rkbyte, el funcionamiento del capacimetro se basa en cargar los capacitores a corriente constante y medir el tiempo de carga a un cierto valor?


----------



## D@rkbytes (Dic 17, 2016)

Si lees el tema podrás ver que lo que preguntas ya se ha explicado.


----------



## moises92 (Dic 18, 2016)

gracias ya configure los puertos y el codigo casi fuciona solo me arroja un error en la seccio de los comparadores donde sale una sentrencia (nc_nc_a1_a2) que puedo hacer alli?


----------



## D@rkbytes (Dic 18, 2016)

En ese PIC cambia el sistema de comparadores, así que tendrás que hacer varios cambios.
Para obtener un único comparador, necesitas usar la referencia de C1OUT, o sea: RA0 y RA3.
Aparte, cambiar los terminales de conmutación.
La configuración que debes usar, es: A0_A3_A1_A3

No te garantizo que funcione correctamente con ese PIC, pero puedes leer el tema para ver la solución a los problemas de resolución.


----------



## marcoscab1166 (Oct 24, 2018)

Buenas, antes que nada gracias a D@rkbytes y a los que colaboraron por compartir este estupendo proyecto.
Yo estoy tratando de usarlo con un PIC 18f4550, que tiene excelentes prestaciones. La idea es hacer un dispositivo para probar cables (que es lo que fabricamos en mí trabajo), y como hay algunos que tienen un capacitor integrado me viene perfecto esto.
Logré hacerlo funcionar haciendo los cambios correspondientes, lo que incluye una pequeña modificación en la fórmula de conversión del muestreo bajo.
El problema que tengo es que los cables deberían probarse a 24v. Asi que quería saber la fórmula con la que sacaron el valor de las resistencias así puedo cambiarlas por las que vayan. Si no es viable armar el circuito a ese voltaje, lo hago a 5v y ya, pero la idea es probar el cable en los parámetros con los que va a funcionar ya instalado.
Cuando pueda subo el código y el esquema, el esquema es en realidad el mismo no cambie nada fuera de la regulación del trimmer.
En el código cambie la asignación de los pines, y en la fórmula del muestreo bajo cambie la original, que creo era algo así:

valor_cap = (valor_timer1 / 2) - valor calibración

por esta:

valor_cap = (valor_timer1 *2) - 20 - valor_calibracion

Ese 20 es la diferencia que me daba entre las lecturas y el valor de capacitor que estaba probando. Esa diferencia era constante. 
Disculpen que no subo nada es que lo estoy escribiendo en el celular.
Desde ya gracias por la ayuda.


----------



## juanma2468 (Oct 24, 2018)

marcoscab1166 dijo:


> Buenas, antes que nada gracias a D@rkbytes y a los que colaboraron por compartir este estupendo proyecto.
> Yo estoy tratando de usarlo con un PIC 18f4550, que tiene excelentes prestaciones. La idea es hacer un dispositivo para probar cables (que es lo que fabricamos en mí trabajo), y como hay algunos que tienen un capacitor integrado me viene perfecto esto.
> Logré hacerlo funcionar haciendo los cambios correspondientes, lo que incluye una pequeña modificación en la fórmula de conversión del muestreo bajo.
> El problema que tengo es que los cables deberían probarse a 24v. Asi que quería saber la fórmula con la que sacaron el valor de las resistencias así puedo cambiarlas por las que vayan. Si no es viable armar el circuito a ese voltaje, lo hago a 5v y ya, pero la idea es probar el cable en los parámetros con los que va a funcionar ya instalado.
> ...


Pasa que si alimenta con 24V quemas la entrada del micro, por eso se los trabaja con 5V. Una posible solución sería que escalera los 24V a una tensión equivalente de 5V


----------



## marcoscab1166 (Oct 24, 2018)

Por supuesto si, de hecho a los otros cables los pruebo así.
Lo dejo a 5v entonces, más práctico.
Gracias.


----------



## pandacba (Oct 24, 2018)

No entiendo porque queres medir capacidad con tensión,  los capcímetros miden la capacidad, con estos  descargados,  de que rago de capacidad estas hablando?


----------



## marcoscab1166 (Oct 24, 2018)

Disculpa me explique mal yo.
Lo que necesito medir es el valor del capacitor, asi que este circuito me sirve perfecto asi como esta. Despues hay otros factores a medir en el cable pero ya lo solucione. Estoy terminando el codigo a modo de libreria, cuando lo tenga lo subo.


----------



## leo121177 (Jul 27, 2020)

D@rkbytes dijo:


> Para aquellos que les interese saber cómo es que funciona este sencillo capacímetro, aquí está el código fuente.
> 
> Está escrito en PICBasic con Proton IDE.
> 
> ...


*H*ola*. ¿N*o tiene una versi*ó*n en picbasic solamente*? E*n proton no me sirve. *G*racias*.*


----------



## D@rkbytes (Jul 27, 2020)

leo121177 dijo:


> *¿N*o tiene una versi*ó*n en picbasic solamente*?*


No, el programa fue escrito en PICBasic de Proton y posteriormente se migró al C de CCS


leo121177 dijo:


> *E*n proton no me sirve.


Si no te sirve lo puedes modificar para el PICBasic de MicroCode Studio, son similares, pero Proton es mucho mejor.


----------



## DJ T3 (Ago 17, 2020)

Bueno. Me tome el atrevimiento de modificar un minimo los archivos para ordenamiento y posible ahorro de ROM.
De la ultima version; ROM 56% @ RAM 6% - 17%
La que modifique;
modo simulacion: ROM 49% @ RAM 5% - 17%
Modo normal: ROM 51% @ RAM 5% - 17%

Ya voy a ver para portarlo a Arduino, para los amantes.

Compilador; PICc V4.104
Simulador; Proteus V8.7 SP3
Version; Basada en la V1.22 de *éste post* (si no me equivoco)

PD: Probado a medias con el simulador (se me cierra), no tengo armado nada en fisico.

PD2: Los archivos traté de comentar lo mejor que pudes


----------



## Jmur30 (Sep 22, 2020)

Muy buenos días disculpen la pregunta soy nuevo en esto, pero ahí leyendo un poco el código del programa del PIC aunque esta comentado no entiendo muy bien como conocer el valor que tendrá el get_time() que es del módulo temporizador del PIC, porque el RV1 está al 62% que está configurado como un divisor de voltaje y que dicho valor fijo es 3.1 V que ingresa al pin RA1 del PIC en donde se compara con el valor de salida del circuito donde se encuentran los transistores PNP y dicho resultado ingresa al pin RA2, y que internamente el PIC cuenta con un comparador en donde evalúa el voltaje y de acuerdo a eso realiza una acción internamente.

Disculpen mi ignorancia de donde salen los 8us, los 250ms los estableció en base a alguna fórmula??

De antemano le agradezco por su tiempo que tenga un excelente dia.


----------



## D@rkbytes (Sep 22, 2020)

Todo eso se ha explicado anteriormente y viendo el código final se puede comprender mejor.
Las lecturas se toman mientras el timer 1 no desborde y el resto es en base al comparador interno.
Si desborda se cambia de rango y se vuelve a calcular


Jmur30 dijo:


> Disculpen mi ignorancia de donde salen los 8us, los 250ms los estableció en base a alguna fórmula?


Eso también está explicado en el programa.
Es parte de la fórmula principal y está basada en los 200 Ohms de la resistencia de carga R6 para calcular el tiempo de carga del capacitor.
En sí, para poder entender esto mejor tendrías que leer la hoja de datos del PIC16F628A


----------



## paliz (Nov 24, 2020)

¿al circuito inicial se le podría añadir una protección de sobre-voltaje con la clásica pareja de diodos a vcc y gnd en el nodo Vref?

es para evitar el paso de tener que descargar fuera del medidor, condensadores con voltajes >5v


----------



## D@rkbytes (Nov 24, 2020)

No lo sé, aunque tal vez interfiera.
Con la configuración electrónica de entrada ya se tiene buena protección.


----------



## DJ T3 (Nov 24, 2020)

Quizas agregue algo de capacitancia.
Mejor usa una llave selectora para "descargar" sin quitar del aparato, y en la otra posicion al medidor


----------



## DOSMETROS (Nov 24, 2020)

Pulsador NC en paralelo con las pinzas . . . pulsas y lees


----------

