cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f3 discovery how to fix loop periode !!

marzouk_najeh92
Associate II
Posted on October 26, 2016 at 00:52

Hi all, i use stm32f3 discovery and i develop a project with IAR but i have faced a problem in fixing my loop periode

to be more clear :

i use the accelerometer and the gyroscope of th stm32f3 discovery , however after filtring the acc and gyro data i have to know how much time my loop take longer , sorry for my beginner english ;) i need some help please thank you ..!

i think this post discribe clearly what i want to do

''''''''''''''''''''''''''''''''''''''

The gyro tracking will not be accurate if you can not run a well timed loop. The code includes the mymillis() function for the timing.

At the start of each loop, we get the current time;

1

startInt = mymillis();

then at the end of the loop, we make sure that at least 20ms has passed before continuing;

1 2 3 4 5

//Each loop should be at least 20ms.
while

(mymillis() - startInt < 20)
{
usleep(100);
}

If your loop takes longer than 20ms to run, 45ms for example. Jut update the above value to make sure that every loop cycle runs at the same speed and set this value in DT for the gyro tracking.

#please-try-again
3 REPLIES 3
Posted on October 26, 2016 at 02:14

So use a free running 32-bit TIM at a granularity you want to either a) time stamp the measurement epochs, or b) manage the loop iterations.

You could also use the DWT_CYCCNT to get into the sub-microsecond realm for loop iterations. Covered this here multiple times, review other posts

//******************************************************************************
// sourcer32@gmail.com
volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004; //address of the register
volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000; //address of the register
volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC; //address of the register
//******************************************************************************
void EnableTiming(void)
{
static int enabled = 0;
if (!enabled)
{
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
*SCB_DEMCR |= 0x01000000;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL |= 1 ; // enable the counter
enabled = 1;
}
}
//******************************************************************************
void TimingDelay(unsigned int tick)
{
unsigned int start, current;
start = *DWT_CYCCNT;
do
{
current = *DWT_CYCCNT;
} while((current - start) < tick);
}
//******************************************************************************
TimingDelay(SystemCoreClock); // One Second of ticks
TimingDelay(SystemCoreClock / 1000000); // One Microsecond of ticks

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
marzouk_najeh92
Associate II
Posted on October 26, 2016 at 18:45

thank you so much for your answer , i think it will help me a lot ;)

this is my code and what i  want to do i written inside the code ( the main function )

 

int main(void)

{  

  /* SysTick end of count event each 10ms */

  RCC_GetClocksFreq(&RCC_Clocks);

  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

 

  /* Configure the USB */

     Demo_USB();

  /* Configure the gyroscope */  

     Demo_GyroConfig();

  /* Configure the accelerometer */

     Demo_CompassConfig();

  /* Infinite loop */

  while (1)

  {

           *********At the start of each loop, I get the current time*******************

                 exemple --->        ---- current_time() = start_time ----

                   

                   

    //read ACC and GYR data

    Demo_CompassReadAcc(acc_raw);

    Demo_GyroReadAngRate(gyr_raw);

    //Convert Gyro raw to degrees per second

    rate_gyr_x = (float) *gyr_raw * G_GAIN;

    rate_gyr_y = (float) *(gyr_raw+1) * G_GAIN;

    rate_gyr_z = (float) *(gyr_raw+2) * G_GAIN;

    //Calculate the angles from the gyro

    gyroXangle+=rate_gyr_x*DT;

    gyroYangle+=rate_gyr_y*DT;

    gyroZangle+=rate_gyr_z*DT;

    //Convert Accelerometer values to degrees

    AccXangle = (float) (atan2(*(acc_raw+1),*(acc_raw+2))+M_PI)*RAD_TO_DEG;

    AccYangle = (float) (atan2(*(acc_raw+2),*acc_raw)+M_PI)*RAD_TO_DEG;

        AccZangle = (float) (atan2(*(acc_raw),*acc_raw+1)+M_PI)*RAD_TO_DEG;

    //Change the rotation value of the accelerometer to -/+ 180

    if (AccXangle >180)

    {

        AccXangle -= (float)360.0;

    }

    if (AccYangle >180)

        {

        AccYangle -= (float)360.0;

        }

    if (AccZangle >180)

        AccZangle -= (float)360.0;

        // Complementary filter used to combine the accelerometer and gyro values.

    CFangleX=AA*(CFangleX+rate_gyr_x*DT) +(1 - AA) * AccXangle;

    CFangleY=AA*(CFangleY+rate_gyr_y*DT) +(1 - AA) * AccYangle;

        CFangleZ=AA*(CFangleZ+rate_gyr_z*DT) +(1 - AA) * AccZangle;

    

        filter_xterm[0] = (AccXangle - CFangleX) * timeConstant * timeConstant;

    filter_yterm[0] = (AccYangle - CFangleY) * timeConstant * timeConstant;

        filter_zterm[0] = (AccZangle - CFangleZ) * timeConstant * timeConstant;

      filter_xterm[2] = (DT * filter_xterm[0]) + filter_xterm[2];

      filter_yterm[2] = (DT * filter_yterm[0]) + filter_yterm[2];

        filter_zterm[2] = (DT * filter_zterm[0]) + filter_zterm[2];

      filter_xterm[1] = filter_xterm[2] + (AccXangle - CFangleX) * 2 * timeConstant + rate_gyr_x;

      filter_yterm[1] = filter_yterm[2] + (AccYangle - CFangleY) * 2 * timeConstant + rate_gyr_y;

        filter_zterm[1] = filter_zterm[2] + (AccZangle - CFangleZ) * 2 * timeConstant + rate_gyr_z;

      CFangleX2 = (DT * filter_xterm[1]) + CFangleX2;

      CFangleY2 = (DT * filter_yterm[1]) + CFangleY2;

        CFangleZ2 = (DT * filter_zterm[1]) + CFangleZ2;

        

 --------------- ******* current_time()- start_time= DT

                         while

                              (DT < 20 )

      ***exemple                  delay(10) ;

       

        //Each loop should be at least 20ms.

      

    }

}
Posted on October 26, 2016 at 18:50

The forum doesn't like mobile devices, and you should top-post responses

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..