[Aporte] Capacímetro Autorango con PIC16F628A

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.
 

Adjuntos

  • CapMeter JHD 162A.c.rar
    1.9 KB · Visitas: 49
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.
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.
 
¿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:
PHP:
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:
PHP:
            Valor_Cap  = get_timer1();
            Valor_Cap /= 2;
            Valor_Cap -= Valor_Calib;
PHP:
            Valor_Cap  = get_timer1();
            Valor_Cap /= 25;
 
Última edición por un moderador:
¿Puedes publicar el hex o cof de la última versión que te he mandado?
Aquí lo adjunto.
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.
 

Adjuntos

  • CapMeter PICC Post 43 Hex File.rar
    31.9 KB · Visitas: 80
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.
 
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.
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.
 

Adjuntos

  • CapMeter PICC Post 43.rar
    56.4 KB · Visitas: 64
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.
 

Adjuntos

  • CapMeter JHD 162A.c.rar
    1.9 KB · Visitas: 56
Última edición por un moderador:
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. :aplauso:
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.
 

Adjuntos

  • CapMeter PICC Final.rar
    36.6 KB · Visitas: 11,729
Última edición:
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¿?
 
Última edición:
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.
 
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 :p esperemos qe funciones jajaja



otraaaaa consulta se puede alimentar con 9 volt¿? o es estrictamente a 5volt¿?
 
Última edición:
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 :p 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.
 
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
 
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)
 
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.
 
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
 
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.
 
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?
 
Atrás
Arriba