Monday, January 21, 2013

ADF Timer event

It didn't take long to realize that I didn't need all of my devices to be checking on status updates every 10 milliseconds, and I also needed to have some long timed events, like run the motor for 2 seconds. To this end I created a timer event.

For example, I wanted to read the accelerometer x y and z angles every 250 milliseconds.  The timer event class has an add timer method that allows you to specify a "ProcessID" and a "TimerID". The process ID is the class that is creating the timer. Each class gats it's unique process ID from the QF unique priority. These are all encapsulated in the class variable m_ProcessID. This means any class can get its own unique id by referencing me->m_ProcessID. Because each "process" can have multiple timers, you can specify them with timer IDs. The signature of the add method is:

ADFTimer_AddTimer(uint8_t processID, uint8_t timerID, ADFTIMER_TYPE type)

Creating a timer in the ADXL345 class:

ADFTimer_AddTimer(me->m_ProcessID, 0, ADFTIMER_REPEAT);

creates a repeating timer, as opposed to a ADFTIMER_ONSHOT timer. Starting the timer:

ADFTimer_StartTimer(uint8_t processID, uint8_t timerID,
                        uint16_t milliSeconds)

for this process using timer ID 0 for 250 ms is

ADFTimer_StartTimer(me->m_ProcessID, 0, 250);

All we have to do subscribe to the event during class initialization:

me->subscribe(ADFTIMER_NOTICE);

and we will receive notices from the timer. Once a notice comes in we need to ensure it is our timer:

if( Q_EVT_CAST(ADFTimerEventArg)->processID == me->m_ProcessID );

and then we can react to it. In the above case, the accelerometer is only using one timer so we don't need to further determine which timer it is.

So currently I have the following device startups:

    ADFTimer_Start          ( ++priority );
    DigitalODC_Start        ( ++priority );
    DigitalIDC_Start        ( ++priority );
    AnalogIDC_Start         ( ++priority );
    DCMotorControl_Start    ( ++priority );
    ADXL345Handler_Start    ( ++priority );

Plus my controller:

    MyController_Start      ( ++priority );

In about 17K, the ADF platform can:

  • Write to N number of digital output pins
  • Read N number of digital input pins
  • Write to N number of Analog pins
  • Control N number of H-Bridge DC motors
  • Read 1 accelerometer on the IIC bus.
  • Time N number of events
The last point I want to make it that the timer resolution is somewhat variable depending on the number of interrupts per second that are designated in the bsp.h file. For example, I'm currently running at 200 interrupts per second:

#define BSP_TICKS_PER_SEC  200U
#define TICK_DIVIDER ((F_CPU / BSP_TICKS_PER_SEC / 1024) - 1)
#define TICK_MILLIS  (1000/BSP_TICKS_PER_SEC)

This would provide a 5 millisecond time tick. However, if ticks per second is set to the minimum of 66, That is about 15ms per tick. If the time of the event is not exactly a modulo of the tick millis, then the time will be longer by tick millis. This means in my current scenario, my timer is either exactly correct or off by plus 5 ms.

No comments:

Post a Comment