Autor Tema: Medidor capacitivo de nivel de combustible.  (Leído 508 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 596
Medidor capacitivo de nivel de combustible.
« en: 03 de Octubre de 2020, 13:29:55 »
Hace un tiempo publiqué este tema:

http://www.todopic.com.ar/foros/index.php?topic=49594.msg411259#msg411259

 Donde construí un medidor capacitivo de nivel de combustible cuya estrategia de funcionamiento consistía en aplicar una frecuencia fija a los electrodos sumergidos en gasolina para luego rectificarla y obtener la tensión continua resultante para medirla con un ADC.  Esto funcionaba, pero no del todo bien. Era inestable y había que estar recalibrando. La calibración se hacía mediante dos potenciómetros que fijaban las vref + y - del modulo analógico del pic.

   El usuario @picuino me propuso otra forma mucho mejor de hacerla y así lo he planteado con un ligero cambio que ahora comento. La estrategia consiste en hacer un resonador RC donde C es la propia sonda y R es una resistencia de 10 K de alta precisión.

   La sonda es un tubo de cobre de 6mm que lleva un hilo de 3mm esmaltado en su interior, así sin mas. El tubo es un electrodo y el hilo interior es el otro electrodo. El dieléctrico es la parte variable del "condensador" siendo la propia gasolina o el aire.

   El resonador RC se realiza utilizando un comparador del pic 16f628A que mediante una serie de resistencias de 1k5 consigue que la oscilación sea entre 2,2V y 3,3V lo que significa que en la sonda habrá una señal oscilante con suelo en 2,2V y techo en 3V3 ( 1,1 vpp) y una intensidad muy limitada. Esto para salvar el tema de seguridad y no tener mucha tensión entre electrodos dentro del depósito.

  Originalmente, en la solución que propuso Picuino, la salida del comparador se conectaría a la entrada del modulo capture/compare/pwm en modo capturador, por lo que capturando las lecturas del timer1 cada flanco de subida del comparador se podía obtener con muchisima precisión el valor de la frecuencia de la señal.

  El problema me lo he encontrado en que la frecuencia que genera la sonda es de 1.136.363 Hz (1,13 Mhz) llena de combustible, y 1.408.450 Hz (1,40 Mhz) estando vacía.

    Esas frecuencias y con un pic trabajando a 20 Mhz con ciclo de instrucción a 200 nS está lejos de poderse leer por este método por que el tiempo que se demora acumulando las lecturas y manteniéndose en el bucle con o sin interrupción es mucho o bien yo no he sabido plantear bien esta parte.

  Por ello lo que he hecho ha sido utilizar el timer0 y el timer1. El timer0 recibe la salida del comparador, es decir, la frecuencia.
 El timer1 está conectado al oscilador interno y lo utilizo para generar un bucle de 1 segundo de duración.  (Esto significa inherentemente que el sistema conseguirá un rate de 1 lectura por segundo), me sirve perfectamente.

  Dentro de ese "segundo" lo que hago es contar con el timer0 (y sus desbordamientos por supuesto) el numero de pulsos total que envía la salida del comparador y ahí obtengo casi de forma exacta el valor de la frecuencia.

   Ha quedado bastante estable, tiene un rango amplio desde lleno hasta vacío por lo que se puede obtener una lectura del nivel bastante precisa.

   Este es el circuito y el prototipo como va quedando. Me ha fallado el encapsulado del Max232 que es mas estrecho que el de la PCB. los cables que aparecen son solo para la programación, luego se retira.  El puente con el trozo de cable en el pic es debido a cambiar la entrada del comparador por el timer0 como ya dije antes. Ya en la versión final quiero también quitar la placa buck y ponerlo todo en la placa base y terminarlo haciéndole una carcasa, de momento modelada e impresa en 3D con PLA u otro material que soporte bien el combustible sin dañarse.

  La señal la envía por rs232 y el receptor será el encargado de interpretarla y relacionar la lectura con la cantidad según la forma del tanque y demás. Pero eso ya se hace todo en el receptor.

 

* FUEL_LEVEL.jpg
(83.4 kB, 951x600 - visto 120 veces)


 

* IMG_7642.JPG
(127.42 kB, 1005x572 - visto 123 veces)


 

* IMG_7643.JPG
(76.28 kB, 475x465 - visto 117 veces)


Por ultimo comparto el código completo en CCS, abierto a sugerencias:

Código: C
  1. #include <16f628.h>  // Descriptores de dispositivo.
  2.  
  3. #fuses  NOWDT, HS, NOMCLR, BROWNOUT, PROTECT   // No Whatdog. , oscilador de cuarzo, no Master clear, Reset Brownout, Codigo protegido.
  4. #use delay(clock=20000000)                     // Función Delay tendrá en cuentra la velocidad del cristal elegido.
  5. #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8)   // El puerto RS232 operará a 9600 bps, 8N1.
  6.  
  7. #bit led=0x006.0   // Macro de instancia al puerto B0 donde se ha conectado un diodo led indicador.
  8. #byte CMCON=getenv("SFR:CMCON")   // Macro de instancia al registro CMCON para configrar el modo de trabajo de los comparadores analógicos.  
  9. #bit TMR1IF=0x00c.0   // Macro de instancia para bandera interrupcion desbordamiento del timer 1
  10. #bit TMR0IF=0x00b.2   // Macro de instancia para bandera interrupcion desbordamiento del timer 0
  11.  
  12.  
  13.  
  14. void main() {
  15.    
  16.     led = 0;                 // Led de barrido/control apagado inicialmente.  
  17.     set_tris_a(0b11110111);  // Configuración de entradas y salidas.
  18.     set_tris_b(0b11111010);
  19.     CMCON = 0xc6;            // Comparadores en modo referencia común (+COMUN "PIN A2"), es decir, que el pin A2 está conectado a las entradas + de ambos comparadores.
  20.                              // Las salidas son independientes y los (-) son independientes. No se invierten las salidas.
  21.                              // Usaremos solo la salida del comparador 1 (Pin A3).
  22.                              // La entrada (-) del comparador 1 (Pin A0) será donde se conecta el circuito RC
  23.    
  24.    
  25.     setup_timer_0(T0_EXT_L_TO_H | T0_DIV_1);    // El timer0 se incrementa de forma externa, en flanco de subida, sin prescalador. La salida del comparador será quien incremente este timer.
  26.     setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   // El timer1 es conectado al oscilador interno sin prescalador. Será usado como base de tiempo para la medición.
  27.    
  28.     led = 1;                // Genero un parpadeo de medio segundo para indicar que la cpu está en marcha.
  29.     delay_ms(500);         // y así también hago una espera de estabilidad de clock, de alimentación, etc.
  30.     led = 0;              // Vuelvo a apagar el led.
  31.    
  32.    
  33.    
  34.     while(1) {                    // Bucle de función.
  35.        
  36.         int16 desbtmr0 = 0;       // Contador de desbordamientos del timer0
  37.         int8 desbtmr1 = 0;        // Contador de desbordamientos del timer1
  38.         set_timer0(0);            // Timer0 puesto a cero.
  39.         TMR0IF = 0;               // Banderas de desbordamiento inicialmente a cero.
  40.         TMR1IF = 0;              
  41.          
  42.         while(desbtmr1 < 76) {   // Generamos bucle de aproximadamente 1 segundo. (Entrada a timer1 = 5000000, deborda cada (65535 + 1), 5000000/65536 = 76,29 desbordamientos necesarios para 1 segundo)
  43.            
  44.             if (TMR0IF) {         // ¿Ha desbordado el timer0?
  45.                 desbtmr0++;        // Incremento su contador de desbordamientos.
  46.                 TMR0IF = 0;       // Bajo la bandera de desbordamiento.        
  47.             }  
  48.            
  49.             if (TMR1IF) {        // Ha desbordado el timer1?
  50.                 desbtmr1++;      // Incremento su contador de desbordamientos.
  51.                 TMR1IF = 0;      // Bajo la bandera de desbordamiento.          
  52.             }                                      
  53.                        
  54.         }
  55.        
  56.         // ¿Se han cumplido los 76 debordamientos del timer1?.
  57.  
  58.  
  59.         int16 resultado = (((int32)desbtmr0 * 256) + get_timer0()) / 1000;  // Genero variable para totalizar el numero de pulsos totales contados por el timer0.
  60.                                                                             // Para ello, como el timer0 desborda cada (255 + 1) pulsos, multiplico 256 * el numero de veces que ha desbordado.
  61.                                                                             // A ello le sumo el resto del ultimo valor que contiene el timer y obtenemos el numero de pulsos totales.
  62.                                                                             // Divido finalmente entre 1000 para eliminar los digitos que no necesito. Con 4 digitos es suficiente, me quedo
  63.                                                                             // los 4 digitos mas estables.
  64.  
  65.         led = 1;                   // Genero un parpadeo en cada transmisión que se efectúa.
  66.         printf("LEV");             // Envio el resultado enmascarado en una trama de control. Empieza con 3 bytes que contienen la palabra clave (LEV),
  67.         putc(make8(resultado,1));  // seguido de dos bytes que contienen el valor del nivel medido codificado en un entero simple en 16 bits, MSB primero,
  68.         putc(make8(resultado,0));  // LSB después.
  69.         putc('L' + 'E' + 'V' + make8(resultado,1) + make8(resultado,0)); // y cierro la trama con un checksum convencional.        
  70.         led = 0;          // Fin del parpadeo del led.
  71.  
  72.         // El receptor recibirá una trama cada 1 segundo. Para parsear la trama deberá leerla entera, identifica la palabra LEV, que servirá como control para saber que los dos siguientes
  73.         // bytes contienen el valor del nivel medido.  Por ultimo comprueba la suma de verificación checksum y si es válido procesa el valor.
  74.  
  75.         } // Fin de bucle de función.
  76. } // Fin de programa.
  77.                
  78.  
   
« Última modificación: 03 de Octubre de 2020, 15:09:54 por remi04 »

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 596
Re:Medidor capacitivo de nivel de combustible.
« Respuesta #1 en: 03 de Octubre de 2020, 13:36:32 »
.
« Última modificación: 03 de Octubre de 2020, 13:44:16 por remi04 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8136
Re:Medidor capacitivo de nivel de combustible.
« Respuesta #2 en: 04 de Octubre de 2020, 12:09:18 »
Muy bueno remi!

Te iba a preguntar algo, pero luego me di cuenta que estaba explicado en tu texto.

Pero se me ocurre otra cosa... de ponerle una capacidad en paralelo, aumentarías la capacidad y la frecuencia no debería ser menor ?
« Última modificación: 04 de Octubre de 2020, 12:15:12 por KILLERJC »

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 596
Re:Medidor capacitivo de nivel de combustible.
« Respuesta #3 en: 04 de Octubre de 2020, 12:25:19 »
Muy bueno remi!

Te iba a preguntar algo, pero luego me di cuenta que estaba explicado en tu texto.

Pero se me ocurre otra cosa... de ponerle una capacidad en paralelo, aumentarías la capacidad y la frecuencia no debería ser menor ?

 Hola Killer, gracias por tu respuesta.

  Si, pero se reduce muchísimo el ancho de acción. Es decir, con un 120 pf por ejemplo obtengo 250 Khz aprox, pero al poner la sonda, si lleno total son 250.000 hz,  vacío total son 249.970 y eso además muy bailón  y lo suficientemente inestable como para ser imposible plantearlo.

  El problema es que el tubo sonda parece que hace una capacitancia muy pequeña.  Por eso me da esa frecuencia.

 De todos modos está trabajando bastante bien de la forma que lo he planteado al final. Obtiene un buen rango y al poder prescindir de los dígitos de menos peso las lecturas son bastante estables.

Un saludo.
« Última modificación: 04 de Octubre de 2020, 12:28:26 por remi04 »

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 521
Re:Medidor capacitivo de nivel de combustible.
« Respuesta #4 en: 04 de Octubre de 2020, 12:57:48 »
...
  El problema es que el tubo sonda parece que hace una capacitancia muy pequeña.  Por eso me da esa frecuencia.
Podés usar en el oscilador una resistencia mayor para bajar la frecuencia, aunque lo mejor sería que el hilo central sea una barra (u otro tubo) con ~1mm de huelgo en el interior.

Citar
De todos modos está trabajando bastante bien de la forma que lo he planteado al final. Obtiene un buen rango y al poder prescindir de los dígitos de menos peso las lecturas son bastante estables.
Ni hablar, para un medidor de combustible no tiene sentido mas de 2 dígitos.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 596
Re:Medidor capacitivo de nivel de combustible.
« Respuesta #5 en: 04 de Octubre de 2020, 16:51:32 »
...
  El problema es que el tubo sonda parece que hace una capacitancia muy pequeña.  Por eso me da esa frecuencia.
Podés usar en el oscilador una resistencia mayor para bajar la frecuencia, aunque lo mejor sería que el hilo central sea una barra (u otro tubo) con ~1mm de huelgo en el interior.

Citar
De todos modos está trabajando bastante bien de la forma que lo he planteado al final. Obtiene un buen rango y al poder prescindir de los dígitos de menos peso las lecturas son bastante estables.
Ni hablar, para un medidor de combustible no tiene sentido mas de 2 dígitos.

  Si que había pensado también en eso. En aumentar la superficie del electrodo interior con otro tubo más pequeño que de ese huelgo.

  Lo de los dígitos, así es.  Me quedo con los justos que más estables sean y con dos o tres máximos es suficiente.