Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Motor DC, speed control using PI (need helps)

Status
Not open for further replies.

royanto

Newbie level 3
Joined
May 23, 2011
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Indonesia
Activity points
1,305
i'm designing a digital PID controller to control the speed of a motor DC..
I'm using the jennic JN5139 micro and Codeblocks,,

My problems are i can't get the correct feedback values from the tacho and also the correct control signal..
Also i think i have an error on the ADCs

I need help immedietly to know what is wrong with my code..

The code i've reached so far is..


Code:
#include <jendefs.h>
#include <AppHardwareApi.h>
#include <AppQueueApi.h>


PRIVATE void vAdc_Config(void);
PRIVATE void vTimerConfig(void);

PRIVATE void vUART_Init(void);
PRIVATE void vDebug(char *pcMessage);
PRIVATE void vDisplayHex(uint32 u32Data, int iSize);

uint16 u16ADC1_Result; // set point from potentiometer
uint16 u16ADC2_Result; // feedback from Tachogenerator

int Ts = 0;//time sampling
float Kp = 0.85;// Kp 
float b0,b1,b2;
float e0=0, e1=0, e2=0, u0=0, u1=0;
uint T=0.06;


/****************************************************************************
 *
 * NAME: AppColdStart
 *
 * DESCRIPTION:
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * Entry point for a power on reset or wake from sleep mode.
 ****************************************************************************/
PUBLIC void AppColdStart(void)
{
    uint16 u16ADC1_Result;

       /* Initialise stack and hardware interfaces */
   // (void)u32AppQApiInit(NULL,NULL,NULL);
    (void)u32AHI_Init();

       /* Initialise the serial port and rx/tx queues */
    vUART_Init();

    vAdc_Config();  /* convert on chanel 1*/

    /* now sit in this loop and run the control loop */
    while(1)
    {
        vAHI_AdcEnable(E_AHI_ADC_SINGLE_SHOT,
                       E_AHI_AP_INPUT_RANGE_2,
                       E_AHI_ADC_SRC_ADC_1);    /* enable ADC1 for setpoint */

        vAHI_AdcStartSample();              /* start an AtoD sample here */
        while(bAHI_AdcPoll() != 0x00);      /* wait for convertion complete */
        u16ADC1_Result = u16AHI_AdcRead();  /* save AtoD result */

        vDebug("\n\rSETPOINT = ");
        vDisplayHex(u16ADC1_Result,4);
        vAHI_AdcDisable();

        /* enable ADC2 for feedback */
        vAHI_AdcEnable(E_AHI_ADC_SINGLE_SHOT,
                       E_AHI_AP_INPUT_RANGE_2,
                       E_AHI_ADC_SRC_ADC_2);

        vAHI_AdcStartSample();              /* start an AtoD sample here */
        while(bAHI_AdcPoll() != 0x00);      /* wait for convertion complete */

        u16ADC2_Result = u16AHI_AdcRead();  /* save AtoD result */

        vDebug("\n\rFEEDBACK = ");
        vDisplayHex(u16ADC2_Result,4);
        vAHI_AdcDisable();

        /* determines b0, b1 dan b2 values*/
        b0=Kp+(Ki*T/2);  //original form b0=Kp+(Ki*T/2)+(Kd/T)  where Kd=0
        b1=((Ki*T)/2)-Kp; // original form b1=(Ki*T/2)-Kp-(2*Kd/T);
        b2=0;           // original form b2=Kd/T


        for (Ts=0;Ts<10;Ts++)
        {
            vTimerConfig();
        }

    }

}


/****************************************************************************
 *
 * NAME: AppWarmStart
 *
 * DESCRIPTION:
 * Entry point for a wake from sleep mode with the memory contents held. We
 * are not using this mode and so should never get here.
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * None.
 ****************************************************************************/
PUBLIC void AppWarmStart(void)
{
    AppColdStart();
}


/****************************************************************************
 *
 * NAME: vAdc_Config
 *
 * DESCRIPTION:
 * configures ADC channel 1 2Vref
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * None.
 ****************************************************************************/
void vAdc_Config(void)
{
  /* Enable ADC channel 1 to measure POT across power pins */
    vAHI_ApConfigure(E_AHI_AP_REGULATOR_ENABLE,
                     E_AHI_AP_INT_DISABLE,
                     E_AHI_AP_SAMPLE_8,
                     E_AHI_AP_CLOCKDIV_500KHZ,
                     E_AHI_AP_INTREF);
    while(bAHI_APRegulatorEnabled() == 0);

}


PRIVATE void vTimerConfig(void)
{
        float float_ADC1_Result;
        float_ADC1_Result = u16ADC1_Result;

        float float_ADC2_Result;
        float_ADC2_Result = u16ADC2_Result;

        e0 = float_ADC1_Result - float_ADC2_Result;//e0 ==> system error 

        vDebug("\n\r e0 = ");
        vDisplayHex(e0,4);


        /*Digital PI Formula*/

         u0=(b0*e0)+(b1*e1)+u1+b2*e2;  //for the present u
                                       /* original form: u0=a1*u1+(b0*e0)+(b1*e1)+u1+b2*e2
                                          where a1=1
                                       */


        /*update u0, u1,e0, e1, e2 after T*/

        u1=u0;
        e2=e1;
        e1=e0;

        uint16 uint16_u0;
        uint16_u0 = u0;

         if (u0 > 0x1110) //determine the saturation point
        {
            u0=0x1110;
        }
        else if (u0 < 0)
        {
            u0=0x000;
        }

    vDebug("\n\r u0 = ");
    vDisplayHex(u0,4);

     /* set up timer 1 for PWM */
    vAHI_TimerEnable(E_AHI_TIMER_1,
                     0x00,
                     FALSE,
                     FALSE,
                     TRUE);
    vAHI_TimerClockSelect(E_AHI_TIMER_1,
                          FALSE,
                          TRUE);
    vAHI_TimerStartRepeat(E_AHI_TIMER_1,
                          uint16_u0,       // low period (space)
                          0x1110);      // period

}



PUBLIC void vUART_Init(void)
{
    /* Enable UART 0: 19200-8-N-1 */
    vAHI_UartEnable(E_AHI_UART_0);

    vAHI_UartReset(E_AHI_UART_0, TRUE, TRUE);
    vAHI_UartReset(E_AHI_UART_0, FALSE, FALSE);

    vAHI_UartSetClockDivisor(E_AHI_UART_0, E_AHI_UART_RATE_19200);
    vAHI_UartSetControl(E_AHI_UART_0, FALSE, FALSE, E_AHI_UART_WORD_LEN_8, TRUE, FALSE);
    vAHI_UartSetInterrupt(E_AHI_UART_0, FALSE, FALSE, FALSE, FALSE, E_AHI_UART_FIFO_LEVEL_1);
}

PRIVATE void vDebug(char *pcMessage)
{
    while (*pcMessage)
    {
        while ((u8AHI_UartReadLineStatus(0) & 0x20) == 0);
        vAHI_UartWriteData(0, *pcMessage);
        pcMessage++;

    }
}


PRIVATE void vDisplayHex(uint32 u32Data, int iSize)
{
    char acValue[9];
    char *pcString = acValue;
   uint8 u8Nybble;
  int i, j;

    j = 0;
    for (i = (iSize << 2) - 4; i >= 0; i -= 4)
    {
        u8Nybble = (uint8)((u32Data >> i) & 0x0f);
        u8Nybble += 0x30;
        if (u8Nybble > 0x39)
            u8Nybble += 7;

        *pcString = u8Nybble;
        pcString++;
    }


    *pcString = '\0';

     vDebug(acValue);  }

Thank you for the help..
 

how big the error was?
can you check the tacho output with a scope? maybe there is a noise injected to the tacho signal.
filter the Analog VCC from the Digital VCC, so the noise from digital VCC do not enter the ADC.

here`s some article regarding ADC error, hope its help
http://versita.metapress.com/content/l460723765rk3401/fulltext.pdf
**broken link removed**

NB:
gak ada pengalaman sama mikro ini, coba bantu saja mas, barangkali dibawah ada yang bisa bantu


good luck..:)
 

mas erio..thanks for the help.. i've checked all the things you've told me.. and i've got the correct value..
Now, the problem is, the PID program was not responding well.. do you know what is the problem with the code?
Thank you mas and for all other friends..
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top