royanto
Newbie level 3

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..
Thank you for the help..
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..