Microcontroller-Based Overcurrent Protective Relay

Discussion in 'Embedded Systems and Microcontrollers' started by THE^O/\/E, Jun 1, 2010.

  1. THE^O/\/E

    Thread Starter New Member

    Jun 1, 2010
    3
    0
    Hi there,

    I'm new to this forum and to the world of pic microcontrollers programming. I have a project I'm working on which is to design a microcontroller based overcurrent protective relay. I'm using pic16f877A chip along with QL200 development board. I'm programming using C and I'm using HI-Tech compiler with MPLab. I've simulated the algorithm I'm using on Matlab and everything went perfect. After that I started writing the C program and when I done with it I wrote it on the microcontroller but unfortunately it didn't work well.

    I’m using a method called (Four-Sample) method to identify the signal “basically taking one sample each ¼ of the period (T=1/f=1/60) and using these samples to calculate the RMS value of the current to be monitored”. After getting the RMS value I used another algorithm to implement the relaying decision part of the program. It is required to display the current value in the three lines continuously in the normal condition and then if fault occurs, the program shows a massage on the LCD and the program stop. The LCD I’m using is 128*64 dots LCD.

    Note/ I’ve tested the time required to execute the code completely from the beginning to the end and I got 6 seconds!!!. I need to take a one sample every 4.167ms that’s for the three lines!!!

    Here is my code. Any help would be appreciated.

    Regards,
     
  2. THE^O/\/E

    Thread Starter New Member

    Jun 1, 2010
    3
    0
    Code ( (Unknown Language)):
    1.  
    2. ///////////////
    3. //
    4. // taking analog input for three lines from port E
    5. // and using port A as a control unit for the LCD
    6. //
    7. //
    8. /////////////////////
    9.  
    10. #include<pic.h>
    11.  
    12. #include<math.h>
    13. __CONFIG(0x1832);
    14. #define  rs  RA5                    //COMMNAD/DATA SELECT
    15. #define  rw  RA4                    //READ/WRITE SELECT
    16. #define  e   RA3                    //ENABLE SIGNAL
    17. #define  psb RA2                    //PARALLEL/SERIAL SELECT£¨H/L£©
    18. #define  rst RA0                    //RESET SIGNAL
    19. #define  nop()  asm("nop")          //nop func
    20.  
    21. unsigned char MM[9];
    22.  
    23. const unsigned char NNA[ ]={' ',' ','F','A','U','L','T',' ','O','C',' ','L','A'};
    24. const unsigned char NNB[ ]={' ',' ','F','A','U','L','T',' ','O','C',' ','L','B'};
    25. const unsigned char NNC[ ]={' ',' ','F','A','U','L','T',' ','O','C',' ','L','C'};
    26.  
    27. unsigned int lcd_x;                //X address
    28. unsigned int lcd_y;                //Y address
    29.  
    30. bit busy;                          //busy flag
    31.  
    32. void display(int x,unsigned int y);
    33. void fault(int r);
    34. void init();                        //system init.
    35. void lcd_init();                    //LCD init
    36. void clear_p();                    //clear screen
    37. void flash();
    38. void wr_zb();                       //display setting mode.
    39. void qushu(int counts,const unsigned char *ps);       //search table.
    40. void send_d(unsigned char x);       //send data
    41. void send_i(unsigned char x);       //send command.
    42. void chk_busy();                    //check busy sub.
    43. void delay();                       //delay func, decide the speed of display.
    44. void delay1();                      //delay func, decide the speed of blink.
    45. void delay2();                      //delay func, to insure saving sample.
    46. void delayad();                     //delay func, to insure the 4 samples per cycle.
    47. void main()
    48. {
    49.       int i=0x0;
    50.       int j=0x0;
    51.    
    52.       unsigned int A[4];
    53.       unsigned int B[4];
    54.       unsigned int Q[4];
    55.       unsigned int a1=0x0;
    56.       unsigned int b1=0x0;
    57.       unsigned int q1=0x0;
    58.       unsigned int ip1=0x0;
    59.       unsigned int ip2=0x0;
    60.       unsigned int ip3=0x0;
    61.       unsigned int pp=0x0;
    62.       unsigned int s=0x0;
    63.       unsigned int c=0x0;
    64.       unsigned int ipick=0x0231;
    65.  
    66.         //-------
    67.  
    68.       ADRESH=0x0;
    69.       ADRESL=0x0;
    70.  
    71.       //-------
    72.  
    73.       TRISA=0xFF;
    74.       PORTA=0X00;
    75.       TRISE=0x07;
    76.       PORTC=0X00;
    77.  
    78.       ADCON1=0x80;
    79.       for(i=0;i<4;)
    80.                   {
    81.                   /////////////////////////
    82.                    ADRESH=0x0;
    83.                    ADRESL=0x0;
    84.                    ADCON0=0x41;      // teke analog from RE0 >> line A
    85.                    ADGO=0X1;             //start convert
    86.  
    87.                    while(ADGO);
    88.                    delay2();   // i<0x5
    89.  
    90.                    A[i]= ADRESH << 8 | ADRESL;
    91.  
    92.                    /////////////////////////
    93.  
    94.                    /////////////////////////
    95.  
    96.                   ADRESH=0x0;
    97.                   ADRESL=0x0;
    98.                   ADCON0=0x71;     // take analog input from RE1 >> line B
    99.                   ADGO=0X1;             //start convert
    100.  
    101.                   while(ADGO);
    102.  
    103.                   delay2();   // i<0x5
    104.  
    105.                   B[i]= ADRESH << 8 | ADRESL;
    106.  
    107.                   /////////////////////////
    108.  
    109.                   ADRESH=0x0;
    110.                   ADRESL=0x0;
    111.                   ADCON0=0x79;     // take analog input from RE2 >> line C
    112.                   ADGO=0X1;             //start convert
    113.  
    114.                   while(ADGO);
    115.  
    116.                   delay2();   // i<0x5
    117.  
    118.                   Q[i]= ADRESH << 8 | ADRESL;
    119.  
    120.                   /////////////////////////
    121.  
    122.                   delayad();
    123.       i++;
    124.  
    125.       }
    126.  
    127.       while(1)
    128.  
    129.       {
    130.               //-------
    131.  
    132.               ADRESH=0x0;
    133.               ADRESL=0x0;
    134.               //-------
    135.               TRISA=0xFF;
    136.               PORTA=0X00;
    137.               TRISE=0x07;
    138.               PORTC=0X00;
    139.               TRISB=0x0;
    140.               PORTB=0x01;
    141.  
    142.               //-------
    143.  
    144.               ADCON1=0x80;
    145.  
    146.               //-------
    147.  
    148.                ADRESH=0x0;
    149.                ADRESL=0x0;
    150.                ADCON0=0x69;      // teke analog from RE0 >> line A
    151.                ADGO=0X1;             //start convert
    152.  
    153.                while(ADGO);
    154.  
    155.                delay2();   // i<0x5
    156.  
    157.                a1= ADRESH << 8 | ADRESL;
    158.  
    159.                /////////////////////////
    160.  
    161.               ADRESH=0x0;
    162.               ADRESL=0x0;
    163.               ADCON0=0x71;     // take analog input from RE1 >> line B
    164.               ADGO=0X1;             //start convert
    165.  
    166.               while(ADGO);
    167.  
    168.               delay2();   // i<0x5
    169.  
    170.               b1= ADRESH << 8 | ADRESL;
    171.  
    172.               /////////////////////////
    173.  
    174.               ADRESH=0x0;
    175.               ADRESL=0x0;
    176.               ADCON0=0x79;     // take analog input from RE2 >> line C
    177.               ADGO=0X1;             //start convert
    178.  
    179.               while(ADGO);
    180.  
    181.               delay2();   // i<0x5
    182.  
    183.               q1= ADRESH << 8 | ADRESL;
    184.  
    185.               /////////////////////////
    186.  
    187.               for(i=0;i<3;)      // shift the samples in the arrays to make room for
    188.  
    189.               {                  // the new sample
    190.  
    191.               A[i]=A[i+1];
    192.               B[i]=B[i+1];
    193.               Q[i]=Q[i+1];
    194.  
    195.               i++;
    196.  
    197.               }
    198.  
    199.               A[3]=a1;
    200.               B[3]=b1;
    201.               Q[3]=q1;
    202.  
    203.               //---------
    204.               s=0x0;
    205.               c=0x0;
    206.      
    207.               s=A[0]+A[1]-A[2]-A[3];
    208.               c=A[0]-A[1]-A[2]+A[3];
    209.  
    210.               ip1=(sqrt((s*s)+(c*c)));
    211.               ip1=ip1>>2; // ip1/4
    212.  
    213.               //---------
    214.               s=0x0;
    215.               c=0x0;
    216.               s=B[0]+B[1]-B[2]-B[3];
    217.               c=B[0]-B[1]-B[2]+B[3];
    218.  
    219.               ip2=sqrt(((s*s)+(c*c)));
    220.               ip2=ip2>>2;
    221.  
    222.               //----------
    223.               s=0x0;
    224.               c=0x0;
    225.               s=Q[0]+Q[1]-Q[2]-Q[3];
    226.               c=Q[0]-Q[1]-Q[2]+Q[3];
    227.  
    228.               ip3=sqrt(((s*s)+(c*c)));
    229.               ip3=ip3>>2;
    230.  
    231.                //-----------------------
    232.  
    233.                // scale the voltage level here to the value of the current before
    234.  
    235.                // the conditioning circuit.
    236.  
    237.                //-----------------------
    238.                //ip3=0x0275;
    239.  
    240.               init();                 //initiate the ports for the LCD display
    241.  
    242.           lcd_init();    //LCD initiation.      
    243.  
    244.                         clear_p();    //LCD clear
    245.  
    246.                      //pp=(A[0]+A[1]+A[2]+A[3])/4;
    247.  
    248.                display(0x1,pp);
    249.  
    250.                display(0x2,ip2);
    251.  
    252.                display(0x3,ip3);
    253.  
    254.                //-------
    255.  
    256.                // disicion
    257.  
    258.                //-------
    259.  
    260.               if(ip1>ipick)
    261.  
    262.               {
    263.  
    264.                 fault(0x1);
    265.  
    266.               }
    267.  
    268.               //else
    269.  
    270.               //{ display(0x1,ip1); }
    271.  
    272.              
    273.               if(ip2>ipick)
    274.  
    275.               {
    276.  
    277.                 fault(0x2);
    278.  
    279.               }
    280.  
    281.               //else
    282.  
    283.               //{ display(0x2,ip2); }
    284.  
    285.               if(ip3>ipick)
    286.  
    287.               {
    288.  
    289.                 fault(0x3);
    290.  
    291.               }
    292.  
    293.              // else
    294.  
    295.              // { display(0x3,ip3); }
    296.  
    297.          PORTB=0x0;
    298.  
    299.              delay1();  
    300.  
    301.         } // end of the while(1) loop
    302.  
    303.  
    304. }  // end of main function
    305. ///-------------------------------------
    306. void display(int x,unsigned int y)
    307.  
    308. {
    309.         if(x==0x1)
    310.  
    311.          {
    312.  
    313.           MM[0]=76;                // L
    314.           MM[1]=45;                // -
    315.           MM[2]=49;                // 1
    316.           MM[3]=61;                // =
    317.           MM[4]=(5*y/1024)+48;     // first digit
    318.           MM[5]=46;                // point (.)
    319.           MM[6]=((50*y/1024)%10)+48; // second digit
    320.           MM[7]=((20*y/41)%10)+48;   // third digit
    321.           MM[8]=65;                 //  A for Amp
    322.  
    323.           send_i(0x80);  /// search what is the thing
    324.           qushu(0x9,MM);
    325.  
    326.          }
    327.  
    328.          if(x==0x2)
    329.  
    330.          {
    331.  
    332.           MM[0]=76;                 // L
    333.           MM[1]=45;                 // -
    334.           MM[2]=50;                 // 2
    335.           MM[3]=61;                 // =
    336.           MM[4]=(5*y/1024)+48;      // first digit
    337.           MM[5]=46;                 // point (.)
    338.           MM[6]=((50*y/1024)%10)+48; // second digit
    339.           MM[7]=((20*y/41)%10)+48;  // third digit
    340.           MM[8]=65;                 // A for Amp
    341.  
    342.          send_i(0x90);
    343.           qushu(0x9,MM);
    344.  
    345.          }
    346.  
    347.          if(x==0x3)
    348.  
    349.          {
    350.  
    351.           MM[0]=76;               // L
    352.           MM[1]=45;              // -
    353.           MM[2]=51;               // 3
    354.           MM[3]=61;               // =
    355.           MM[4]=(5*y/1024)+48;    // first digit
    356.           MM[5]=46;               // point (.)
    357.           MM[6]=((50*y/1024)%10)+48; // second digit
    358.           MM[7]=((20*y/41)%10)+48;  // third digit
    359.           MM[8]=65;                // A for Amp
    360.  
    361.           send_i(0x88);
    362.           qushu(0x9,MM);
    363.  
    364.          }
    365.  
    366.         delay1();                     //
    367.  
    368.         //clear_p();                   //
    369. }[/i][/i][/i][/i][/i][/i]
     
  3. THE^O/\/E

    Thread Starter New Member

    Jun 1, 2010
    3
    0
    //----------------
    void fault(int r)

    {

    init(); //system init.
    lcd_init(); //
    clear_p(); //
    send_i(0x90);

    if(r==0x1)

    {

    qushu(0xd,NNA);

    }

    if(r==0x2)

    {

    qushu(0xd,NNB);

    }



    if(r==0x3)

    {

    qushu(0xd,NNC);

    }
    delay1(); //
    flash();
    clear_p();

    }

    //----------

    void flash()

    {

    send_i(0x08); //off display.
    delay1(); //delay
    send_i(0x0c); //on display
    delay1();
    delay1(); //delay
    send_i(0x08); //off
    delay1();
    send_i(0x0c); //on
    delay1();
    delay1();
    send_i(0x08); //off
    delay1();
    send_i(0x0c); //on
    delay1();
    delay1();
    }

    //------------

    void init()

    {

    TRISA=0X00; //A port as output
    TRISD=0X00; //d port as output
    ADCON1=0X06; //A port as ordinary i/o
    }

    /////

    void lcd_init()

    {

    rst=0; //reset LCD
    delay();
    rst=1; //LCD normal work.
    nop();
    psb=1; //8 bit as parrallel.
    send_i(0x30); //basic operation instruction
    send_i(0x01); //off display
    send_i(0x06); //set the cursor's moving direction.
    send_i(0x0c); //on display,off cursor,off blink
    }

    ////

    void wr_zb()

    {

    send_i(lcd_y);
    send_i(lcd_x);

    }

    /////

    void clear_p()

    {

    send_i(0x1); //clear all
    send_i(0x34); //extend.
    send_i(0x30); //basic

    }

    ////

    void qushu(int counts,const unsigned char *ps)

    {

    int i; //define loop count.

    for(i=counts;i>0;i--) //

    {

    send_d(*ps); //
    delay(); //
    ps++; //get next.

    }

    }

    ////

    void send_d(unsigned char x)

    {

    chk_busy(); //check busy.
    rs=1; //data not commnad.
    rw=0; //write not read.
    PORTD=x; //data to bus.
    e=1; //enable.
    nop();
    nop();
    nop();
    e=0; //disable.
    }

    ////

    void send_i(unsigned char x)

    {

    chk_busy(); //check lcd if busy.
    rs=0; //data not commnad.
    rw=0; //write not read.
    PORTD=x; //data to bus.
    e=1; //enable.
    nop();
    nop();
    nop();
    e=0; //disable.

    }

    ////

    void chk_busy()

    {

    busy=1; //set busy signal
    TRISD=0XFF; //change the bus to input.
    rs=0; //command not data.
    rw=1; //read not write.
    while(busy)
    {

    nop();
    nop();
    nop();
    e=1; //enable.
    nop();
    nop();
    nop();
    if(!RD7) busy=0; //
    nop();
    nop();
    nop();
    e=0; //DISABLE.
    }
    e=0; //DISABLE.
    TRISD=0X00; //bus as output.
    }

    ////

    void delayad()

    {

    int i;

    for(i=0;i<0x100;i++)

    {;}
    }

    ////

    void delay()

    {

    int i;

    for(i=0;i<5000;i++)

    {;}

    }

    //-------------------------------------------

    //delay1

    void delay1()

    {

    int i;

    for(i=0;i<10;i++)

    {

    delay(); //call delay.

    }

    }

    ////

    void delay2()

    {

    int i;

    for(i=0;i<0x5;i++)

    {;}

    }
    [/code]
     
Loading...