TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: splasma2 en 11 de Junio de 2012, 05:24:04

Título: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 11 de Junio de 2012, 05:24:04
Buenas a todos.

Estoy dandole vueltas a un proyecto nuevo relacionado con medidas de impedancias. La idea surgió después de leer un antiguo proyecto de Elektor del año 1997 "Advanced LCR meter".

Elektor pdf (https://docs.google.com/viewer?a=v&pid=sites&srcid=ZGVmYXVsdGRvbWFpbnxrbm9ob3dsY3JtZXRlcnxneDoxNDYyZTg2ZDRjYmVlODQy)

El objeto es diseñar un instrumento avanzado de medidas de L, C y R asi como otros parametros relacionados con estos componentes como el factor Q.
 
En lugar de usar el clásico metodo de contar la frecuencia de oscilación generada por un circuito donde se incluye el elemento a medir, este instrumento
estaría basado en la medida de impedancias en un puente compuesto por un impedancia de referecia y el elemento a medir, para obtener esta magnitud
el puente se excita con una onda sinusoidal de frecuencia conocida y se mide los valores de tensión y desplazamiento de fase en el puente.

Para hacer esto el proyecto de Elektor usaba un CI que generaba la onda con un DAC interno y luego obtenia el valor medido en el puente con un ADC incluido en el mismo CI.
No he conseguido suficientes detalles ( para migrarlo a un PIC18, dspPIC o PIC32) del proceso matemático posterior que permite obtener la medidas de L,C y R y factor Q y otros.

He encontrado otros proyecto similares que usan el mismo principio pero con poco detalle del algoritmo que usan ( http://www.pro-radio.ru/measure/4319/ en ruso... :?).

Tengo varias dudas iniciales:

   - Generación de la onda senosoidal : los ejemplo que he visto usan DAC de 14-16 bits, si uso un PIC necesito un DAC externo ( no quiero meterme en lios de DDS) ,
    no se si podré obtener una onda de 1Khz, 10 Khz o hasta 100 Khz con un PIC rápido y un DAC mediante SPI o I2C.
   - Que precision necesito en la amplitud de la ona generada y en su frecuencia para obtener medidas fiables ( digamos 1% de error ) ¿?
   - Relacionado con lo anterior, ¿ como de bueno tiene que ser el ADC para obtener esa  precisión ? puedo usar el ADC interno de un PIC (ya los hay 12 bits)

Bueno, no pongo más dudas porque me desanimo a mi mismo y lo doy por "imposible"   :(, con vuestra ayuda seguro que no será así. :)

Gracias a todos...
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 11 de Junio de 2012, 11:37:03
Es un proyecto interesante. Me apunto al hilo.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Suky en 11 de Junio de 2012, 12:16:09
Respecto al error de la amplitud y frecuencia, seguramente para calcular las impedancias estos valores se ingresan en una formula. Ahí se puede aplicar propagación de errores, de esa manera teniendo por ejemplo la amplitud con x%, la frecuencia con y% podes determinar con que % de error obtienes la medida. Luego a ese error pueden agregarse otros, que dependen de cada caso.

Saludos!
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 11 de Junio de 2012, 18:11:54
Creo que se puede intentar. Me conformo con mucho menos de lo que promete el artículo.

Rango de medidas:
R = 0.1 mOhm  ...  100 Mohm
L = 100 nH  ...   10 kH
C = 0.5 pF ...  10 mF
Q factor = 1 ... 1000

Exactitud 0.25% en gran parte del rango.

Tensión de test: 0.1 ... 1 voltio
Frecuencia de test: 1000 Hz
Tiempo de medida: 1.5 segundos


Yo puedo ayudar en la programación de las rutinas matemáticas.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 11 de Junio de 2012, 19:24:56
Buenas noticias  :mrgreen: :mrgreen:

Del foro ruso he sacado un esquema :

http://cqham.ru/image4/RLC_usb_big.png


y código que corre en un micro 8051F410, el calculo que hace se basa en la siguiente formula:



        Re_U + j*Im_U     Re_U*Re_I + Im_U*Im_I        ReI*Im_U - Re_U*Im_I
 Z =   --------------      = ----------------------------    + j -----------------------
         Re_I + j*Im_I     Re_I*Re_I + Im_I*Im_I          Re_I*Re_I + Im_I*Im_I




La parte Real e Imaginaria de U e I se calcula con un MAC de 48 bits, que se hace sobre una serie de muestras obtenidas en el ADC periodicamente.

Despues a partir de Z se obtiene los valores de R , C o L , lo malo es que parte del programa está en ensamblador, copio parte del codigo C extraido :

Código: [Seleccionar]
     

        tfloat=Re_I*Re_I+Im_I*Im_I;

      Real.F=R_Et*(Re_U*Re_I+Im_U*Im_I)/tfloat; // Calculate real part complex resistance
      Imag.F=R_Et*(Im_U*Re_I-Re_U*Im_I)/tfloat; // Calculate imaginery part complex resistance

      if (Real.F==0) Real.F=1.0E-38 ;

      Phase = atan(Imag.F/Real.F);
      if ((Real.F<0) && (Imag.F<0)) Phase-=Pi;
      if ((Real.F<0) && (Imag.F>=0)) Phase+=Pi;

      if (abs(Phase)<0.1){
        strcpy(LCD_Line,"R= ");
      } else {
        if (Phase > 0) {
          Real.F=1/(2*Pi*Frequency*Imag.F);      
          strcpy(LCD_Line,"C= ");
        } else {
          Real.F=Imag.F/(2*Pi*Frequency);
          strcpy(LCD_Line,"L= ");
        }
      }


Seguire investigando, si alguien se anima con el foro ruso...  :lol:  por el momento ya he hecho un pedido de samples de un PIC con ADC de 12 bits y un DAC (MPC4822) a nuestro amigo Microchip.


Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 12 de Junio de 2012, 03:05:29
He estado estudiando el esquema y creo que la base del sistema se basa en un lock-in amplifier.

Este amplificador lo que hace es multiplicar la señal de referencia (tensión senoidal) por la señal de corriente (otra onda senoidal desfasada).
El amplificador sólo amplifica la señal que tenga exactamente la misma frecuencia y fase. El resto de señales se elimina. Elimina el ruido de manera muy eficaz.
Para detectar el desfase multiplica la señal de entrada desfasada 90º (señal coseno) por la señal de corriente.

El amplificador lock-in está implementado dentro del microcontrolador y por eso tiene que ser tan rápido.

Dejo otro enlace de un miliohmetro que utiliza un sistema semejante, pero no detecta desfases y el amplificador está fuera del micro. Lo mejor de este artículo es que explica con detalle el funcionamiento:
http://cappels.org/dproj/dlmom/dlmom.html

Un amplificador Lock-in para el laboratorio:
http://orchard.uwaterloo.ca/Courses/Chem724/SimpleLockInAmplifier.pdf

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 12 de Junio de 2012, 10:22:25
Creo que si se puede hacer y es muy semejante a un proyecto que quería copiar de un medidor de miliohmios, pero más avanzado.

Esta nota de aplicación de Microchip explica como hacer un lock-in amplifier digital:
   Implementing Digital Lock-In Amplifiers Using the dsPIC DSC (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en532447)


Un Lock-in amplifier analógico casero, con ejemplos de aplicación y muchos enlaces:
Homebrew Lock-In Amplifier (http://blockyourid.com/~gbpprorg/mil/cavity/lock/index.html)

Presentación que explica el principio de los lock-in amplifiers:
Lock-in amplifiers (http://blockyourid.com/~gbpprorg/mil/cavity/lock/18-Lock-in-amplifiers.pdf)


Creo que sí se puede hacer el medidor LRC.


Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 12 de Junio de 2012, 14:07:06
Gracias Picuino por tu análisis y busqueda de información.

Seguire mirando el código C que consegui en el foro ruso   :mrgreen: porque creo que el esquema que adjunte no corresponde con ese software, encontre otro en ensamblador pero no me entero de "na" por que los comentarios están en ese bonito lenguaje desconocido que hablan nuestro amigos... :lol:.

Aparte de que el esamblador es de un PIC y el "C" de un 8051... otra diferencia que si he conseguido identificar es que el sofware C usa un DAC para generar la onda senoidal, pero en el código ensamblador parece que se usa una onda cuadrada generada mediante el CCP del PIC, por eso creo que se usa un filtro de segundo orden en el esquema, para sacar de ahi la senoidal.



Sin embargo el codigo de  la nota de microchip que pasate si parece similar al "software C".. supongo que la algoritmia que sigue un filtro lock-in y el procesamiento que se usa para calcular los valores LCR es similar... no sé... el principal problema que veo es el proceso de multiplicación y suma que hay que hacer con las muestras del ADC y la tabla seno y coseno... esto tiene que ser rápidito...

Por cierto, todo este software se puede sacar del foro ruso, hay que buscar, no tengo los links directos a mano.


Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 12 de Junio de 2012, 14:56:02
El funcionamiento es el siguiente:

Primero se genera una señal de tensión senoidal (se podría dedicar un pequeño pic a ello sin problema o un GAL)

Después se aplica la tensión a una impedancia desconocida y se mide la corriente.

Se convierte la corriente a señal digital con un DAC.

Se multiplica la señal de corriente por la señal seno y se van sumando los resultados.
Se multiplica la señal de corriente por la señal coseno (la misma señal seno pero desfasada 90º) y se van sumando los resultados.

Los dos valores anteriores son la parte real e imaginaria de la corriente  I = X + Y j

Ahora se puede calcular la impedancia como Z = V/I


En realidad los cálculos se complican un poco porque el puente de medida es un poco más complejo, pero la base del asunto es la que te he contado. Creo que se puede hacer hasta con un PIC16F. Depende de la precisión que quieras tener.

Saludos.

Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 12 de Junio de 2012, 16:12:54
Asi es, ese es el algoritmo que implementa el codigo C que tengo:

Código: [Seleccionar]
   Saved_ADC0=ADC1BUF0;
   Saved_Sin=Last_Sin;
   Saved_Cos=Last_Cos;

   // MAC48 !!!! En ensamblador
   //Real+=(Saved_ADC0*Saved_Sin); // Multiplay and acumulate Real Part
   //Imag+=(Saved_ADC0*Saved_Cos); // Multiplay and acumulate Im. Part

Esta parte está incluida en la rutina de interrupción del ADC, como ves aqui es donde se multiplica el valor leido del ADC por el seno y el coseno, pero hay una diferencia con lo que dices, primero se hace con V durante 0.5 segundos y después con I el mismo tiempo, es decir obtengo 2 numeros complejos V e I a partir de varias muestras, luego se divide por el numero de muestras y así se obtiene el primer valor de la formula que ya puse:


        Re_U + j*Im_U     Re_U*Re_I + Im_U*Im_I        ReI*Im_U - Re_U*Im_I
 Z =   --------------      = ----------------------------    + j -----------------------
         Re_I + j*Im_I     Re_I*Re_I + Im_I*Im_I          Re_I*Re_I + Im_I*Im_I



También veras que he marcado MAC48 ( Multiply -Accumulate ), aqui realmente se usa una rutina en ensamblador que maneja magnitudes de 48 bits.
Mi idea es migralo a ensamblador del PIC18F y ver que pasa....
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 12 de Junio de 2012, 17:14:09
Hay muchas formas de hacerlo dependiendo del puente que utilices. Todas son equivalentes.

Al final necesitas saber 2 números complejos V e I.
En mi explicación supongo V conocida y por eso no la mido.

También hay otros métodos que suponen V conocida con dos valores y miden dos valores de I para poder eliminar el error de offset, etc.

En el proyecto que presentaste al comienzo parece que se conoce V_total y se mide la tensión que sale de un divisor de tensión en el que una impedancia es conocida y la otra no.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: nZeta en 14 de Junio de 2012, 01:05:57
Talvez te interece ver los videos de PSOC Today Episodios  2 a 5 que tratan de Synchronous Detection, en el ep 5 muestran que como se puede usar para crear un RLC.
http://www.cypress.com/?rID=60521
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 14 de Junio de 2012, 09:21:36



Gracias por la info, nZeta, les echare un vistazo...

Sigo avanzando con esto, conseguí un codigo en ensamblador que hace un MAC de 48 bits rapidito, lo que necesitaba para poder ponerlo en la rutina de interrupción.

Lo he estado probando ( desde C llama a la rutina en ensamblador) y parece que va bien, la prueba consiste en ir pasandole al MAC datos sacados de dos arrays de 96 valores
que forman una onda seno y coseno completa.

Hay un detalle que me llama la atención: si en el MAC introduzo un seno y un coseno es decir ejecuto el siguiente proceso : mac = mac + ( sin(x) * cos(x) )
el resultado despues de un numero entero de ciclos simpre en 0, es aritmetica con signo , lo cual parece correcto.

Sin embargo si en el MAC introduzco 2 senos , es decir :  mac = mac + ( sin(x) * sin(x) ) el resultado, como parece obvio va creciendo con el numero de ciclos .

Esta prueba corresponderia con el siguiente escenario real:

una impedancia Z que sería una R pura, es decir sin componentes L y C excitado por una funcion seno.

con el algoritmo que indicó Picuino :


Se multiplica la señal de corriente por la señal seno y se van sumando los resultados.
Se multiplica la señal de corriente por la señal coseno (la misma señal seno pero desfasada 90º) y se van sumando los resultados.

Los dos valores anteriores son la parte real e imaginaria de la corriente  I = X + Y j

Ahora se puede calcular la impedancia como Z = V/I



una de las componentes , la imainaria sería 0, correcto,  pero  la parte real  al estar las 2 señales en fase, iria creciendo indefinidamente, ¿ es esto correcto ?

supongo que si, ya que al final el valor que se obtiene después de N ciclos se divide por N, pero me llama la atención...
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 14 de Junio de 2012, 10:47:27
Se supone que la operación mac la realizas sobre un número finito de samples (por ejemplo 16000)

Si quieres sacar una señal continua, como hace un lock-in amplifier, tienes que aplicar un filtro paso bajos.

Hay muchas maneras de implementarlo. Una de ellas sería un filtro exponencial de orden uno:

   mac = (255 * mac  +  1* (sen[t] * i[t])) / 256


Los números multiplicadores tienen que sumar 256 para que funcione. Cuanto mayor sea el primer multiplicador, mas despacio responde el filtro. Los números están escogidos para que sea muy rápido realizar la multiplicación y la división (con un desplazamiento de 8 bit y una resta se multiplica por 255 y con un desplazamiento de 8 bit se divide por 256, todo muy rápido con el barrel shifter)

A propósito, creo que no necesitas tanta precisión. Con 16 bit para empezar creo que es suficiente.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 14 de Junio de 2012, 11:21:56
Gracias Picuino,

Probare a incluir el filtro que me indicas en la rutina en ensamblador    :?  que calcula el MAc de 48 bits... a ver como se comporta

La prueba la hice con 500x96 muestras y cada muestra es de 12 bits ( es decir el n. de bits del ADC del PIC que quiero usar) la anchura en bits del resultado de MAC tiene que ser grande , por eso  48 bits, realmente el codigo que estoy usando  esta pensado para un MAC de 16x16, pero... mejor que sobre... :mrgreen:
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 14 de Junio de 2012, 16:14:41
500x96 = 48000 = 16 bits
16 bits + 12 bits = 28 bits.

Esto es de forma ideal, en la práctica las señales se cancelan entre sí.

Además está el problema de que de los 48 bits que calculas, 38 bits son directamente ruido que puedes eliminar.

Y también la mayoría de las sumas positivas se cancelarán con las sumas negativas.

48 bits está bien para las pruebas, pero piensa que al final con 16 bits vas a tener una resolución más que suficiente (0.0015% ó 15ppm)

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 15 de Junio de 2012, 07:32:54
Si, el proceso es casi como dices:

Auque uso un ADC de 12 bits , el resultado lo almaceno en un "signed int", y la señal seno o coseno de referencia tambien ,por lo que al final el proceso de multiplicación del MAC es:

16 x 16 => 32 bits

si a esto le sumamos bits extras debidos al proceso acumulativo, podría llegar a usar los 48 bits....

En las pruebas que estoy haciendo con 500 muestras no paso de magnitudes que necesiten más de 36 bits , pero como ya comenté, el código que uso está preparado para 48 bits, asi que ... me sobra espacio  ;-)

Luego, como dices habrá que ver que parte es útil.

Ahora estoy probando el control y carga del DAC externo para generar la señal senoidal de referencia... mi problema va a ser que con un PIC a 40 Mhz y 96 muestras por ciclo  no podré pasar de 1000 Hz.  :(
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 15 de Junio de 2012, 13:39:59
Podrías comenzar por usar 16 muestras por ciclo y generar la tensión de salida con 4 pines del microcontrolador (sólo 4 bits) y una escalera de resitencias R-2R.

A la hora de multiplicar el seno por la señal de entrada de 12 bits tendrías un resultado válido de 16 bits como máximo.

Seguro que se pueden lograr buenas precisiones.

Adjunto una simulación:
   Salida senoidal de 1khz, 16 puntos por ciclo y resolución de 4 bits
   Entrada muestreada a 16khz y 10bits con
   Ruido del 25% del valor de la señal de entrada
   Tiempo de muestreo: 0.1 segundos
   Error máximo del 1%

Simulación Lock-in (https://sites.google.com/site/picuino/lock-in_amplifier/Digital_Lock-in_simulation.zip)

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 15 de Junio de 2012, 20:22:49
Uhmm, parece que con pocos bits también  puede dar buenos resultados, probare con un  18F26K22 que trae un DAC integrado de 5 bits.
Gracias
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 15 de Junio de 2012, 20:25:10
Un post de regalo, para pasar de categoria...   :mrgreen:
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: PFER90 en 16 de Junio de 2012, 01:36:16
Hola, Para generar la onda senoidal de referencia se podría usar un DDS, el ad9833, andan muy bien y son fáciles de configurar, se pueden conseguir frecuencias con un paso de 0.1Hz
saludos
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 17 de Junio de 2012, 11:19:38
Un conversor digital-analógico muy sencillo (sólo necesita 19 resistencias smd acopladas a 6 salidas digitales del PIC):
http://www.todopic.com.ar/foros/index.php?topic=38627.msg321612#msg321612


Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 19 de Junio de 2012, 18:40:56
Hola, Para generar la onda senoidal de referencia se podría usar un DDS, el ad9833, andan muy bien y son fáciles de configurar, se pueden conseguir frecuencias con un paso de 0.1Hz
saludos

Gracias por el apunte, pero para realizar el calculo del coseno/seno que me da la parte real/imaginaria de la impedancia Z necesito los valores instantaneos (fase) de la onda senoidal que uso para excitar dicha impedancia, con una onda generada externamente con un DDS desconozco ese dato (fase en tiempo real).

Si se pudiera hacer  me vendría de maravilla porque con el DAC externo que uso, con la simulación Proteus (PIC 18F26K22 a 48Mhz escribiendo en un MPC4822 DAC 12 bits) no paso de 600Hz.

Siguiendo el consejo de Picuino,  tengo que probar con menos bits con DAC hecho a mano R-2R  ;-) o DAC interno de 5 bits...
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 19 de Junio de 2012, 19:06:43
Voy a probar con este que me acabo de hacer (6bits):

https://sites.google.com/site/picuino/dac_r2r

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 23 de Junio de 2012, 16:51:36
He estado probando el conversor y funciona bastante bien.

Con un PIC18F2550 he generarado una senoidal de 1000Hz de 32 puntos,
En cada ciclo (32000 por segundo) se toman datos de una entrada analógica con el conversor Analógico-Digital configurado para leer 8 bit de resolución.
Después se multiplica la señal de entrada por la señal seno y por la señal coseno y se almacena la suma total.

Todo esto en tiempo real, de forma que se puede sumar en un segundo 32000 muestras.

La precisión que se consigue es bastante buena. El error es más o menos 20ppm, es decir +-0.002%


El problema que encuentro ahora es el de interpretar los datos. Todas las señales son positivas (tienen offset) y no se cómo interpretar los datos de salida.

Por ejemplo la señal senoidal oscila entre 0 y 252, de manera que se han añadido 126 puntos para que no sea negativa.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 23 de Junio de 2012, 16:59:32
Estos son los datos que obtengo al aplicar la señal senoidal a un condensador de 33nF con una resistencia en serie de 3300 ohmios (el generador DAC tiene una impedancia de 2200 ohmios):

Tensión de salida: aplicada al condensador
Tensión de entrada: tomada entre el condensador y la resistencia.
El otro pin de la resistencia está conectado a masa.

Número de muestras: 32*1024 = 32768
Promedio de la tensión de entrada: 104,70120 puntos

Suma de las tensiones de entrada = 3430921
Suma de la tensión de entrada por el seno = 660932821
Suma de la tensión de entrada por el coseno = 339144227


    [ DAC Vout ]>-------| |-----------/\/\/\-----------|Gnd
     Rout=2200         C=33nF    |    R=3300
                                 |
    [  Vin     ]<-----------------  

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 24 de Junio de 2012, 04:05:30
Creo que ya lo tengo.

A las sumas totales hay que restarles el producto de las medias:


v_in = tensión de entrada
seno = valores asignados al conversor Digital-Analógico para que produzca una señal de tensión senoidal de salida
coseno = valores de la función seno desfasados 90º
muestras = número de muestras tomadas de tensión de entrada. Numero de sumatorios realizados.


Sum_vin        = Sum(v_in)
Sum_seno       = Sum(seno)
Sum_vin_seno   = Sum(v_in * seno)
Sum_vin_coseno = Sum(v_in * coseno)


X = Sum_vin_seno - Sum_vin * Sum_seno / muestras
Y = Sum_vin_coseno - Sum_vin * Sum_coseno / muestras

Angulo = atan(X/Y)


Me falta calcular el módulo.

Saludos
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 25 de Junio de 2012, 04:55:37
Muy buen trabajo Picuino... :)

Yo ya he recibido el DAC de 12 bits, por lo que me pondré a probar la opción "pija", así podremos comparar resultados y ver si  la aproximación sencilla que estás desarrollando es suficiente para un usuario normal...

El principal problema que tengo es que no podré llegar a mas de 1 Khz con 96 puntos... pero como tu estás probando con 32 puntos @ 1KHZ, veremos si merece la pena aumentar la resolución en bits y muestras/seg.

Una pregunta , ¿ estás usando un filtro anti-image o anti-aliasing, detras del DAC para eleminar las frecuencias imagen generadas por la cuantificacion..? yo pensaba poner un simple filtro RC tras el DAC, pero eso produce desplazamiento de fase que desvirtua la señal de excitación.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 25 de Junio de 2012, 07:26:11
No utilizo nada y consigo precisiones de +-20ppm (a mi por ahora me basta)
Lo estoy desarrollando con un PIC18F, pero tengo un dsPIC que probaré cuando compruebe que esto va bién.
En principio quiero experimentar para conseguir un 1% de precisión en un rango grande de RLC, con un procesador sencillo.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 25 de Junio de 2012, 07:28:29
yo pensaba poner un simple filtro RC tras el DAC, pero eso produce desplazamiento de fase que desvirtua la señal de excitación.

Luego puedes restar la fase con cálculos.
Creo que la mejor opción para medir con precisión es colocar dos impedancias: una conocida y otra desconocida y luego compararlas para hallar el valor de la desconocida. Así consigues eliminar errores de offset como el desplazamiento de fase que comentas.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 25 de Junio de 2012, 07:59:37

Citar

Luego puedes restar la fase con cálculos.



Si, eso pensaba hacer con un proceso inicial de calibrado,  pero queria ver si me podia evitar ese "apaño", dejando la salida del DAC sin filtrar. En todos los esquemas que he encontrado relacionados con esto siempre aparecen filtros de 2 orden o más, supongo que es importante tener una señal limpia para conseguir exactitud en la medida, yo ire a minimos:  una RC y a ver que pasa.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 25 de Junio de 2012, 13:00:24
Ten en cuenta que para una señal de 1KHz con 32 pasos, el ruido comienza en 32KHz y tiene una amplitud de 1.5% de la onda principal.

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 12 de Julio de 2012, 09:41:34
Empiezo a conseguir los primeros resultados.
La función seno y coseno para multiplicar no debe tener componente continua (sumando todos los valores del ciclo debe resultar cero). En caso contrario los cálculos dan problemas.

La señal de entrada puede tener componente continua porque desaparece con los cálculos. Lo que no se es si merece la pena disminuir la continua lo máximo posible para mejorar la precisión.


Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 04 de Diciembre de 2012, 18:02:03
Tengo un esquema funcionando que puede medir impedancias (Z) con una resolución de 1 miliohmio y un rango de 2 ohmios.

Cambiando la ganancia del amplificador de instrumentación, puede medir rangos de resistencias más altas y capacidades más bajas.

Adjunto esquema con el que estoy trabajando

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=38565.0;attach=19788;image)


Saludos
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 04 de Diciembre de 2012, 18:17:36
Adjunto programa con el que estoy trabajando.
Con el PIC18F2550 a 48Mhz no he tenido problemas de velocidad.
Se puede multiplicar la lectura del ADC por el valor del seno y por el valor del coseno con 4 instrucciones de multiplicación de tipo byte muy rápidas (4 ciclos de reloj cada una).


Código: [Seleccionar]
/****************************************************************************
    LOCK-IN DIGITAL AMPLIFIER
    IMPEDANCE METER


    License:
    ========
    Creative Commons Reconocimiento-CompartirIgual 3.0 España License.
    Work title: Picuino C Library
    Attribute work to name: Picuino
    Attribute work to URL: https://sites.google.com/site/picuino

    THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
    WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
    TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. NOBODY SHALL,
    IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
    CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

 ****************************************************************************/


/****************************************************************************
      GLOBAL INCLUDE AND DEFINITIONS
 ****************************************************************************/
#include <p18cxxx.h>
#include <stdio.h>
#include <math.h>

#include "rs232.h"
#include "configuration.h"

static unsigned char isr_ticks, isr_go, phi;

/*
  Seno(x) adaptado a un byte para la multiplicación
  sen[n] = int(127.5 + 127*sen(n*2*pi/32))
  Promedio = 127
*/
#define DC     127
#define seno_0   0
#define seno_1  25
#define seno_2  49
#define seno_3  71
#define seno_4  90
#define seno_5 106
#define seno_6 117
#define seno_7 125
#define seno_8 127
const unsigned char seno[] = {
   DC + seno_0, DC + seno_1, DC + seno_2, DC + seno_3, DC + seno_4, DC + seno_5, DC + seno_6, DC + seno_7,
   DC + seno_8, DC + seno_7, DC + seno_6, DC + seno_5, DC + seno_4, DC + seno_3, DC + seno_2, DC + seno_1,     
   DC - seno_0, DC - seno_1, DC - seno_2, DC - seno_3, DC - seno_4, DC - seno_5, DC - seno_6, DC - seno_7,
   DC - seno_8, DC - seno_7, DC - seno_6, DC - seno_5, DC - seno_4, DC - seno_3, DC - seno_2, DC - seno_1,
};

const unsigned char coseno[] = {
   DC + seno_8, DC + seno_7, DC + seno_6, DC + seno_5, DC + seno_4, DC + seno_3, DC + seno_2, DC + seno_1,     
   DC - seno_0, DC - seno_1, DC - seno_2, DC - seno_3, DC - seno_4, DC - seno_5, DC - seno_6, DC - seno_7,
   DC - seno_8, DC - seno_7, DC - seno_6, DC - seno_5, DC - seno_4, DC - seno_3, DC - seno_2, DC - seno_1,
   DC + seno_0, DC + seno_1, DC + seno_2, DC + seno_3, DC + seno_4, DC + seno_5, DC + seno_6, DC + seno_7,
};


// sen[n] para producir una tensión de salida en el puerto B Conversor R-2R de 6 bits
// 0 - 63
const unsigned char seno_port[] =
/* {
   104, 124, 144, 160, 176, 192, 200, 208,
   208, 208, 200, 192, 176, 160, 144, 124,
   104,  84,  64,  48,  32,  16,   8,   0,
     0,   0,   8,  16,  32,  48,  64,  84,
}; */
{
   124, 148, 172, 192, 212, 228, 240, 244,
   248, 244, 240, 228, 212, 192, 172, 148,
   124, 100,  76,  56,  36,  20,   8,   4,
     0,   4,   8,  20,  36,  56,  76, 100,
};

/****************************************************************************
      INTERRUPT SERVICE ROUTINE
 ****************************************************************************/

#pragma interrupt isr_low_main
void isr_low_main(void) {
   // Timer2 interrupt counter
   if (PIR1bits.TMR2IF == 1) {
      PIR1bits.TMR2IF = 0;
      if (--isr_ticks==0) {
         isr_ticks = 3;
         isr_go = 1;

         // Compute next output signal
         phi++;
         phi &= 0x1F;
         PORTB = seno_port[phi];         

         // ADC Hold and Start Analog-Digital conversion
         ADCON0bits.GO = 1;
      }
   }
}

#pragma code high_vector=0x08
void isr_high(void) {
   _asm GOTO isr_low_main  _endasm
}

#pragma code low_vector=0x18
void isr_low(void) {
   _asm GOTO isr_low_main  _endasm
}


/****************************************************************************
      PROGRAM FUNCTIONS
 ****************************************************************************/

#pragma code

/*
   Timer 2 configure and reset
*/
void timer2_init(void) {
   TMR2 = 0;
   T2CON = (unsigned char)
          (0<<3)    // postscaler
                    // 0 = 1:1 postscaler
                    // 1 = 1:2 postscaler
                    // 15 = 1:16 postscaler
         +(1<<2)    // TMR2ON: 1 = Timer2 is on
         +(0b00);   // T2CKPS: Timer2 Clock Prescale Select bits
                    // 1x = 1:16 Prescaler value
                    // 01 = 1:4 Prescaler value
                    // 00 = 1:1 Prescaler value
   PR2 = 124;       // PWM Period = [(PR2) + 1] • TCY •(TMR2 Prescale Value)]
   PIR1bits.TMR2IF = 0;
   PIE1bits.TMR2IE = 1;
   IPR1bits.TMR2IP = 0;
}


/*
   Init ADC
   Select input pin to sample and hold circuit
*/
void adc_init(unsigned char channel) {
   // Configure ADC
   ADCON0 = 0b00000001 + (channel<<2);   // ADC on. Select channel
   ADCON1 = 0b00000000;   // Analog inputs
   ADCON2 = (unsigned char)
          (1<<7)    // ADFM: 0 = Result Left justified
         +(2<<3)    // ACQT2: A/D Acquisition Time
                    // 7 = 20 Tad
                    // 6 = 16 Tad
                    // 5 = 12 Tad
                    // 4 = 8 Tad
                    // 3 = 6 Tad
                    // 2 = 4 Tad
                    // 1 = 2 Tad
                    // 0 = 0 Tad
         +(6);      // ADCS2: A/D Conversion Clock
                    // 7 = Frc
                    // 6 = Fosc/64
                    // 5 = Fosc/16
                    // 4 = Fosc/4
                    // 3 = Frc
                    // 2 = Fosc/32
                    // 1 = Fosc/8
                    // 0 = Fosc/2

}


/* Print float number with sign */
void print_float(static float num) {
   if (num<0)
      printf ("-%lu\t", (long)-num);
   else
      printf ("%lu\t", (long)num);
}

/* Compute modulo of a vector */
float modulo(static float x, static float y) {
   return sqrt(x*x + y*y);
}


/* Compute angle of a vector */
float angle(static float x, static float y) {
   if (x == 0) {
      if (y > 0) return  3.141592654/2.0;
      else       return -3.141592654/2.0;
   }
   return atan(y/x);
}


/****************************************************************************
      MAIN PROGRAM
 ****************************************************************************/

void main(void) {
   static float Vz_re, Vz_im, Vz_mod, Vz_phi;
   static float Vr_re, Vr_im, Vr_mod, Vr_phi;
   static float Z_re, Z_im, Z_mod, Z_phi;
   static unsigned char sen, cos;
   static unsigned int counter, samples;
   static long seno_mul_sum, seno_mul_sum2;
   static long coseno_mul_sum, coseno_mul_sum2;
   static long vin_sum;
   static union {
      unsigned int word;
      struct {
          unsigned char lob;
          unsigned char hib;
      };
   } mul, vin;

   // Peripheral config
   TRISB = 0b00000011;     // Digital to Analog output
   TRISA = 0b11111111;
   rs232_init();
   adc_init(ANALOG_RA0_CHANNEL);
   timer2_init();

   // Interrupt config
   RCONbits.IPEN = 0;
   INTCONbits.GIE = 1;
   INTCONbits.PEIE = 1;

   rs232_puts("System OK\n");

   samples = 32*1024;

   // Main loop
   while(1) {
      counter = samples;
      seno_mul_sum = seno_mul_sum2 = 0;
      coseno_mul_sum = coseno_mul_sum2 = 0;
      vin_sum = 0;

      TRISCbits.TRISC0 = 0;

      // wait first step and read ADC
      while(phi!=0);
      while(ADCON0bits.GO == 1);
      vin.lob = ADRESL;
      vin.hib = ADRESH;

      // Compute 32*1024 samples
      do {

         // wait next step
         isr_go = 0;
         while(isr_go==0);

         // Compute sen, cos and Increment pointers
         sen = seno[phi];
         cos = coseno[phi];

         // Lock-in detector
         vin_sum += vin.word;

         // Compute Vin * sen
         mul.lob = vin.lob * sen;
         mul.hib = PRODH;
         seno_mul_sum += (unsigned long)mul.word;

         mul.lob = vin.hib * sen;
         mul.hib = PRODH;
         seno_mul_sum2 += (unsigned long)mul.word;

         // Compute Vin * cos
         mul.lob = vin.lob * cos;
         mul.hib = PRODH;
         coseno_mul_sum += (unsigned long)mul.word;

         mul.lob = vin.hib * cos;
         mul.hib = PRODH;
         coseno_mul_sum2 += (unsigned long)mul.word;

         // Read Analog-Digital conversion
         while(ADCON0bits.GO == 1);
         vin.lob = ADRESL;
         vin.hib = ADRESH;

      } while(--counter);

      // Add low mul and high mul
      seno_mul_sum += seno_mul_sum2<<8;
      coseno_mul_sum += coseno_mul_sum2<<8;
   
      // Compute X,Y components without DC
      Vz_re = seno_mul_sum - (vin_sum*127);
      Vz_im = coseno_mul_sum - (vin_sum*127);
 
      // print results
      printf ("\r\n");
      #define VZ_CORRECTION    0.99099*0.9875
      Vz_re *= VZ_CORRECTION*2.0*5.0/(1024.0*127.0*32.0*1024.0*1.41421);
      Vz_im *= VZ_CORRECTION*2.0*5.0/(1024.0*127.0*32.0*1024.0*1.41421);   
      Vz_phi = angle(Vz_re, Vz_im)-(16.780*3.1415927/180.0);
      Vz_mod = modulo(Vz_re, Vz_im);
      Vz_re = Vz_mod * sin(Vz_phi+1.570796327);
      Vz_im = Vz_mod * sin(Vz_phi);
      //printf ("Vz_re=\t");   print_float(Vz_re*10000.0);
      //printf ("Vz_im=\t");   print_float(Vz_im*10000.0);
      printf ("Vz_mod=\t");  print_float(Vz_mod*1000.0);
      printf ("Vz_phi=\t");  print_float(Vz_phi*(1000.0*180.0/3.1415927));

      Vr_re = 0.8002 - Vz_re;
      Vr_im = 0.0000 - Vz_im;
      Vr_mod = modulo(Vr_re, Vr_im);
      Vr_phi = angle(Vr_re, Vr_im);
      printf ("Vr_mod=\t");  print_float(Vr_mod*1000.0);
      printf ("Vr_phi=\t");  print_float(Vr_phi*(1000.0*180.0/3.1415927));

      Z_mod = 990.0 * Vz_mod / Vr_mod;
      Z_phi = Vz_phi - Vr_phi;
      Z_re = Z_mod * sin(Z_phi+1.570796327);
      Z_im = Z_mod * sin(Z_phi);

      //printf ("Z_mod=\t");   print_float(Z_mod*10.0);
      //printf ("Z_phi=\t");   print_float(Z_phi*(100.0*180.0/3.1415927));
      printf ("R=\t");       print_float(Z_re*10.0);
      printf ("Zc=\t");      print_float(Z_im*10.0);
     
      Z_im = 1000000000.0/(6283.1853*Z_im);
      printf ("C[nF]=\t");      print_float(Z_im);

   }
}

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 04 de Diciembre de 2012, 19:00:46
Los amplificadores operacionales y de instrumentación utilizados son de Microchip.
Tienen una tensión de alimentación de 5V con entradas y salidas Rail to Rail, que significa que pueden ir desde cero a 5 voltios.
Funcionan bastante bien, son baratos (gratuitos en caso de pedirles como samples) y no necesitan utilizar una fuente de alimentación simétrica.

Amplificador de instrumentación MCP6N11: http://ww1.microchip.com/downloads/en/DeviceDoc/25073A.pdf

Amplificadores operacionales MCP6L92: http://ww1.microchip.com/downloads/en/DeviceDoc/22141b.pdf


Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: splasma2 en 14 de Diciembre de 2012, 12:02:58
Estupendo trabajo Picuino, yo lo deje abandonado....  :oops: pero veo que tú lo conseguiste.

Una duda, las resitencias son de precisión (1%) o no influyen en la medida ???

Saludos,

Repito, magnifico resultado. ;-)

Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 15 de Diciembre de 2012, 20:07:56
Todavía no lo he conseguido.
Estoy esperando poder pedir más samples de Microchip para completar el circuito.
Por las pruebas que he realizado hasta ahora, si he comprobado que se puede hacer.

Cuando tenga más avances los postearé. La herramienta me parece increíble.

Con este aparato puedes medir resistencias desde un miliohmio hasta cientos de megaohmios, puedes medir la resistencia en serie de condensadores, la resistencia serie equivalente de una pila, inductancias, capacidades.
Parece el medidor perfecto de impedancias. Por ahora tengo la intención de seguir con ello hasta que lo consiga.


Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: Picuino en 15 de Diciembre de 2012, 20:13:41
Una duda, las resitencias son de precisión (1%) o no influyen en la medida ???

No estoy utilizando resistencias de precisión, pero en el aparato final si que se tendrán que utilizar.

El valor de la resistencia R1 no es muy importante porque hay que calibrar el instrumento y cualquier desviación se puede corregir. El problema es que R1 varíe con la temperatura o con el tiempo, porque el aparato necesitaría continuamente calibración. Por eso se deben utilizar resistencias muy precisas (0.1% en el caso del circuito de Elektor)

En mi caso, utilizaré resistencias smd del 1%  (me conformo con esa exactitud)

Saludos.
Título: Re: Medidor avanzado LCR ( se puede hacer??)
Publicado por: sirias52 en 19 de Diciembre de 2012, 03:42:35
Siguiendo el Hilo, muy interesante Picuino y te felicito por no dejar atras este interesante proyecto.