Autor Tema: Frecuencia de red  (Leído 9129 veces)

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

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 17764
    • MicroPIC
Re: Frecuencia de red
« Respuesta #30 en: 03 de Mayo de 2012, 15:39:45 »
Permíteme un consejo si es que no lo has hecho todavía: prueba tu algoritmo de medición con el debugger de MPLAB y su función Stopwatch si los ciclos que estás contando son exactamente los que esperas contar.
Como sabes, hay instrucciones que ocupan más ciclos que otras, y también se producen retrasos en el salvado de contexto al entrar en la interrupción, lo que provoca que sea un tormento calcular exactamente el delay de instrucciones hasta conseguir tu timer con precisión.
Con Stopwatch sabrás exactamente los ciclos consumidos y podrás hacer los cálculos que correspondan.
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

Desconectado Picuino

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5420
Re: Frecuencia de red
« Respuesta #31 en: 03 de Mayo de 2012, 16:32:02 »
Gracias Nocturno. No conozco esa función porque antes no la podía utilizar con el bootloader que tenía.
Ahora tengo el Pickit3 y lo apunto en tareas para hacer.

Por ahora no lo voy a necesitar porque he cambiado de forma de tomar datos. Ahora los tomo de forma automática con el módulo capture. Es mucho más preciso.


Programa contador de frecuencia utilizado:

Código: C
  1. /****************************************************************************
  2.  Precision Frequency counter
  3.  
  4.  Processor:  PIC 18F2550
  5.  Input Pin:  RC2 / CPP1
  6.  
  7.  Base frequency:
  8.     Timer1 counting Fosc/4
  9.  
  10.  Count mode:
  11.    Capture Timer1 count at CPP1 falling edge
  12.    Send both values in hexadecimal by UART
  13.  
  14. ****************************************************************************/
  15.  
  16. #include <p18cxxx.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <delays.h>
  20. #include "main.h"
  21.  
  22. /****************************************************************************
  23.       GLOBAL VARS AND DEFINITIONS
  24.  ****************************************************************************/
  25. #pragma udata
  26. char str_buf[20];
  27. static unsigned char sys_clk, cent_second;
  28. static unsigned short timer1_carry;  // Timer1 extended counter
  29.  
  30. // Timer1 long counter (48 bits)
  31. union {
  32.    struct {
  33.       unsigned int _word;
  34.       unsigned long dword;
  35.    };
  36.    unsigned int  word[3];
  37.    unsigned char byte[6];
  38. } timer1_count, timer1_capture;
  39.  
  40.  
  41. #define TMR0_COUNT      (FOSC/((unsigned long)4*250*100))      // Number of carrys per second
  42. #define FOSC 20000000    // clock oscillator
  43. #define BAUD 57600       // usart baud speed
  44.  
  45.  
  46. /****************************************************************************
  47.       INTERRUPT SERVICE ROUTINE
  48.  ****************************************************************************/
  49.  
  50. #pragma interrupt isr_main
  51. void isr_main(void) {
  52.  
  53.    // Timer1 interrupt counter
  54.    if (PIR1bits.TMR1IF == 1) {
  55.        PIR1bits.TMR1IF = 0;
  56.        timer1_count.dword++;
  57.    }
  58. }
  59.  
  60.  
  61. #pragma code high_vector=0x08
  62. void isr_high(void) {
  63.    _asm GOTO isr_main  _endasm
  64. }
  65.  
  66. #pragma code
  67.  
  68.  
  69. /****************************************************************************
  70.       USART AND RS232 FUNCTIONS
  71.  ****************************************************************************/
  72.  
  73. /*
  74.   Initialize USART for RS232 comunications
  75. */
  76.  
  77. void rs232_init(void) {
  78.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  79.    SPBRGH = 0;
  80.    SPBRG = (FOSC/(16*BAUD))-1;   // Real Baud = FOSC/(16*(SPBRG+1))
  81.  
  82.    TXSTA = (char)
  83.            (0<<7)    // CSRC:  1 = Syncronous Master mode
  84.          + (0<<6)    // TX9:   1 = Selects 9-bit transmission
  85.          + (1<<5)    // TXEN:  1 = Transmit enabled
  86.          + (0<<4)    // SYNC:  1 = Synchronous mode
  87.          + (0<<3)    // SENDB: 1 = Asynchronous mode: Send Sync Break on next transmission (cleared by hardware upon completion)
  88.          + (1<<2)    // BRGH:  1 = Asynchronous mode: High speed
  89.          + (1<<1)    // TRMT:  1 = TSR empty
  90.          + (0<<0);   // TX9D:  Ninth bit of Transmit Data
  91.  
  92.    RCSTA = (char)
  93.            (1<<7)    // SPEN:  1 = Serial port enabled
  94.          + (0<<6)    // RX9:   1 = Selects 9-bit reception
  95.          + (0<<5)    // SREN:  1 = Enables single receive in Master Synchronous mode
  96.          + (1<<4)    // CREN:  1 = Enables Continuous Receive
  97.          + (0<<3)    // ADDEN: 1 = Enables address detection (RX9 = 1)
  98.          + (0<<2)    // FERR:  1 = Framing error
  99.          + (0<<1)    // OERR:  1 = Overrun error (can be cleared by clearing bit CREN)
  100.          + (0<<0);   // RX9D:  Ninth bit of Received Data
  101.  
  102.    TRISCbits.TRISC6 = 0;      // Enable TX output
  103.    PIE1bits.TXIE = 0;         // Disable RS232 interrupts
  104.    PIR1bits.TXIF = 0;
  105.    //TXREG = 0;
  106. }
  107.  
  108.  
  109. /*
  110.    Puts rom buffer to usart
  111. */
  112. void rs232_puts(char const rom *str) {
  113.    while(*str) {
  114.       if (*str == '\n')
  115.          rs232_putc('\r');
  116.       rs232_putc(*str);
  117.       str++;
  118.    }
  119. }
  120.  
  121. /*
  122.    Send char to USART with pooling
  123. */
  124. void rs232_putc(char c) {
  125.    while (PIR1bits.TXIF == 0);
  126.    TXREG = c;
  127. }
  128.  
  129.  
  130. /*
  131.    Return Hexadecimal character of a nibble
  132. */
  133. char Hexdec(char nibble) {
  134.    char bin2hex[] = "0123456789ABCDEF";
  135.    return bin2hex[nibble & 0x0F];
  136. }
  137.  
  138.  
  139. /****************************************************************************
  140.       CAPTURE MODE
  141.       Timer1 counts time
  142.       Input by CCP1
  143.  ****************************************************************************/
  144.  
  145. void capture_init(void) {
  146.    T1CON = (unsigned char)
  147.        (1<<7)    // RD16: 1 = 16-Bit Read/Write Mode Enable bit
  148.       +(0<<6)    // T1RUN: 1 = Device clock is derived from Timer1 oscillator
  149.       +(0b00<<4) // T1CKPS: Timer1 Input Clock Prescale Select bits
  150.                  // 11 = 1:8 Prescale value
  151.                  // 10 = 1:4 Prescale value
  152.                  // 01 = 1:2 Prescale value
  153.                  // 00 = 1:1 Prescale value
  154.       +(0<<3)    // T1OSCEN: 0 = Timer1 oscillator is shut off
  155.       +(1<<2)    // T1SYNC: 1 = Do not synchronize external clock input
  156.       +(0<<1)    // TMR1CS: 1 = External clock from RC0 pin, 0 = Internal clock (FOSC/4)
  157.       +(1<<0);   // TMR1ON: 1 = Enables Timer1
  158.  
  159.    // Reset Timer1 counters
  160.    TMR1H = 0;
  161.    TMR1L = 0;
  162.    timer1_count.word[0] = 0;
  163.    timer1_count.word[1] = 0;
  164.    timer1_count.word[2] = 0;
  165.  
  166.    // Reset Timer1 interrupts
  167.    PIR1bits.TMR1IF = 0;
  168.    PIE1bits.TMR1IE = 1;
  169.    INTCONbits.GIE = 1;  
  170.    INTCONbits.PEIE = 1;
  171.  
  172.  
  173.    // CCP1 config
  174.    TRISCbits.TRISC2 = 1;  // CPP1 input
  175.    CCP1CON = 0b00000100;  // Capture every falling edge. Prescaler = 1
  176.    CCPR1H = 0;
  177.    CCPR1L = 0;
  178.    PIR1bits.CCP1IF = 0;
  179.    PIE1bits.CCP1IE = 0;
  180.  
  181.    T3CONbits.T3CCP1 = 0; // Timer1 is the capture clock source for both CCP modules.
  182.    T3CONbits.T3CCP1 = 0;
  183. }
  184.  
  185.  
  186. void capture_read(void) {
  187.    // Wait for falling edge
  188.    while (PIR1bits.CCP1IF == 0);
  189.    PIR1bits.CCP1IF = 0;
  190.  
  191.    // Read timer1
  192.    timer1_capture.byte[0] = CCPR1L;
  193.    timer1_capture.byte[1] = CCPR1H;
  194.  
  195.    // Read timer1 overflow counter
  196.    timer1_capture.dword = timer1_count.dword;
  197.    timer1_count.byte[0] = TMR1L;
  198.    timer1_count.byte[1] = TMR1H;
  199.    if (timer1_count.word[0] < timer1_capture.word[0]) {
  200.       timer1_capture.dword = timer1_count.dword-1;
  201.    }
  202. }
  203.  
  204.  
  205. /****************************************************************************
  206.       MAIN PROGRAM
  207.  ****************************************************************************/
  208. #pragma code
  209.  
  210. #define PPB_ERROR  (2900)
  211.  
  212. /*
  213.    MAIN ROUTINE
  214. */
  215. void main(void) {
  216.    int i;
  217.    union {
  218.        unsigned char byte[4];
  219.        unsigned long dword;
  220.    } pulses;
  221.  
  222.    // Initialize subsystems
  223.    rs232_init();
  224.    capture_init();
  225.    pulses.dword = 0;
  226.  
  227.    
  228.    // Pulse and time counter
  229.    while(1) {
  230.  
  231.       // Wait 100 pulses
  232.       for(i=100; i>0; i--) {
  233.          capture_read();
  234.          pulses.dword++;
  235.       }
  236.  
  237.       // Print Time count by Timer1
  238.       rs232_puts("t=\t");
  239.       //rs232_putc(Hexdec(timer1_capture.byte[5]<<4));
  240.       //rs232_putc(Hexdec(timer1_capture.byte[5]));
  241.       rs232_putc(Hexdec(timer1_capture.byte[4]>>4));
  242.       rs232_putc(Hexdec(timer1_capture.byte[4]));
  243.       rs232_putc(Hexdec(timer1_capture.byte[3]>>4));
  244.       rs232_putc(Hexdec(timer1_capture.byte[3]));
  245.       rs232_putc(Hexdec(timer1_capture.byte[2]>>4));
  246.       rs232_putc(Hexdec(timer1_capture.byte[2]));
  247.       rs232_putc(Hexdec(timer1_capture.byte[1]>>4));
  248.       rs232_putc(Hexdec(timer1_capture.byte[1]));
  249.       rs232_putc(Hexdec(timer1_capture.byte[0]>>4));
  250.       rs232_putc(Hexdec(timer1_capture.byte[0]));
  251.       rs232_puts("\t*200ns\t");
  252.  
  253.       // Print falling edges counted
  254.       rs232_puts("N=\t");
  255.       rs232_putc(Hexdec(pulses.byte[2]>>4));
  256.       rs232_putc(Hexdec(pulses.byte[2]));
  257.       rs232_putc(Hexdec(pulses.byte[1]>>4));
  258.       rs232_putc(Hexdec(pulses.byte[1]));
  259.       rs232_putc(Hexdec(pulses.byte[0]>>4));
  260.       rs232_putc(Hexdec(pulses.byte[0]));
  261.       rs232_puts("\n");
  262.    }
  263. }
  264.  
  265.  


Datos en bruto devueltos por el microcontrolador:

t=   00004BD7C3   *200ns   N=   000064
t=   00009827A6   *200ns   N=   0000C8
t=   0000E478E4   *200ns   N=   00012C
t=   000130CA99   *200ns   N=   000190
t=   00017D1C4B   *200ns   N=   0001F4
t=   0001C96EC3   *200ns   N=   000258
t=   000215C1B4   *200ns   N=   0002BC
t=   00026213BD   *200ns   N=   000320
t=   0002AE6589   *200ns   N=   000384
t=   0002FAB94A   *200ns   N=   0003E8
t=   0003470E68   *200ns   N=   00044C
t=   00039362EE   *200ns   N=   0004B0
t=   0003DFB632   *200ns   N=   000514
t=   00042C098D   *200ns   N=   000578
t=   0004785D00   *200ns   N=   0005DC
t=   0004C4AF9B   *200ns   N=   000640
t=   0005110105   *200ns   N=   0006A4
t=   00055D50E5   *200ns   N=   000708
t=   0005A9A016   *200ns   N=   00076C




Función excel para procesar datos hexadecimales:

Código: Visual Basic
  1. Function Hex2dec(str)
  2.     Dim n As Double
  3.     l = Len(str)
  4.     n = 0
  5.     For i = 1 To l
  6.        c = Mid(str, i, 1)
  7.        If c >= "0" And c <= "9" Then
  8.           d = Asc(c) - Asc("0")
  9.        Else
  10.           d = Asc(c) - Asc("A") + 10
  11.        End If
  12.        n = n * 16 + d
  13.     Next
  14.     Hex2dec = n
  15. End Function
  16.  



Datos procesados con Excel:

Tiempo   Pulsos   Frecuencia   Error de tiempo   [ms]   
 0,994087    100   100,594817   -5,913
 1,994324    200   100,284588   -5,676
 2,994631    300   100,179281   -5,369
 3,994962    400   100,126114   -5,038
 4,995292    500   100,094253   -4,708
 5,995661    600   100,072362   -4,339
 6,996055    700   100,056386   -3,945
 7,996403    800   100,044988   -3,597
 8,996738    900   100,036260   -3,262
 9,997173   1000   100,028276   -2,827
10,997678   1100   100,021110   -2,322
11,998153   1200   100,015392   -1,847
12,998564   1300   100,011050   -1,436
13,998979   1400   100,007296   -1,021
14,999398   1500   100,004011   -0,602
15,999775   1600   100,001406   -0,225
17,000091   1700    99,999467   0,091
18,000327   1800    99,998181   0,327
19,000529   1900    99,997215   0,529
20,000706   2000    99,996468   0,706
21,000850   2100    99,995952   0,850
22,000893   2200    99,995940   0,893
23,000904   2300    99,996069   0,904
24,000921   2400    99,996162   0,921





Gráfica de desfase de frecuencia de red:





El error máximo es de 3ppm. (1 milisegundo de error en el periodo de 300segundos de muestreo)

Saludos.

Saludos
« Última modificación: 03 de Mayo de 2012, 18:23:52 por Picuino »

Desconectado Picuino

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5420
Re: Frecuencia de red
« Respuesta #32 en: 03 de Mayo de 2012, 19:04:23 »
Documentación legal española sobre el "Establecimiento de la reserva para la regulación frecuencia-potencia":
   Resolucion 13/julio/2006: http://www.ree.es/operacion/pdf/po/RES_PO_1.5.pdf


Procedimientos de operación de la red eléctrica española:
   http://www.ree.es/operacion/procedimientos_operacion.asp


Curva de demanda eléctrica en tiempo real:
    https://demanda.ree.es/demanda.html

Datos tomados de la web de red eléctrica española REE:
   http://www.ree.es/home.asp



Curva de desfase de frecuencia tomado de 23:22h a 24:00h del 04/05/2012:





Saludos.


« Última modificación: 03 de Mayo de 2012, 19:08:43 por Picuino »

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Frecuencia de red
« Respuesta #33 en: 03 de Mayo de 2012, 21:40:48 »
Pon a medir la red de mi pueblo, te sorprenderas  :D los dias de tormenta puede que hasta se te queme el circuito

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 17764
    • MicroPIC
Re: Frecuencia de red
« Respuesta #34 en: 04 de Mayo de 2012, 02:09:50 »
Gracias Nocturno. No conozco esa función porque antes no la podía utilizar con el bootloader que tenía.
Ahora tengo el Pickit3 y lo apunto en tareas para hacer.


No necesitas nada, sólo el MPLAB. Lo pones en modo MPLAB SIM y ejecutas paso a paso en el simulador.
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

Desconectado Picuino

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5420
Re: Frecuencia de red
« Respuesta #35 en: 04 de Mayo de 2012, 09:54:42 »
Gracias Nocturno. No conozco esa función porque antes no la podía utilizar con el bootloader que tenía.
Ahora tengo el Pickit3 y lo apunto en tareas para hacer.


No necesitas nada, sólo el MPLAB. Lo pones en modo MPLAB SIM y ejecutas paso a paso en el simulador.

No lo conocía. Me vendrá bien para depurar programas, gracias.

Me gustaría comprobar que las mediciones de red pueden servir para sincronizar relojes. ¿Alguien se anima a medir la frecuencia de red?

Saludos.

Desconectado jansuini

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 557
Re: Frecuencia de red
« Respuesta #36 en: 04 de Mayo de 2012, 17:58:27 »
Te comento desde ya :si necesitas buena sincronización ,la frecuencia de red no sirve ,para ello lo mas preciso es usar un gps.-
Sds.
Jorge

Desconectado Picuino

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5420
Re: Frecuencia de red
« Respuesta #37 en: 04 de Mayo de 2012, 18:20:42 »
¿Cómo se puede usar un GPS normal para calibrar un oscilador?


Saludos.

Desconectado jansuini

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 557
Re: Frecuencia de red
« Respuesta #38 en: 04 de Mayo de 2012, 21:09:35 »
No digo para calibrar un oscilador ,sino sincronizar relojes ,asi y todo no es un gps tan "normal" sino uno que tenga salida de pulso por segundo ,que cualquer placa de gps OEM lo trae.-
Sds.
Jorge

Desconectado Picuino

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5420
Re: Frecuencia de red
« Respuesta #39 en: 05 de Mayo de 2012, 09:22:21 »
Aunque he puesto en el post anterior "sincronizar relojes" en realidad lo que quería decir es afinar o ajustar un reloj con otro que sirva de patrón.
Si consigo ajustar un oscilador OCXO de esos que venden en e-bay, con un error de 0.1ppm,  me puede servir de base para ajustar el resto de aparatos del laboratorio.

El problema que le veo al GPS es que te tienes que ir a la calle para que tenga cobertura y que la salida de 1 segundo tiene poca frecuencia para calibrar un frecuencímetro.

Saludos.


 

anything