TODOPIC

Otros Microcontroladores / Dispositivos programables => ** PROYECTOS ** => Mensaje iniciado por: Picuino en 06 de Mayo de 2012, 17:39:33

Título: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 06 de Mayo de 2012, 17:39:33
Hace tiempo que voy añadiendo características a un frecuencímetro casero que estoy desarrollando.
La motivación para hacer otro frecuencímetro más (Yet Another Freqmeter) con la cantidad de frecuencímetros que ya hay desarrollados fue conseguir un aparato de mucha resolución tanto en altas como en bajas frecuencias.
La resolución en bajas frecuencias es más difícil de conseguir con los aparatos habituales. Cuando me plantee por primera vez "afinar" un oscilador de 32768 Khz me di cuenta de que la mayoría de los frecuencímetros "baratos" dan la lectura:
32768 con error de +-1.
Eso significa un error de +-30 ppm en el mejor de los casos. Un reloj basado en ese oscilador tendrá un error de 80 segundos al mes, que es un poco alto.

El objetivo en este proyecto es que el frecuencímetro muestre 7 cifras significativas sin error y una cifra más con un error acotado de +-5:

   1.0000000 Hz frecuencia nominal mínima admitida por el frecuencímetro.
   50.000000 Hz frecuencia de red
   32768.000 Hz frecuencia de un oscilador de cristal de bajo consumo
   4000000.0 Hz frecuencia de un oscilador de cristal de 4Mhz
   50000000. Hz frecuencia nominal máxima admitida por el frecuencímetro

El microcontrolador a utilizar será un PIC18F2550 programado en C18 con el mínimo número de librerías para que sea más portable.
La entrada a utilizar será la RC0 / T13CKI, sin preamplificación.
El amplificador, atenuador y divisor de frecuencias para dar mayor rango de medición lo dejaré para otro proyecto.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Suky en 06 de Mayo de 2012, 19:44:57
Lo que quieres lograr es más que interesante. Que instrumento usas para contrastar para todo ese rango?
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 06 de Mayo de 2012, 20:13:18
Utilizo un frecuencímetro chino VC3165 como referencia para conseguir una señal exacta.
Genero una señal cuadrada con un generador de funciones DDS a una frecuencia exacta de 1048576.0Mhz (2^20 Hz).
Esa frecuencia la voy dividiendo por dos con varios integrados hasta conseguir 1Hz y esas son las frecuencias que testeo en el frecuencímetro que estoy construyendo.

Por ahora la medición tiene errores sistemáticos debido al oscilador de cristal de la placa del PIC (afinado con error de 1ppm).

El frecuencímetro será tan exacto como lo sea el oscilador que tenga el PIC. Si utilizo un cuarzo de 100ppm esa será la exactitud. Si utilizo un oscilador externo OCXO puedo llegar a 0.1ppm.
Lo que me interesa por ahora es crear el programa que sea preciso y exacto. Del oscilador me ocuparé más adelante.


http://electronicsjunk.com/index.php?option=com_content&view=article&id=55:victor-vc3165-frequency-counter&catid=34:electronics&Itemid=59
http://asterion.almadark.com/wp-content/uploads/2011/05/vc3165.pdf


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: todopic en 06 de Mayo de 2012, 21:24:08
Estoy atento al tema...  muy interesante ...
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Nocturno en 07 de Mayo de 2012, 02:06:30
Me suscribo al hilo.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 07 de Mayo de 2012, 18:08:12
Sigo peleándome con las rutinas matemáticas. Ya me falta poco.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: MLO__ en 07 de Mayo de 2012, 19:52:09
Hola

Esta muy interesante!!! me suscribo al hilo tambien  :)

Saludos
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 07 de Mayo de 2012, 20:36:04
Primeros resultados. Las rutinas matemáticas parecen funcionar bien con 12 dígitos de precisión:


System OK

Time=   000000010000037   Pulses=   000000010000054   freq=   005000009,02586
Time=   000000020031617   Pulses=   000000020031652   freq=   005000008,97166
Time=   000000030000024   Pulses=   000000030000077   freq=   005000009,02851
Time=   000000040011031   Pulses=   000000040011103   freq=   005000009,48954


El tiempo está medido en ciclos de instrucción (5 millones por segundo para un oscilador de 20Mhz)

Los pulsos provienen de un oscilador de 5MHz.

La frecuencia se calcula como la diferencia entre pulsos dividido entre la diferencia entre tiempos.

Se puede ver como bailan los números a partir de  0.1ppm = 0.5 Hz

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 07 de Mayo de 2012, 20:40:52
Código para manejar aritmética de 48 bits:


math48.c
Código: C
  1. /****************************************************************************
  2.     48 bit integer math
  3.  
  4.    Picuino Development Board
  5.    Creative Commons Reconocimiento-CompartirIgual 3.0 España License.
  6.    https://sites.google.com/site/picuino
  7.    
  8.  ****************************************************************************/
  9. #include "math48.h"
  10.  
  11. /****************************************************************************
  12.       GLOBAL VARS AND DEFINITIONS
  13.  ****************************************************************************/
  14.  
  15. // Variable for store answer and status register
  16. static uint48 ans;
  17. static struct {
  18.     unsigned char carry:1;
  19.     unsigned char overflow:1;
  20. } st48;
  21.  
  22.  
  23. /****************************************************************************
  24.       BASIC MATH ROUTINES
  25.  ****************************************************************************/
  26. /*
  27.    Compare 2 uint48 numbers
  28.    (a = b) return 0
  29.    (a > b) return 1
  30.    (a < b) return -1
  31. */
  32. signed char comp48(uint48 a, uint48 b) {
  33.    if (a.dword > b.dword) return 1;
  34.    if (a.dword < b.dword) return -1;
  35.    if (a.word[0] > b.word[0]) return 1;
  36.    if (a.word[0] < b.word[0]) return -1;
  37.    return 0;
  38. }
  39.  
  40.  
  41. /*
  42.    Sub 2 uint48 numbers
  43.    return a - b
  44. */
  45. uint48 sub48(uint48 a, uint48 b) {
  46.    ans.dword = a.dword - b.dword;
  47.    if (b.word[0] > a.word[0])
  48.       ans.dword--;
  49.    ans.word[0] = a.word[0] - b.word[0];
  50.    return ans;
  51. }
  52.  
  53. /*
  54.    Add 2 uint48 numbers
  55.    return a + b
  56. */
  57. uint48 add48(uint48 a, uint48 b) {
  58.    ans.dword = a.dword + b.dword;
  59.    ans.word[0] = a.word[0] + b.word[0];
  60.    if (ans.word[0] < a.word[0])
  61.       ans.dword++;
  62.    return ans;
  63. }
  64.  
  65. /*
  66.    Add 2 uint48 numbers
  67.    return a + b
  68. */
  69. uint48 inc48(uint48 a) {
  70.    ans.word[0] = a.word[0] + 1;
  71.    ans.dword = a.dword;
  72.    if (ans.word[0] == 0)
  73.       ans.dword++;
  74.    return ans;
  75. }
  76.  
  77.  
  78. /*
  79.    Rotate left
  80.    return a<<1
  81. */
  82. uint48 _rl48(uint48 a) {
  83.    st48.carry = 0;
  84.    if (a.b47==1) st48.carry = 1;
  85.    ans.dword = a.dword<<1;
  86.    if (a.b15==1) ans.b16 = 1;
  87.    ans.word[0] = a.word[0]<<1;
  88.    if (st48.carry == 1)
  89.       ans.b0 = 1;
  90.    return ans;
  91. }
  92.  
  93. /*
  94.    Rotate right
  95.    return a>>1
  96. */
  97. uint48 _rr48(uint48 a) {
  98.    st48.carry = 0;
  99.    if (a.b0==1) st48.carry = 1;
  100.    ans.word[0] = a.word[0]>>1;
  101.    if (a.b16==1) ans.b15 = 1;
  102.    ans.dword = a.dword>>1;
  103.    if (st48.carry == 1)
  104.       ans.b47 = 1;
  105.    return ans;
  106. }
  107.  
  108.  
  109. /*
  110.    Shift left
  111.    return a<<1
  112. */
  113. uint48 sl48(uint48 a) {
  114.    st48.carry = 0;
  115.    if (a.b47==1) st48.carry = 1;
  116.    ans.dword = a.dword<<1;
  117.    if (a.b15==1) ans.b16 = 1;
  118.    ans.word[0] = a.word[0]<<1;
  119.    return ans;
  120. }
  121.  
  122. /*
  123.    Shift right
  124.    return a>>1
  125. */
  126. uint48 sr48(uint48 a) {
  127.    st48.carry = 0;
  128.    if (a.b0==1) st48.carry = 1;
  129.    ans.word[0] = a.word[0]>>1;
  130.    if (a.b16==1) ans.b15 = 1;
  131.    ans.dword = a.dword>>1;
  132.    return ans;
  133. }
  134.  
  135.  
  136. /****************************************************************************
  137.       DECIMAL MATH ROUTINES
  138.  ****************************************************************************/
  139.  
  140. /*
  141.    Multiply by 10
  142.    return a*10
  143. */
  144. uint48 mul10_48(uint48 a) {
  145.    a = sl48(a);
  146.    ans = sl48(a);
  147.    ans = sl48(ans);
  148.    ans = add48(a, ans);
  149.    return ans;
  150. }
  151.  
  152.  
  153. /*
  154.    Rational division
  155.    rat = a/b * 10^dot
  156.    rat = [signed char dot] + [uint 40bit number]
  157. */
  158. uint48 div48_rat(uint48 a, uint48 b) {
  159.    signed char i, exp, dot;
  160.    uint48 rat;
  161.  
  162.    // Clear rational result
  163.    LOAD48(rat, 0);
  164.  
  165.    // Adjust integers
  166.    exp = 0;
  167.    for(i=46; i>0; i--) {
  168.       if (a.b46 == 1) break;
  169.       a = sl48(a);
  170.       exp--;
  171.    }
  172.    for(i=46; i>0; i--) {
  173.       if (b.b46 == 1) break;
  174.       b = sl48(b);
  175.       exp++;
  176.    }
  177.  
  178.    // if (argument == zero) return zero
  179.    if (b.b46 == 0 || a.b46 == 0)
  180.       return rat;
  181.  
  182.  
  183.    // divide a / b
  184.    do {
  185.       if (comp48(a, b) >= 0) {
  186.          a = sub48(a, b);
  187.          rat.b0 = 1;
  188.       }
  189.       a = sl48(a);
  190.       rat = sl48(rat);
  191.       exp--;      
  192.    } while(rat.b39==0); // max resolution = 40bit = 12 decimal digits
  193.  
  194.  
  195.    // Adjust binary to decimal ratio
  196.    dot = 0;
  197.    for(i=30; i>0; i--) {
  198.  
  199.       // rat = rat * 10/8
  200.       if (exp>-3) break;
  201.       if (exp==-3)
  202.          if (rat.byte[4]>=186) break; // avoid overflow
  203.       inc48(rat);
  204.       sr48(ans);
  205.       sr48(ans);
  206.       rat = add48(rat, ans);
  207.       exp += 3;
  208.       dot--;
  209.  
  210.       // rat = rat / 2
  211.       if (rat.b40==1) {
  212.          inc48(rat);
  213.          rat = sr48(ans);   // 1/2
  214.          exp++;
  215.       }
  216.    };
  217.  
  218.    for(;exp<0; exp++) {
  219.       inc48(rat);
  220.       rat = sr48(ans);
  221.    }
  222.  
  223.    // Add exponent and return
  224.    rat.byte[5] = dot;
  225.    return rat;
  226. }
  227.  
  228.  
  229. /*
  230.    Transform 48bit binary to BCD
  231.    sdlong = byte[8]
  232.    Delay = 12500 cycles
  233. */
  234. #define DEC_DIG_48   15
  235. void ltoa48(unsigned char *str, static uint48 bin) {
  236.    unsigned char maxdig, digcnt, bitcnt;
  237.    static unsigned char *p, carry;
  238.  
  239.    // Clear string
  240.    p = str;
  241.    digcnt = DEC_DIG_48 + 1;
  242.    do *p++ = 0; while (--digcnt);
  243.  
  244.    // Transform binary to BCD
  245.    bitcnt = 48;
  246.    maxdig = (DEC_DIG_48 - 1);
  247.    str += (DEC_DIG_48 - 1);
  248.    do {
  249.       // shift binary number left with carry
  250.       carry = 0;
  251.       if (bin.b47==1) carry |= 1;
  252.       bin = sl48(bin);
  253.      
  254.       // shift decimal number left with carry
  255.       p = str;
  256.       digcnt = DEC_DIG_48 - maxdig;
  257.       do {
  258.          carry = (*p<<1) + carry;
  259.          if (carry>=10) {
  260.             *p-- = carry - 10;
  261.             carry = 1;
  262.             if (digcnt==1) {
  263.                maxdig--;
  264.                digcnt++;
  265.             }
  266.          }
  267.          else {
  268.             *p-- = carry;
  269.             carry = 0;
  270.          }
  271.       } while(--digcnt);
  272.    } while(--bitcnt);
  273.  
  274.    // Transform BCD to ASCII
  275.    digcnt = DEC_DIG_48;
  276.    do *str-- += '0'; while (--digcnt);
  277. }
  278.  


----------------------------------------------------------------------------------------


math48.h
Código: C
  1. /*
  2.     Declaration file for math48.c
  3.  
  4.    Picuino Development Board
  5.    Creative Commons Reconocimiento-CompartirIgual 3.0 España License.
  6.    https://sites.google.com/site/picuino
  7.  
  8. */
  9.  
  10. #ifndef MATH48_H
  11. #define MATH48_H
  12.  
  13. // Unsigned 48 bit integer
  14. typedef union {
  15.    unsigned char  byte[6];
  16.    unsigned int   word[3];
  17.    struct {
  18.       unsigned int __word;
  19.       unsigned long dword;
  20.    };
  21.    struct {
  22.       unsigned b0:1;
  23.       unsigned b1:1;
  24.       unsigned b2:1;
  25.       unsigned b3:1;
  26.       unsigned b4:1;
  27.       unsigned b5:1;
  28.       unsigned b6:1;
  29.       unsigned b7:1;
  30.       unsigned b8:1;
  31.       unsigned b9:1;
  32.       unsigned b10:1;
  33.       unsigned b11:1;
  34.       unsigned b12:1;
  35.       unsigned b13:1;
  36.       unsigned b14:1;
  37.       unsigned b15:1;
  38.       unsigned b16:1;
  39.       unsigned b17:1;
  40.       unsigned b18:1;
  41.       unsigned b19:1;
  42.       unsigned b20:1;
  43.       unsigned b21:1;
  44.       unsigned b22:1;
  45.       unsigned b23:1;
  46.       unsigned b24:1;
  47.       unsigned b25:1;
  48.       unsigned b26:1;
  49.       unsigned b27:1;
  50.       unsigned b28:1;
  51.       unsigned b29:1;
  52.       unsigned b30:1;
  53.       unsigned b31:1;
  54.       unsigned b32:1;
  55.       unsigned b33:1;
  56.       unsigned b34:1;
  57.       unsigned b35:1;
  58.       unsigned b36:1;
  59.       unsigned b37:1;
  60.       unsigned b38:1;
  61.       unsigned b39:1;
  62.       unsigned b40:1;
  63.       unsigned b41:1;
  64.       unsigned b42:1;
  65.       unsigned b43:1;
  66.       unsigned b44:1;
  67.       unsigned b45:1;
  68.       unsigned b46:1;
  69.       unsigned b47:1;
  70.       unsigned b48:1;
  71.    };
  72. } uint48;
  73.  
  74. #define LOAD48(u48, n) u48.dword = n / 65536; u48.word[0] = n % 65536
  75. #define CLEAR48(u48) u48.word[0] = 0; u48.word[1] = 0; u48.word[2] = 0
  76.  
  77.  
  78. uint48 _rl48(uint48 a);                              // Line  141
  79. uint48 _rr48(uint48 a);                              // Line  156
  80. uint48 add48(uint48 a, uint48 b);                    // Line  116,   2 calls
  81. signed char comp48(uint48 a, uint48 b);              // Line   91
  82. uint48 div48_rat(uint48 a, uint48 b);                // Line  217
  83. uint48 inc48(uint48 a);                              // Line  128,   3 calls
  84. void ltoa48(unsigned char *str, static uint48 bin);  // Line  294
  85. uint48 mul10_48(uint48 a);                           // Line  203
  86. uint48 sl48(uint48 a);                               // Line  172,   8 calls
  87. uint48 sr48(uint48 a);                               // Line  185,   4 calls
  88. uint48 sub48(uint48 a, uint48 b);                    // Line  104,   1 calls
  89.  
  90. #endif
  91.  
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 08 de Mayo de 2012, 10:21:08
He añadido notación de ingeniería (con prefijos del tipo micro, mili, kilo, mega, etc) y he reducido el número de cifras significativas que se muestran en pantalla a 9 cifras significativas.

Con un tiempo de muestreo de 10 segundos los resultados tienen una resolución asombrosa:


System OK

Time=   000000050000036   Pulses=   000000050002998   f=   5,00029635 MHz
Time=   000000100000494   Pulses=   000000100006420   f=   5,00029639 MHz
Time=   000000150000020   Pulses=   000000150008909   f=   5,00029630 MHz
Time=   000000200000324   Pulses=   000000200012176   f=   5,00029629 MHz
Time=   000000250000041   Pulses=   000000250014855   f=   5,00029620 MHz
Time=   000000299010228   Pulses=   000000299027946   f=   5,00029626 MHz
Time=   000000350002167   Pulses=   000000350022907   f=   5,00029628 MHz
Time=   000000400003827   Pulses=   000000400027530   f=   5,00029629 MHz
Time=   000000450004022   Pulses=   000000450030688   f=   5,00029629 MHz
Time=   000000500000735   Pulses=   000000500030363   f=   5,00029621 MHz
Time=   000000550001169   Pulses=   000000550033759   f=   5,00029619 MHz
Time=   000000600003606   Pulses=   000000600039159   f=   5,00029628 MHz
Time=   000000650004641   Pulses=   000000650043156   f=   5,00029619 MHz
Time=   000000700000369   Pulses=   000000700041847   f=   5,00029632 MHz
Time=   000000750000012   Pulses=   000000750044452   f=   5,00029620 MHz

Las cifras bailan en el rango de 0.01ppm. Tanto el frecuencímetro como el generador de señal tienen osciladores de cristal de cuarzo sin compensar.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 08 de Mayo de 2012, 11:27:46
He forzado un poco las medidas, a ver hasta donde se podía llegar.

Tiempo de muestreo = 2 segundos (10millones de ciclos de reloj, en el límite de las 0.1ppm)

Frecuencia de entrada = oscilador de precisión, no compensado térmicamente.


Resultados devueltos por el frecuencímetro por RS232:

Código: [Seleccionar]
Time= 000000010010033 Pulses= 000000160160795 f= 80,0001416 MHz
Time= 000000020013916 Pulses= 000000320223206 f= 80,0001414 MHz
Time= 000000030010541 Pulses= 000000480169489 f= 80,0001415 MHz
Time= 000000040004498 Pulses= 000000640073084 f= 80,0001415 MHz
Time= 000000050003748 Pulses= 000000800061366 f= 80,0001410 MHz
Time= 000000060015826 Pulses= 000000960254897 f= 80,0001413 MHz
Time= 000000070009354 Pulses= 000001120151628 f= 80,0001415 MHz
Time= 000000080012070 Pulses= 000001280195367 f= 80,0001414 MHz
Time= 000000090011300 Pulses= 000001440183330 f= 80,0001415 MHz
Time= 000000100007045 Pulses= 000001600115533 f= 80,0001415 MHz
Time= 000000110001381 Pulses= 000001760025192 f= 80,0001415 MHz
Time= 000000120005648 Pulses= 000001920093747 f= 80,0001414 MHz
Time= 000000130003277 Pulses= 000002080056094 f= 80,0001415 MHz
Time= 000000140009494 Pulses= 000002240155850 f= 80,0001419 MHz
Time= 000000150004264 Pulses= 000002400072453 f= 80,0001415 MHz
Time= 000000160018444 Pulses= 000002560299616 f= 80,0001412 MHz
Time= 000000170015982 Pulses= 000002720260506 f= 80,0001410 MHz
Time= 000000180014504 Pulses= 000002880237141 f= 80,0001415 MHz
Time= 000000190002404 Pulses= 000003040043823 f= 80,0001411 MHz
Time= 000000200011880 Pulses= 000003200195721 f= 80,0001408 MHz
Time= 000000210012834 Pulses= 000003360211267 f= 80,0001409 MHz
Time= 000000220010587 Pulses= 000003520175597 f= 80,0001410 MHz
Time= 000000230005729 Pulses= 000003680098151 f= 80,0001410 MHz
Time= 000000240000209 Pulses= 000003840010113 f= 80,0001410 MHz
Time= 000000250002992 Pulses= 000004000054924 f= 80,0001414 MHz
Time= 000000260014831 Pulses= 000004160244631 f= 80,0001413 MHz
Time= 000000270002168 Pulses= 000004320042306 f= 80,0001416 MHz
Time= 000000280010573 Pulses= 000004480177070 f= 80,0001418 MHz
Time= 000000290015971 Pulses= 000004640263721 f= 80,0001414 MHz
Time= 000000300000371 Pulses= 000004800014404 f= 80,0001417 MHz
Time= 000000310018154 Pulses= 000004960299215 f= 80,0001412 MHz
Time= 000000320003668 Pulses= 000005120067721 f= 80,0001412 MHz
Time= 000000330012690 Pulses= 000005280212355 f= 80,0001408 MHz
Time= 000000340013923 Pulses= 000005440232365 f= 80,0001409 MHz
Time= 000000350001562 Pulses= 000005600034871 f= 80,0001411 MHz
Time= 000000360004004 Pulses= 000005760074224 f= 80,0001404 MHz

Creo que puedo dar por buena la medición de frecuencias en el rango de 5Mhz a 50 Mhz. Funciona sin problemas con errores máximo de 0.1 ppm

Voy a pedir por e-bay un oscilador OCXO con error menor de 0.1ppm para probar exactitud.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 08 de Mayo de 2012, 13:47:24
Página del NIST de la división encargada de la medición del tiempo y la frecuencia:
http://www.nist.gov/pml/div688


Un widget interesante que da la hora y el error de retardo de la red:
http://www.time.gov/widget/

http://time.gov/widget/NISTtimewidget.swf

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 08 de Mayo de 2012, 13:52:50
Algunos enlaces de interés:

Inexpensive Precision Frequency Standard  (http://robin-wood.com/Ham/Mine/freq_standard.htm)

Homebrewed 10MHz frequency reference locked by GPS (http://www.hanssummers.com/gpsref.html)

GPS-Controlled Frequency Standard (http://www.rt66.com/~shera/index_fs.htm)

DCF77-synchronized oscillator (http://www.qsl.net/d/dl4yhf//dcf77_osc/index.html) with homebrew OCXO oscillator!

    (http://www.qsl.net/d/dl4yhf//dcf77_osc/homebrew_ocxo_closeup1.jpg)


Obtaining a precision frequency reference for  for hobbyist. GPS Disciplined Oscillator (GPSDO) (http://www.ko4bb.com/Timing/FrequencyReference.php)


http://www.electro-tech-online.com/electronic-projects-design-ideas-reviews/99005-make-high-accuracy-frequency-meter.html


Trimble ThunderBolt Timing GPS Receiver GPSDO (http://www.prc68.com/I/ThunderBolt.shtml)
Youtube Thunderbolt GPSDO (http://www.youtube.com/watch?v=DkODp4C-0Q0&feature=relmfu)



Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 09 de Mayo de 2012, 09:54:15
He pedido por e-bay un oscilador de cuarzo de horno controlado (OCXO) de 10Mhz con salida de señal cuadrada de 0 a 5v.
La precisión es mejor de 0.1ppm.
El error máximo se debe al envejecimiento y según la hoja de características es de 0.1ppm al año.

El oscilador tiene una entrada de tensión de 0 a 5 voltios que permite variar la frecuencia +-1 ppm para poder "afinarle".

Ahora el reto que tengo es encontrar una señal patrón con la que comparar el oscilador cada cierto tiempo para comprobar su exactitud.
Estoy valorando las opciones de un módulo GPS o de señales de radio reloj, como la DCF77 que se utiliza para poner en hora los radio-relojes.

¿Alguien conoce el tema? agradecería un poco de orientación.


La exactitud que busco es de 0.1ppm que traducido significa un error de:

   100     nanosegundos cada segundo
   6        microsegundos cada minuto
   360     microsegundos cada hora
   8.64    milisegundos al día
   0.259  segundos al mes
   3.156  segundos al año

   200Hz en 2GHz
   10 Hz en 100MHz
   1 Hz en 10MHz
   0.000005 Hz en 50Hz
   0.0000001 Hz en 1Hz

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 09 de Mayo de 2012, 20:06:28
Comparativa entre las emisiones de radio-reloj  DCF77 y TDF:
http://www.leunig.de/_en/_pro/radio-controlled-clock/funkuhren_DCF77_TDF.htm




Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 11 de Mayo de 2012, 11:11:33
Estoy atascado :( y no se como continuar.

Necesito contar pulsos de dos fuentes de alta frecuencia y capturar los conteos de ambas a la vez y no sé qué micro utilizar o si añadir componentes externos.

No sé cómo contar dos señales de alta frecuencia y no se cómo sincronizar la captura de los dos contadores a la vez.
El esquema es el siguiente:

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

Un entrada es de frecuencia fija de 10Mhz y 0.1ppm
Otra entrada es de la frecuencia a medir (0 a 50Mhz)

* Las dos entradas tienen más frecuencia que el reloj interno, por lo que se deben contar en modo asíncrono.
* El contador debe trabajar sin preescaler para no perder resolución (como mínimo deben contar 10Mpulsos/segundo para conseguir 0.1ppm en un segundo)
* La captura debe estar sincronizada con un flanco de la señal de frecuencia más baja, para no perder resolución.
* Los dos contadores se deben capturar a la vez
* El tiempo entre capturas debe ser alto. Lo suficiente como para que de tiempo a leer la información antes de que otra captura borre los datos (10us como mínimo).
También se podría resolver parando las dos capturas a la vez (que no pare primero una y después la otra)


No encuentro ningún PIC donde meter el esquema. Todos tienen inconvenientes. Estoy pensando colocar un circuito externo, pero no quiero que sea muy complicado.

¿Alguna idea?

Saludos.



Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: KALLITOS en 11 de Mayo de 2012, 11:28:56
Hola picuino el dspic30f4013 tiene timers que se pueden configurar a 32 bits con entrada externa, podras contar los 10M de pulsos, el micro tiene TMR2y3  y TMR4y5 ambos con entrada externa y puede ir hasta 30 MIPS, o sino cualkier pic24HJ esos corren a 40Mips.

checalos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 11 de Mayo de 2012, 11:56:45
Hola KALLITOS, gracias por responder.

Tengo un dsPIC30F4012.
El problema con ese micro es que la captura de datos sólo se realiza con el timer2/3 que es síncrono. Imagino que si pongo el oscilador a 48Mhz a lo mejor alcanza a contar 10Mhz de entrada en modo síncrono (no lo sé).

Otro problema es que el módulo de captura no toma datos del timer1 (el que utilizaría para contar hasta 50Mhz)

Saludos.

Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 11 de Mayo de 2012, 18:33:39
Estoy estudiando el PIC18F25K80.

Tiene dos timers asíncronos (Timer1 y Timer3) con entradas por pines independientes.
El módulo de captura puede capturar tanto el Timer1 como el Timer3. (A la vez si conecto la entrada CCP3 y CCP4 entre sí)

Puede trabajar con una señal externa de reloj de 10MHz y el PLL la multiplica hasta 40Mhz sin problema (el pic18f2550 no puede trabajar con 10Mhz y el PLL a la vez)


Parece un PIC18 "avanzado" y está muy bien de precio.

Saludos.

Edito: Tiene un módulo CTMU con el que medir con precisión el ciclo de trabajo de la señal de entrada. (con ADC de 12 bits)

Edito: Tiene un sensor interno de temperatura asociado al CTMU y es muy fácil medir temperatura externa, con lo que puedo diseñar una compensación de frecuencia con la temperatura ambiente. Así cuando no tenga disponible la señal externa de reloj de alta precisión (10Mhz 0.1ppm) puedo seguir midiendo con el oscilador de cristal normal compensado en temperatura (1ppm).

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 13 de Mayo de 2012, 17:34:43
Unos documentos interesantes:


Frequency Accuracy & Stability Dependencies of Crystal Oscillators:
http://kunz-pc.sce.carleton.ca/thesis/CrystalOscillators.pdf


The Accuracy and Stability of Quartz Watches:
http://tf.nist.gov/general/pdf/2276.pdf


Understanding Frequency Accuracy in Crystal Controlled Instruments:
http://www.tessco.com/yts/industry/products/itm/spectrum_analyzers/pdf/UnderstandingFrequencyAccuracyinCrystalControlledInstruments.pdf


Wikipedia: Crystal oscillator
http://en.wikipedia.org/wiki/Crystal_oscillatorç


RS Online: Cristales (con datasheets)
http://es.rs-online.com/web/c/semiconductores/control-de-frecuencia/cristales/


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 13 de Mayo de 2012, 17:58:28
Algunas definiciones interesantes:

PRECISIÓN (precision): capacidad de un instrumento de dar el mismo resultado en mediciones diferentes realizadas en las mismas condiciones. Esta cualidad debe evaluarse a corto plazo.
Se puede interpretar como la desviación estandar de las medidas tomadas.

EXACTITUD (accuracy): capacidad de un instrumento de acercarse al valor de la magnitud real. Se evalúa a partir de la media de varias mediciones.
Se puede interpretar como la diferencia entre la media de las mediciones y el valor real.

(http://raulcalasanz.files.wordpress.com/2009/10/precision_exactitud.jpg)


RESOLUCION (resolution): El menor cambio de una magnitud que es capaz de medir un instrumento.

ESTABILIDAD (stability): Es la capacidad de un instrumento de mantener la misma exactitud a lo largo de un intervalo de tiempo largo. También puede considerarse estable un instrumento que tiene una variación constante de su medida a lo largo del tiempo (por ejemplo gana 1ppm cada año de forma constante), de forma que pueda compensarse.
La estabilidad en los osciladores de cuarzo depende del tiempo (envejecimiento o aging) y tambíen de las variaciones de temperatura. A los osciladores con temperatura controlada OCXO les afecta las fases de encendido/apagado del instrumento.
La desviación Allan (Allan deviation or ADEV) es una forma de medir la estabilidad.

(http://www.nist.gov/physlab/div847/grp40/images/accuracystability_1.gif)

INCERTIDUMBRE (uncertainty): rango dentro del cual debe estar el valor real de una medida. Es una acotación del error de medida.
Una medida de 10Mhz con una incertidumbre de +-10Hz tendrá un valor real entre 10000010Hz y 9999990Hz

ERROR: diferencia entre el valor de una medida y el valor real. Se aplica a una sóla medida. El error medio de varias medidas se mide con la exactitud.


Saludos.


Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 14 de Mayo de 2012, 09:40:48
Estoy estudiando el micro que debería utilizar para este proyecto y cada vez estoy más encantado con el PIC18F25K80.

Algunas características sobresalientes (que mejoran al conocido PIC18F2550):

PIC18F25K80
   Velocidad hasta 64Mhz (16M instrucciones por segundo)
   Consumo muy bajo (8mA a 64Mhz)
   PLL con frecuencias de entrada desde 4Mhz hasta 16Mhz (acepta reloj externo de 10Mhz para el PLL)
   Soporte de comunicaciones CAN Bus
   Charge Time Measure Unit  (CTMU) que permite medir tiempos con una resolución de 1ns
   Conversor ADC de 12 bit.
   5 Timers (2x8bit, 3x16bit)
   Entradas separadas para los dos timer asíncronos de 16 bit T1 y T3 que se utilizan en la captura de datos (módulo CCP)
   Memoria Flash de 32Kbytes, RAM de 3648 bytes, EEprom 1024 bytes. (igual que el 18F2550)
   Precio reducido.



USB
Otro tema que estoy considerando es la forma de implementar USB en la placa. Si utilizo un microcontrolador con USB para todo, eso complica enórmemente la programación.
Revisando precios de microcontroladores me he dado cuenta de que el conocido PIC18F2550 es casi tan caro como dos procesadores, uno con USB y otro más avanzado.

Precio de varios microcontroladores en RS-Online (formato SOIC):

PIC18F14K50    2,16 Euros     (con USB)
PIC18F25K80    2.38 Euros     (sin USB)
Total                 4.54 Euros

PIC18F2550      4.42 Euros     (con USB)

He decidido por lo tanto hacer la placa con dos microcontroladores (como la placa Arduino UNO).


Saludos.

Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Nocturno en 14 de Mayo de 2012, 13:02:53
Quizás deberías considerar el 24FJ64GB002 (http://es.rs-online.com/web/p/microcontroladores/7037611/)

Tiene USB, es más potente, y más barato que la suma de ambos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 14 de Mayo de 2012, 20:26:38
Es un micro muy interesante. El problema es quizás mío. Me cuesta meter en un mismo micro el manejo del USB y otra aplicación.

Si quieres hacer una sencilla prueba de parpadeo de un led y utilizas un bucle de retardo... adios el USB.
Hay que trabajar obligatoriamente de forma cooperativa con el stack USB, pero no es tampoco un RTOS ....

Por ahora prefiero separar la gestión del USB a otro micro.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: MerLiNz en 14 de Mayo de 2012, 22:26:35
Y porque no usar un timer en vez de un bucle?  :D

Puedes poner el USB por interrupciones asi aunque te quedes en un bucle las interrupciones se iran ejecutando, eso si, perderas ciclos de reloj en el bucle. Pero vamos, yo tengo una enorme aplicacion donde interactua el USB, lecturas de SPI, calculos grandes tipo float, y de 64bits y el usb funciona perfectamente, todo sin rtos, a mi el rtos no me gusta, pero tambien es cierto que no uso NINGUNA funcion bloqueante.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Suky en 14 de Mayo de 2012, 23:43:57
Es una buena practica realizar librerías y códigos sin funciones bloqueantes, sin llegar a utilizar un scheduler puedes trabajar con varios periféricos/dispositivos a la vez  ;-)
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 15 de Mayo de 2012, 06:15:52
Es verdad que las funciones bloqueantes no son muy deseables, era sólo un ejemplo.

¿Cómo podría utilizar el PIC18F2550 para medir frecuencias mientras maneja el USB?

El micro no tiene entradas independientes para los dos contadores (TMR1, TMR3) que podrían capturar las dos señales externas.
No puedo meterle los 10Mhz de referencia en el reloj porque no es compatible con el USB.

Tengo que sincronizar la captura de pulsos de entrada (a frecuencia variable) con un reloj de referencia de 10Mhz con un error de respuesta máximo de 100ns.

El pooling está descartado por que interfiere con el USB.

Podría meter 10Mhz por el Timer0, la señal de entrada por Timer1 y sincronizar la captura de datos por interrupciones, pero tengo que asegurarme de que el tiempo de respuesta a la interrupción sea siempre el mismo a pesar del USB.


No tengo claro cómo hacerlo, por eso quería separar el manejo del USB a otro micro y utilizar el 18F25K80 para medir frecuencias porque tiene entradas separadas para Timer1 y Timer3

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 15 de Mayo de 2012, 15:10:49
Estoy intentando manejar el frecuencímetro con interrupciones y me he encontrado con un problema de esos que desesperan.

El programa espera a que se active CCP1IF (que avisa de dato capturado) y luego lee el dato de CCPR1L (registro de captura).

El resultado siempre es el mismo CCPR1L = 1

No me lo explico. El CCP2 va perfectamente y captura datos del TIMER3 sin problemas.
Cuando configuro CCP1 para que capture datos del Timer3, funciona todo correcto.

No sé qué está ocurriendo.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 15 de Mayo de 2012, 15:15:38
Solucionado:

El módulo de captura sólo captura datos del Timer si está funcionando en modo síncrono.

A veces viene bien leer el manual  :?


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 17 de Mayo de 2012, 08:35:17
Ya tengo algún avance.
Consigo medir bien las bajas frecuencias en el rango de 1 a 1Mhz.
El rango que más me está costando es el de 1Mhz a 10Mhz

Ahora tengo una consulta sobre la que me gustaría recibir opiniones de todo tipo.

¿Que lectura es preferible tener en un frecuencímetro? 7 dígitos correctos u 8 dígitos con error:

A) 7 dígitos. Error +-0.1 Hz
   123 456.7 Hz
   123 456.8 Hz
   123 456.7 Hz
   123 456.7 Hz
   123 456.8 Hz
   123 456.7 Hz

B) 8 dígitos. Error +-0.1 Hz
   123 456.75 Hz
   123 456.82 Hz
   123 456.75 Hz
   123 456.75 Hz
   123 456.82 Hz
   123 456.75 Hz


Las lecturas aparecen cada segundo. En ambos casos la frecuencia exacta es 123 456.77 Hz con error de 0.01Hz (la media de todas las lecturas durante 10 segundos)

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: MerLiNz en 17 de Mayo de 2012, 09:32:33
yo pondria 7 digitos
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 17 de Mayo de 2012, 10:15:53
Puedo poner dos lecturas:
7 dígitos cada segundo (con error de +-1 en el último dígito)
8 dígitos de la media de los últimos 10 segundos (con error de +-1 en el último dígito)

Esta última lectura se puede mantener exacta durante unos días después de calibrar el instrumento.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Suky en 17 de Mayo de 2012, 11:09:17
Si tu instrumento tiene una resolución de +/-0.1, entonces la forma correcta de expresar un valor es xxxxx.x  ;-)


Saludos!
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Nocturno en 17 de Mayo de 2012, 11:47:33
Si la lectura correcta es 123456.77 Hz yo pintaría 123456.8 Hz sin que se moviera, ¿no es posible?
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 17 de Mayo de 2012, 12:23:48
Con el tiempo de muestreo de 1 segundo, a veces se mueve la lectura en el último dígito.

En las frecuencias altas la lectura es correcta y oscila poco.
En frecuencias bajas hay más problemas.

Acabo de hacer una rutina para variar el número de decimales. Así se puede elegir la precisión de pantalla según la precisión de la lectura.

Cuando tenga más resultados los comento.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 17 de Mayo de 2012, 15:55:20
Si la lectura correcta es 123456.77 Hz yo pintaría 123456.8 Hz sin que se moviera, ¿no es posible?

Creo que no es posible hacer que la lectura no baile. Al menos no se puede con el PIC18F2550 con el que lo estoy intentando.

Todos los métodos tienen algún problema que impide tomar medidas exactas.
La mayor parte de las medidas son correctas, pero siempre hay alguna interrupción u otro problema que impide tomar la medida a tiempo.

He decidido intentarlo con circuitería externa que impida la captura de datos. El módulo de captura tiene un problema a altas frecuencias porque captura datos más rápido de lo que se pueden leer y a altas frecuencias deja de ser útil.
Lo que voy a intentar es poner una puerta lógica o algo similar que pueda inhibir otra nueva captura de datos mientras se lee la captura anterior.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 17 de Mayo de 2012, 19:46:24
Dos documentos muy interesantes de HP (Agilent) sobre las funciones que debe tener un frecuencímetro:

Fundamentals of the Electronic Counters: http://cp.literature.agilent.com/litweb/pdf/5965-7660E.pdf

Fundamentals of Microwave Frequency Counters: http://cp.literature.agilent.com/litweb/pdf/5965-7661E.pdf


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 17 de Mayo de 2012, 19:54:38
Diagrama interno y listado de componentes de un frecuencímetro de HP (Agilent):

E1420B Universal Counter Component Level Information: http://cp.literature.agilent.com/litweb/pdf/5989-5950EN.pdf


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 18 de Mayo de 2012, 17:20:04
Por fin he conseguido una lectura estable. Sólo se ven errores iguales o menores de 0.1ppm con un tiempo de muestreo de 1 segundo.
Para tiempos de muestreo mayores, la precisión aumenta.

Lo he conseguido añadiendo interrupciones de alta prioridad para la lectura de datos.
Al final he abandonado el módulo de captura CCP porque me daba demasiados problemas.

También he programado una rutina que permite seleccionar los dígitos de precisión que se presentan en la pantalla.

Las rutinas matemáticas las he implementado en C sin intentar optimizar velocidad. Eso las hace más portables para otros micros.
Los números enteros tienen 48 bits. Eso permite almacenar los pulsos acumulados de una señal de 80Mhz durante más de un año.
Los números en coma flotante tienen mantisa de 32 bits. Eso permite mostrar cálculos con una precisión de 9 1/2 dígitos decimales (0.001 ppm)

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Suky en 18 de Mayo de 2012, 17:33:03
Excelente! Con el tema de la representación, los decimales van acompañados del error. O sea, si tienes un error máximo ya establecido de 0.1, no puedes mostrar 0.05, es totalmente inútil, o es 0.0 o 0.1  ;-)


Saludos!
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 18 de Mayo de 2012, 18:16:28
Ahora el problema lo tengo en los números intermedios. Me explico.

Para las frecuencias menores de 10MHz la precisión es exactamente 0.1ppm. Eso significa que las medidas salen así:

1000000.0  +- 0.1    Aquí todo Ok
2000000.0  +- 0.2    Todavía no pasa nada
5000000.0  +- 0.5    La cosa empeora
8000000.0  +- 0.8    ¿Qué hago aquí?

La última lectura da valores así:
8000000.7
8000000.0
8000000.7
8000000.0
8000000.7
8000000.7
8000000.7
8000000.0

Bailan mucho, pero en definitiva la exactitud requiere 7 decimales para una lectura correcta.

Saludos

Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Suky en 18 de Mayo de 2012, 19:07:27
Podes expresar el error en %. El rango es muuuy amplio, así que tambien podrías establecer distintas escalas con distintos errores. No es lo mismo medir 100 Hz con +/-0.1 que 10 MHz +/-0.1  ;-)


Saludos!
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 18 de Mayo de 2012, 20:27:40
El error siempre es 0.00001% (0.1ppm) Para cualquier frecuencia, incluso las bajas frecuencias.
Por eso quise desarrollar este proyecto, para conseguir buena precisión en cualquier frecuencia.

Para 100 Hz las lecturas son:

100,00000
100,00000
100,00000
100,00001
100,00000
100,00000
100,00000
100,00000
100,00001
100,00000

Al ser una frecuencia que comienza por 1 el error termina siendo pequeño: +- 0.00001

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 21 de Mayo de 2012, 18:07:43
Nuevo avance:

He mejorado las rutinas matemáticas para añadir la multiplicación de números flotantes. Ahora se puede corregir la desviación de frecuencia mediante software.

He incluido dos métodos de estimación de frecuencia: mediante el oscilador del microcontrolador (interno o externo) y mediante una entrada externa conectada al TIMER0.
Gracias a eso se pueden comparar con mucha precisión dos frecuencias externas (por ejemplo una FI de 50Mhz y otra frecuencia patron de 10Mhz para saber la relación entre ambas)

Todos los cálculos se realizan sobre contadores que no paran, de forma que se pueden realizar medias sobre un periodo mucho mayor.

Ahora voy a añadir controles por pulsadores y visualización en LCD.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 24 de Mayo de 2012, 15:47:12
Ya me ha llegado el oscilador. La precisión que tiene es de 10ppb (0.01ppm) y la exactitud depende de la calibración.
Por ahora lo he calibrado con el frecuencímetro digital, pero a largo plazo debería hacerlo con otro más exacto (se supone que tiene un error por envejecimiento de 0.1ppm al año)

Las primeras pruebas funcionan bien, pero no son del todo satisfactorias cuando comparo dos señales externas:
   El oscilador mete 10MHz por RA4 (Timer0)
   La señal a medir entra por RC0 (Timer1)

El error de medida oscila entre 0 y 3 pulsos (es un poco grande porque debería estar entre 0 y 1 pulso)
El método que utilizo es simplemente leer los timers. El módulo de captura no se puede utilizar porque son dos señales y se cuentan en modo asíncrono.

Voy a intentar que el programa tome mejor los datos. Si no lo consigo siempre está la solución de aumentar el tiempo de muestreo a 3 segundos.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: MerLiNz en 25 de Mayo de 2012, 11:27:06
Para que necesitas tanta precision? No estaras pensando en hacer una maquina del tiempo jajaj
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 25 de Mayo de 2012, 16:47:20
En realidad es un reto. No necesito tanta precisión.

De todas formas sí es útil para ciertos trabajos:

Por ejemplo si quieres ajustar un reloj en tiempo real a 1ppm (2.5 segundos de error al mes), necesitas un aparato que mida con mayor precisión.

Una de las cosas que tengo en la cabeza es diseñar un oscilador barato de precisión de 32768Hz compensado térmicamente. La temperatura se puede medir con un diodo 1N4148.

Otro proyecto es medir la deriva de frecuencia de la red eléctrica.

También me gustaría estudiar la variación de la frecuencia de los osciladores basados en cristal a temperatura ambiente (los normales).


La frecuencia y el tiempo es la medida que se puede realizar con mayor precisión en un rango además amplísimo.
Esto te sirve para hacer instrumentos tan interesantes como el LC meter con un rango muy amplio de medida sin necesidad de cambiar ningún selector.

Una vez que lo tenga montado intentaré buscarle más aplicaciones.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: AKENAFAB en 25 de Mayo de 2012, 16:52:03
Muy inteserante tu proyecto! ((:-))

Para que necesitas tanta precision? No estaras pensando en hacer una maquina del tiempo jajaj
LOLazo xD  :D
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 25 de Mayo de 2012, 17:54:20
Para que necesitas tanta precision? No estaras pensando en hacer una maquina del tiempo jajaj
A lo mejor alguien se anima a dejar el esquema del condensador de fluzo y podemos montar una entre todos  :D

¿Qué modelo preferís?

1.- (http://www.yalosabes.com/images//maquina-del-tiempo02.jpg)

2.- (http://cdn.ghosttheory.com/wp-content/uploads/2012/04/The-Time-Machine.jpg)

3.- (http://2.bp.blogspot.com/--ikXMnwkM8s/Ta680D7Lp-I/AAAAAAAAAQs/zgPHfTxh7TI/s1600/TerminatorTimeSphere.jpeg)

La última máquina no se ve. Es la de Terminator.
Todas ellos me han hecho pasar muy buenos ratos.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: MerLiNz en 25 de Mayo de 2012, 19:51:36
uhm, creo que para que nos den los esquemas del condensador de fluzo necesitariamos viajar al pasado, asi que estamos en un dilema  :?
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 26 de Mayo de 2012, 05:29:34
Solo he encontrado una manera de sincronizar correctamente la captura de datos de dos contadores de pulsos externos (Timer0 y Timer1) y es mediante pooling.

La sincronización con interrupciones no funciona bien.


Creo que se pueden resolver los problemas haciendo el pooling compatible con las interrupciones para manejar USB, contar los acarreos de los timers y responder al teclado.

Cada vez tengo más ganas de cambiar de micro o de poner los contadores fuera del microcontrolador.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 27 de Mayo de 2012, 18:32:25
Ya tengo montada la placa del oscilador OCXO a 10MHz. Va a ser el corazón del frecuencímetro.

La exactitud, una vez calibrado, es de 0.01 ppm a corto plazo.

El envejecimiento a un año da un error máximo de 0.1 ppm y es la fuente de mayor desviación.
Como este oscilador es de segunda mano espero que tenga menos envejecimiento que uno nuevo.

Imagen de la placa:

(https://sites.google.com/site/picuino/ocxo_10mhz/ocxo_placa_v09_800px.jpg)


Los dos potenciómetros sirven para ajustar la frecuencia. Uno da el ajuste grueso y el otro el ajuste fino.

El circuito integrado es un 74HC14 para amplificar la señal de salida y poder dar 0-5 voltios con una impedancia de 50 ohms.


Página con los archivos de montaje en formato KiCad y PCB:

    Oscilador OCXO de 10MHz (https://sites.google.com/site/picuino/ocxo_10mhz)


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 28 de Mayo de 2012, 13:44:52
Para que necesitas tanta precision? No estaras pensando en hacer una maquina del tiempo jajaj

En realidad es una de las aplicaciones que pensé, pero no se si tengo suficiente precisión como para conseguirlo.

Uno de los experimentos que demostraron la teoría de la relatividad de Einstein consistió en embarcar en un avión un reloj atómico sincronizado con otro reloj en tierra.
Después del vuelo del avión comprobaron los dos relojes y el reloj embarcado se había retrasado unos milisegundos respecto al reloj en tierra.
Es decir que el avión había volado literalmente hacia el pasado mientras que el reloj en tierra se había permanecido en el presente

Por desgracia el tiempo de retraso es muy pequeño, casi inapreciable como para hacer un viaje en el tiempo significativo.


En realidad dependiendo de la dirección del avión puede haber adelanto o atraso del tiempo:
http://en.wikipedia.org/wiki/Hafele%E2%80%93Keating_experiment


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 31 de Mayo de 2012, 14:47:50
Novedades.
Estoy diseñando una nueva placa de desarrollo basada en un PIC18F25K80 orientada a proyectos de instrumentación y medida.

Voy a trasladar el programa del frecuencímetro a la nueva placa porque creo que tiene más posibilidades que el micro 18F2550 que estoy utilizando ahora.

La he llamado Picuino Kamaleón y la voy a desarrollar con tecnología mixta de componentes pasantes y de montaje superficial.

El nombre se lo he puesto pensando en las semejanzas de la placa con el animal:

   * Kamaleón con K como la referencia del micro 18F25K80

   * El camaleón tiene dos ojos que pueden ver de forma independiente. Con un ojo pueden seguir a una presa mientras con el otro vigilan a posibles depredadores.
      El micro tiene dos entradas independientes para la captura de pulsos con el Timer1 y el Timer3.

   * Dicen de él que se alimenta del aire (1 milivatio de consumo a 4MHz y 1.8 voltios)

   * Está rodeado de una piel muy sensible que detecta los colores que le rodean y es capaz de reproducir el mismo color como respuesta de salida.
      La placa está rodeada de entradas muy sensibles capaces de medir tensiones, diferencias mínimas de capacidad, intervalos de tiempo de hasta 1 nanosegundo, temperaturas, etc.
      Los pines de entrada que rodean a la placa son capaces también de producir salidas digitales, referencia de tensión salida y salidas de corriente.

   * El camaleón tiene una velocidad de reacción rapidísima para capturar las presas.
      La placa soporta modos de operación de hasta 64 Mhz y 16mips.

   * El camaleón es capaz de mimetizarse y cambiar de aspecto para adaptarse al entorno.
      La placa de desarrollo también cambiará de aspecto con los distintos shields para adaptarse a la medida de diferentes magnitudes.


Este fin de semana me dedicaré a terminar el diseño de la PCB y si tengo tiempo de montar la placa lo publicaré.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Nocturno en 01 de Junio de 2012, 02:06:23
Muy ocurrente. Ya estoy deseando verla.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 04 de Junio de 2012, 12:26:15
Sigo dándole vueltas a la placa.
Al principio pensé en hacer una placa genérica y después acoplarle módulos y Shields, pero creo que es demasiado engorroso.

Voy a intentar montar un LCD y un teclado de 4 pulsadores sobre la placa de forma permanente y dejar un solo conector para acoplar módulos adaptadores de medidas.

Así con sólo unir dos placas tendré un frecuencímetro, un LC meter, un capacímetro, un medidor de distancias por ultrasonidos, etc.

Sigo con ello.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 11 de Junio de 2012, 13:09:43
Al final he diseñado una placa para el PIC18F25K80 como semejante a las demás que había hecho antes. Está orientada a conectar módulos.

El problema con el que me encontré es que no sé qué pines voy a utilizar al final y qué pines tendré libres para el LCD. Esta era la configuración más flexible.

Ya he montado la placa y estoy adaptando el bootloader para el nuevo micro. Aún no he montado todos los componentes cuando esté la placa completa dejaré fotos y un enlace a los archivos.

Por ahora dejo una imagen de la cara de pistas. Está un poco sucia porque he utilizado pasta de soldar (esta es la última vez porque ya he comprado flux líquido para SMD como me recomendó el amigo Nocturno)




Un saludo.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: MerLiNz en 11 de Junio de 2012, 14:04:24
Necesitas un soldador mas fino, si o si  :lol:
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Nocturno en 11 de Junio de 2012, 14:19:36
Está fenomenal, Picuino. Una vez que pruebas el SMD ya no quieres volver al through hole.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 11 de Junio de 2012, 16:51:59
Necesitas un soldador mas fino, si o si  :lol:
O unas manos más finas y una lupa más grande  :D
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 11 de Junio de 2012, 16:57:05
Ya tengo la placa funcionando. Por ahora la programo con el Pickit 3. Sólo me falta adaptarle el bootloader RS232 con el que suelo programar.

Por ahora me he llevado una pequeña decepción con el xtal que tiene nada menos que +70ppm de error. He intentado ajustarle con capacidades y en ocasiones deja de oscilar. Voy a comprar varios cristales de 10Mhz y probaré hasta que pueda ajustar uno a 2 o 3 ppm. Así en caso de no conectar la referencia de frecuencia, seguirá funcionando aceptablemente.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 16 de Junio de 2012, 05:21:13
Ya he conseguido programar la placa con un bootloader, puedo comenzar a adaptar el frecuencímetro al PIC18F25K80


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 16 de Junio de 2012, 06:22:45
Ya he publicado los esquemas, fotos y bootloader para la placa Kamaleón:

Placa de desarrollo Picuino Kamaleón (https://sites.google.com/site/picuino/picuino_kamaleon)


(https://sites.google.com/site/picuino/picuino_kamaleon/Front_800px_v09.jpg)


(https://sites.google.com/site/picuino/picuino_kamaleon/Rear_800px_v09.jpg)


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 18 de Junio de 2012, 14:37:12
Ya he conseguido 'traducir' el programa desde el PIC18F2550 hasta el PIC18F25K80.

La medida de datos funciona bastante bien, pero con algunas medidas incorrectas (una de cada 10 más o menos).
Voy a revisar las interrupciones para comprobar los problemas.

También voy a probar el módulo CCP para captura de datos. Esta nuevo microcontrolador tiene muchos más módulos de captura y són más rápidos que el PIC18F2550. Espero que esta vez funcione.


Las pruebas que he realizado por ahora con el oscilador OCXO comparado con el frecuencímetro (que también tiene un oscilador interno de tipo OCXO) dan los siguientes resultados.
   El oscilador OCXO de 10Mhz tarda unos 10 minutos en estabilizarse y al cabo de 1 hora tiene una frecuencia completamente estable con variación menor de 0.02ppm.
   El frecuencímetro por el contrario tarda varias horas en estabilizarse hasta una precisión de 0.02 ppm

   Uno de los dos osciladores tiene un envejecimiento apreciable. Estos días han variado más de 0.3ppm entre ellos.
   Cuando termine el proyecto necesitaré una fuente de frecuencia exacta para calibrar el aparato.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 20 de Junio de 2012, 11:21:20
Parece que ya tengo buenos resultados para altas frecuencias (precisión de 0.01 ppm)

Esta serie mide la frecuencia de oscilación del cristal de cuarzo del microcontrolador comparado con el oscilador OCXO como base de tiempos.

Como puede verse, la exactitud es bastante buena porque el cristal ya está afinado con una capacidad a medida.

(La frecuencia es el último número que indica 10,0000 MHz)

Código: [Seleccionar]
Time= 000000011988468 Pulses= 000000009990389 f= 10,0000017 M
Time= 000000023992451 Pulses= 000000019993710 f= 10,0000018 M
Time= 000000035988467 Pulses= 000000029990392 f= 10,0000018 M
Time= 000000047988465 Pulses= 000000039990392 f= 10,0000018 M
Time= 000000059988473 Pulses= 000000049990401 f= 10,0000019 M
Time= 000000071988470 Pulses= 000000059990400 f= 10,0000018 M
Time= 000000083988465 Pulses= 000000069990398 f= 10,0000019 M
Time= 000000095988465 Pulses= 000000079990400 f= 10,0000019 M
Time= 000000107988471 Pulses= 000000089990407 f= 10,0000019 M
Time= 000000119988468 Pulses= 000000099990406 f= 10,0000019 M
Time= 000000131988468 Pulses= 000000109990408 f= 10,0000019 M
Time= 000000143988470 Pulses= 000000119990412 f= 10,0000020 M
Time= 000000155988470 Pulses= 000000129990414 f= 10,0000019 M
Time= 000000167988467 Pulses= 000000139990413 f= 10,0000019 M
Time= 000000179988467 Pulses= 000000149990415 f= 10,0000019 M
Time= 000000191988467 Pulses= 000000159990417 f= 10,0000019 M
Time= 000000203988467 Pulses= 000000169990419 f= 10,0000019 M
Time= 000000215988468 Pulses= 000000179990422 f= 10,0000019 M
Time= 000000227988465 Pulses= 000000189990421 f= 10,0000019 M
Time= 000000239988466 Pulses= 000000199990424 f= 10,0000020 M
Time= 000000251988479 Pulses= 000000209990437 f= 10,0000020 M
Time= 000000263988465 Pulses= 000000219990427 f= 10,0000019 M
Time= 000000275988470 Pulses= 000000229990433 f= 10,0000019 M
Time= 000000287988465 Pulses= 000000239990431 f= 10,0000020 M
Time= 000000299988465 Pulses= 000000249990433 f= 10,0000020 M
Time= 000000311988470 Pulses= 000000259990439 f= 10,0000019 M
Time= 000000323988465 Pulses= 000000269990437 f= 10,0000020 M
Time= 000000335988465 Pulses= 000000279990439 f= 10,0000019 M
Time= 000000347988469 Pulses= 000000289990444 f= 10,0000020 M
Time= 000000359988470 Pulses= 000000299990447 f= 10,0000020 M
Time= 000000371992447 Pulses= 000000309993763 f= 10,0000019 M
Time= 000000383992447 Pulses= 000000319993765 f= 10,0000020 M
Time= 000000395992447 Pulses= 000000329993767 f= 10,0000020 M
Time= 000000407992447 Pulses= 000000339993769 f= 10,0000020 M
Time= 000000419988470 Pulses= 000000349990457 f= 10,0000020 M
Time= 000000431992447 Pulses= 000000359993773 f= 10,0000020 M
Time= 000000443988470 Pulses= 000000369990461 f= 10,0000020 M
Time= 000000455988470 Pulses= 000000379990463 f= 10,0000020 M
Time= 000000467988469 Pulses= 000000389990464 f= 10,0000020 M
Time= 000000479988475 Pulses= 000000399990471 f= 10,0000020 M
Time= 000000491988469 Pulses= 000000409990468 f= 10,0000020 M
Time= 000000503992448 Pulses= 000000419993786 f= 10,0000020 M
Time= 000000515988469 Pulses= 000000429990472 f= 10,0000020 M
Time= 000000527988465 Pulses= 000000439990471 f= 10,0000020 M
Time= 000000539988465 Pulses= 000000449990473 f= 10,0000020 M
Time= 000000551988470 Pulses= 000000459990479 f= 10,0000020 M
Time= 000000563988465 Pulses= 000000469990477 f= 10,0000020 M
Time= 000000575988470 Pulses= 000000479990483 f= 10,0000020 M
Time= 000000587988465 Pulses= 000000489990481 f= 10,0000020 M
Time= 000000599988465 Pulses= 000000499990483 f= 10,0000020 M
Time= 000000611988470 Pulses= 000000509990489 f= 10,0000020 M
Time= 000000623988473 Pulses= 000000519990494 f= 10,0000021 M
Time= 000000635988465 Pulses= 000000529990489 f= 10,0000020 M
Time= 000000647988473 Pulses= 000000539990498 f= 10,0000020 M
Time= 000000659988473 Pulses= 000000549990500 f= 10,0000020 M
Time= 000000671988465 Pulses= 000000559990495 f= 10,0000020 M
Time= 000000683990795 Pulses= 000000569992439 f= 10,0000020 M
Time= 000000695988468 Pulses= 000000579990502 f= 10,0000021 M

La frecuencia del reloj con PLL es Fosc = 48 Mhz
La frecuencia del oscilador externo OCXO es de 10Mhz
La salida muestra una medida de frecuencia cada segundo.

La precisión de medida es de 0.01 ppm.

La precisión de 0.01 ppm se consigue promediando las diez últimas tomas de datos. Cada segundo se hace media entre las diez últimas medidas realizadas.
El filtro es de tipo FIR (finite Impulse Response) que significa que se toma la media de las diez últimas mediciones guardadas en un Buffer. Pasados 10 segundos se pierde toda memoria de la frecuencia anterior.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: KALLITOS en 20 de Junio de 2012, 13:12:00
Hola picuino, una consulta, en esos ultimos valores en las mediciones ke varian entre 17 y 20, no tiene que ver con el tiempo de ciclos de instruccion en el micro, no los puedes compensar?

Muy buen trabajo!!

saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 20 de Junio de 2012, 15:18:28
Creo que se debe a que el oscilador a cristal varía su frecuencia después de pulsar reset.
Al pulsar reset, el cristal deja de oscilar y puede que se enfríe un poco y al cabo de un tiempo la frecuencia se estabiliza.

Ten en cuenta que la variación es de 0.040 ppm! para un oscilador a cristal no está mal.

Tengo muchas mejoras aún en la cabeza, pero antes de continuar con ellas intentaré añadir un control de LCD y subir un programa que ya funcione.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 20 de Junio de 2012, 15:24:39
Después de 4 horas funcionando los dos osciladores sin parar y con una temperatura ambiente constante, la frecuencia se ha estabilizado.

Después de un reset sigue manteniéndose constante:

Código: [Seleccionar]
Time= 000001475992458 Pulses= 000001229994193 f= 10,0000041 M
Time= 000001487988481 Pulses= 000001239990883 f= 10,0000041 M
Time= 000001499988482 Pulses= 000001249990888 f= 10,0000041 M
Time= 000001511988484 Pulses= 000001259990893 f= 10,0000041 M
Time= 000001523988478 Pulses= 000001269990893 f= 10,0000041 M
Time= 000001535992461 Pulses= 000001279994216 f= 10,0000042 M
Time= 000001547988478 Pulses= 000001289990901 f= 10,0000041 M
Time= 000001559988481 Pulses= 000001299990907 f= 10,0000041 M
Time= 000001571996459 Pulses= 000001309997560 f= 10,0000042 M
Time= 000001583988481 Pulses= 000001319990916 f= 10,0000042 M
Time= 000001595992458 Pulses= 000001329994234 f= 10,0000041 M
Time= 000001607988476 Pulses= 000001339990920 f= 10,0000041 M
Time= 000001619988484 Pulses= 000001349990930 f= 10,0000040 M
Time= 000001631988476 Pulses= 000001359990928 f= 10,0000042 M
Time= 000001643988478 Pulses= 000001369990934 f= 10,0000041 M
Time= 000001655988479 Pulses= 000001379990939 f= 10,0000041 M
Time= 000001667988481 Pulses= 000001389990944 f= 10,0000041 M
Time= 000001679996459 Pulses= 000001399997597 f= 10,0000042 M
Time= 000001691988482 Pulses= 000001409990953 f= 10,0000041 M
Time= 000001703988476 Pulses= 000001419990953 f= 10,0000041 M
Time= 000001715988476 Pulses= 000001429990957 f= 10,0000041 M
Time= 000001727996456 Pulses= 000001439997611 f= 10,0000041 M
Time= 000001739988478 Pulses= 000001449990967 f= 10,0000042 M
Time= 000001751988623 Pulses= 000001459991091 f= 10,0000041 M
Time= 000001763988479 Pulses= 000001469990975 f= 10,0000040 M
Time= 000001775988479 Pulses= 000001479990979 f= 10,0000040 M
Time= 000001787988481 Pulses= 000001489990985 f= 10,0000041 M
Time= 000001799992458 Pulses= 000001499994303 f= 10,0000040 M
Time= 000001811988481 Pulses= 000001509990993 f= 10,0000041 M
Time= 000001823988476 Pulses= 000001519990993 f= 10,0000040 M
Time= 000001835996456 Pulses= 000001529997647 f= 10,0000040 M
Time= 000001847988478 Pulses= 000001539991003 f= 10,0000040 M
Time= 000001859988478 Pulses= 000001549991007 f= 10,0000040 M
Time= 000001871988478 Pulses= 000001559991011 f= 10,0000041 M
Time= 000001883988479 Pulses= 000001569991016 f= 10,0000041 M
Time= 000001895988479 Pulses= 000001579991020 f= 10,0000041 M
Time= 000001907988481 Pulses= 000001589991026 f= 10,0000041 M
Time= 000001919988481 Pulses= 000001599991030 f= 10,0000041 M
Time= 000001931988481 Pulses= 000001609991034 f= 10,0000041 M
Time= 000001943988481 Pulses= 000001619991038 f= 10,0000041 M
Time= 000001955988482 Pulses= 000001629991043 f= 10,0000041 M
Time= 000001967996456 Pulses= 000001639997692 f= 10,0000041 M
Time= 000001979988478 Pulses= 000001649991048 f= 10,0000041 M
Time= 000001991992461 Pulses= 000001659994371 f= 10,0000041 M
Time= 000002003988479 Pulses= 000001669991057 f= 10,0000041 M
Time= 000002015988479 Pulses= 000001679991061 f= 10,0000041 M
Time= 000002027988479 Pulses= 000001689991065 f= 10,0000041 M
Time= 000002039996459 Pulses= 000001699997719 f= 10,0000041 M
Time= 000002051990047 Pulses= 000001709992380 f= 10,0000041 M
Time= 000002063988482 Pulses= 000001719991079 f= 10,0000040 M
Time= 000002075992458 Pulses= 000001729994397 f= 10,0000041 M
Time= 000002087988476 Pulses= 000001739991083 f= 10,0000041 M
Time= 000002099988481 Pulses= 000001749991091 f= 10,0000041 M


La lectura es de  10000004. 1 Hz +- 0.1 Hz

La precisión por lo tanto es de +- 0.01 ppm

La exactitud que he conseguido en el oscilador de cuarzo añadiendo capacidades y suponiendo que el OCXO está bien ajustado es de:

 4.1/10M = 0.4 ppm 



Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 20 de Junio de 2012, 15:32:09
El programa ahora mismo me permite comparar dos frecuencias de las siguientes:

   1. Oscilador de cuarzo del microcontrolador
   2. Entrada de señal por la patilla T0CKI
   3. Entrada de señal por la patilla T13CKI

En el caso anterior estoy tomando como base de tiempos (TIME) la frecuencia del oscilador de cuarzo y la frecuencia a medir (PULSES) la tomo de T13CKI, donde tengo conextado el oscilador OCXO.


También se pueden comparar dos frecuencias externas entre sí (T0CKI y T13CKI) con lo cual se puede tomar como base de tiempos una frecuencia exterior muy estable para medir otra frecuencia exterior.

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 21 de Junio de 2012, 19:26:20
He publicado una versión de pruebas del programa del frecuencímetro.

El programa está escrito para C18 (compilador de Microchip) y adaptado al microprocesador PIC18F2550.

La entrada de frecuencia a medir se debe introducir en el pin T0CKI/RA4

La entrada de frecuencia de referencia de 10MHz se debe introducir en el pin RC0/T13CKI. En caso de que no exista señal en este pin, se tomará el oscilador de cristal de 20Mhz como base de tiempos.

La precisión obtenida es de 0.1 ppm con un buffer de datos de 3 segundos. Cada segundo devuelve la frecuencia media de los últimos tres segundos.

La salida de datos se realiza a través del puerto serie.

Frecuencímetro Picuino YAF versión 0.8 (https://sites.google.com/site/picuino/ocxo_10mhz/Picuino_YAF_Freqmeter_v08.zip)

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 21 de Junio de 2012, 19:36:02
Creo que necesito beta testers para poder continuar.

La versión que he publicado funciona con cualquier PIC18F2550 o PIC18F4550 sin modificación alguna.

Los ficheros ya están compilados y sólo hace falta cargar el archivo *.HEX

No es necesario añadir una referencia externa de frecuencia. Si no se conecta, el programa lo etecta automaticamente y toma como base de tiempos el oscilador a cristal externo de 20Mhz.


El único problema que veo es que por ahora envía los datos por la USART.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 22 de Junio de 2012, 12:50:40
He olvidado añadir los fuses.
Como trabajo con un bootloader, el programa se carga dando por supuesto los fuses del bootloader.

El cristal externo es de 20Mhz y la frecuencia interna es de 48Mhz producida por el PLL.

En cuanto pueda añado en el programa los fuses necesarios para hacerle independiente del bootloader.


Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 26 de Mayo de 2013, 09:25:19
Bueno, llevo varios meses sin avances y he decidido ponerme otra vez manos a la obra.

Hasta el momento había conseguido buenos resultados con las rutinas matemáticas de números enteros y de coma flotante de 48 bits, pero no conseguía una lectura estable en todo el rango de frecuencias.

Después de dos días trabajando en ello, he conseguido por fin lecturas estables en todas las frecuencias.
Ahora el problema es cómo realizar el cambio entre frecuencias. Para que el frecuencímetro pueda funcionar bien con grandes frecuencias, es necesario activar el prescaler. Por otra parte en bajas frecuencias es necesario desactivar el preescaler para que el periodo de muestreo no se haga demasiado grande.

Casi tengo terminado el programa para el PIC18F2550. Al final me he decantado por este micro porque es mucho más conocido.

En cuanto pueda pulir los detalles publico el programa. Por ahora dejo el enlace a la página web donde aparecen las características técnicas que he conseguido.

Frecuencímetro de alta precisión YAF (https://sites.google.com/site/picuino/freqmeter_yaf)

Saludos.
Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: planeta9999 en 26 de Mayo de 2013, 17:23:25


En la revista Circuit Cellar de este mes, publican un frecuencímetro de 0.1Hz a 1.5Ghz, con un PIC18F2620 y un preescaler MC12080.
El programa está hecho en C18, el código fuente completo se puede bajar por FTP de Circuit Cellar en  ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2013/275


Este es el diagrama de bloques del circuito:

(http://img109.imageshack.us/img109/6339/frecuencimetro1g5cc.jpg)

Título: Re: Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 27 de Mayo de 2013, 09:34:22
Gracias por el aporte, Planeta.
He descargado el código y lo estoy estudiando.
Por lo que he podido ver por ahora, el frecuencímetro tiene bastante resolución para altas frecuencias, pero creo que no ocurre lo mismo para las bajas.
Con las rutinas que ya tengo en marcha puedo leer la frecuencia de un oscilador de baja potencia con tres decimales:
f = 32.761236 kHz  (con error de lectura de 0.1 ppm)

El de circuit cellar daría una lectura:
f = 32.7612 kHz   (en el mejor de los casos con error de lectura de 3ppm)

Puede que no parezca mucho, pero ese error de  se traduce en un reloj en tiempo real en un segundo cada 4 días (8 segundos al mes). Si quieres ajustar el oscilador con más precisión necesitas más dígitos.

El error es todavía mayor para frecuencias más bajas:
f = 50.002532 Hz  (Lectura de la frecuencia de red con mi frecuencímetro)
f = 50.0 Hz          (Lectura de la frecuencia de red con el frecuencímetro de Circuit Cellar)

De todas formas el código tiene partes interesantes que estudiar.

Saludos.
Título: Re:Frecuencímetro 0-50Mhz autorrango y 0.1ppm (YAF)
Publicado por: Picuino en 02 de Mayo de 2020, 08:33:50
Hace tiempo que he rediseñado el frecuencímetro para un pic distinto, el PIC16F18446
todo el material está alojado en GitHub:
https://github.com/picuino/freqcounter