chThdSleepMilliseconds( 1000 ) Weird ?

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess

Tabulous
Posts: 509
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 17 times

Re: chThdSleepMilliseconds( 1000 ) Weird ?

Postby Tabulous » Wed Nov 30, 2016 8:25 pm

the reason for the teh low jitter, is the data that is read is accellormeter/gyro data. To generate pitch and roll angles from gyro it needs to be integrated over time.

steved
Posts: 825
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: chThdSleepMilliseconds( 1000 ) Weird ?

Postby steved » Wed Nov 30, 2016 9:32 pm

Is the accelerometer data latched at some well-defined point early on in the I2C transfer? If so, maybe you could start off the bit-banging in a GPT-triggered ISR, and continue within a normal thread.
Otherwise I would expect that bit-banged I2C, especially if subject to the uncertainties of interrupts and context switches, is inherently going to have a fair amount of jitter.

Tabulous
Posts: 509
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 17 times

Re: chThdSleepMilliseconds( 1000 ) Weird ?

Postby Tabulous » Thu Dec 01, 2016 9:58 am

steved wrote:Is the accelerometer data latched at some well-defined point early on in the I2C transfer? If so, maybe you could start off the bit-banging in a GPT-triggered ISR, and continue within a normal thread.
Otherwise I would expect that bit-banged I2C, especially if subject to the uncertainties of interrupts and context switches, is inherently going to have a fair amount of jitter.



i2c runs totally inside gpt callback, with no way to allow the scheduler to have some time back, and that is the route to my issue.


i could run the code inside a thread, in fact this is what i used to do, but the jitter when trying to run a thread at 100hz was too much.

Tabulous
Posts: 509
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 17 times

Re: chThdSleepMilliseconds( 1000 ) Weird ?

Postby Tabulous » Thu Dec 01, 2016 10:28 am

So ive just moved all the code back into a thread, well just disabled the gpt timer, and are calling the timer callback function from a thread, but its the same thing. inside the gpt3cb callback is the reading of the i2c which is bit banged.

The code is below, as you can see the thread loop is @ 10ms or 100hz, you'll also see i'm timing the loop using GPIO pins, and guess what the loop timing is not 10ms, it is 11ms or 90Hz........

Code: Select all

    while( TRUE )
    {
        palSetPad(GPIOB, GPIOB_PIN2);
        gpt3cb( &GPTD3 );

        if( imu->running )
        {
            calculatePitchRoll( imu );
        }
        palClearPad(GPIOB, GPIOB_PIN2);

        chThdSleepMilliseconds( 10 );
    }


Now if i change CH_CFG_ST_FREQUENCY from 1000 to 100, boom timing is perfect......10ms spot on


Ive also tried CH_CFG_ST_FREQUENCY 1000 and setting the thread priority to HIGHPRIO(all other threads in the system are NORMALPRIO), but this has zero effect.


So what can i conclude from this ?

Marco
Posts: 128
Joined: Tue Apr 16, 2013 8:22 pm
Has thanked: 4 times
Been thanked: 11 times

Re: chThdSleepMilliseconds( 1000 ) Weird ?

Postby Marco » Thu Dec 01, 2016 11:03 am

Hi,

I think the problem is that the gpt3cb() function is taking longer than 1ms, and so chThdSleepMilliseconds() will add 10ms to that.

Instead of chThdSleepMilliseconds() i would use the following construction in the thread:

Code: Select all

    while( TRUE )
    {
        /* Wait here on the next signal */
        chBSemWait();
       
        palSetPad(GPIOB, GPIOB_PIN2);
        gpt3cb( &GPTD3 );

        if( imu->running )
        {
            calculatePitchRoll( imu );
        }
        palClearPad(GPIOB, GPIOB_PIN2);
    }


and your 100hz timer is giving the semaphore with chBsemSignalI() in the callback. That should give you exact 100hz timing.

Marco

Tabulous
Posts: 509
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 17 times

Re: chThdSleepMilliseconds( 1000 ) Weird ?

Postby Tabulous » Thu Dec 01, 2016 11:58 am

Marco wrote:Hi,

I think the problem is that the gpt3cb() function is taking longer than 1ms, and so chThdSleepMilliseconds() will add 10ms to that.

Instead of chThdSleepMilliseconds() i would use the following construction in the thread:

Code: Select all

    while( TRUE )
    {
        /* Wait here on the next signal */
        chBSemWait();
       
        palSetPad(GPIOB, GPIOB_PIN2);
        gpt3cb( &GPTD3 );

        if( imu->running )
        {
            calculatePitchRoll( imu );
        }
        palClearPad(GPIOB, GPIOB_PIN2);
    }


and your 100hz timer is giving the semaphore with chBsemSignalI() in the callback. That should give you exact 100hz timing.

Marco


This works :-)

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: chThdSleepMilliseconds( 1000 ) Weird ?

Postby Giovanni » Thu Dec 01, 2016 3:09 pm

Hi,

About timings, you need to use a different method if you want accurate timed loop regardless of the execution time of the code inside the loop.

See this article: http://chibios.org/dokuwiki/doku.php?id ... :kb:timing

See under "A better solution", using deadlines makes the loop accurate if you don't know exactly the execution time of the code inside.

Giovanni


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 38 guests