In the declare section goes:
/* create a hardware timer */
hw_timer_t * timer = NULL;
#define TimerDivider 80
#define TIMER_FOUR 3
#define OneK 1000
volatile int iTicCount = 0; //counts milliseconds
Then you will need a interrupt handler routine like so:
void IRAM_ATTR onTimer()
{
BaseType_t xHigherPriorityTaskWoken;
iTicCount++;
xEventGroupSetBitsFromISR(eg, OneMilliSecondGroupBits, &xHigherPriorityTaskWoken);
if ( (iTicCount % 2) == 0 )
{
if ( (xSemaphoreTakeFromISR(sema_ReceiveSerial_LIDAR, &xHigherPriorityTaskWoken)) == pdTRUE ) // grab semaphore, no wait
{
xEventGroupSetBitsFromISR(eg, evtReceiveSerial_LIDAR, &xHigherPriorityTaskWoken); // trigger every 2mS, if not already processing
}
}
if ( (iTicCount % 3) == 0 )
{
if ( (xSemaphoreTakeFromISR(sema_HexaPodAdjustment, &xHigherPriorityTaskWoken)) == pdTRUE ) // grab semaphore, no wait
{
xEventGroupSetBitsFromISR(eg1, evtWalk_Forward, &xHigherPriorityTaskWoken);
}
}
if ( iTicCount == OneK )
{
xEventGroupSetBitsFromISR(eg, OneSecondGroupBits, &xHigherPriorityTaskWoken); // trigger every 1X a second
// reset counter to start again
iTicCount = 0;
}
if ( !bLIDAR_OK )
{
xSemaphoreTakeFromISR ( sema_iLIDAR_Power_Reset, &xHigherPriorityTaskWoken );
++iLIDAR_Power_Reset;
xSemaphoreGiveFromISR ( sema_iLIDAR_Power_Reset, &xHigherPriorityTaskWoken);
if ( iLIDAR_Power_Reset >= 4000 )
{
xEventGroupSetBitsFromISR(eg, evtfLIDAR_Power_On, &xHigherPriorityTaskWoken);
}
}
} // void IRAM_ATTR onTimer()
An event that is triggered by a timer launched event
void fWalk_Forward ( void *pvParameters )
{
stuSERVO_Message pxServoMessage;
for ( ;; )
{
xEventGroupWaitBits (eg1, evtWalk_Forward, pdTRUE, pdTRUE, portMAX_DELAY);
if ( xSemaphoreTake( sema_STOP_Walking, xTicksToWait0 ) == pdTRUE ) // grab semaphore no wait
{
if ( EOT == false )
{
pxServoMessage.Instruction = '1' ;
pxServoMessage.p1 = xServo_ACK.p4;
pxServoMessage.p2 = xServo_ACK.p4;
pxServoMessage.p3 = xServo_ACK.p4;
pxServoMessage.p4 = xServo_ACK.p4;
xQueueSend( xQ_SERVO_Message, ( void * ) &pxServoMessage, QueueReceiveDelayTime );
vTaskDelay( pdMS_TO_TICKS( 10 ) );
/// SET EOT
EOT = true;
// }
} // if ( EOT == false )
}
xSemaphoreGive( sema_HexaPodAdjustment );
}
vTaskDelete( NULL );
} // void fwalk_forward( ( void *pvParameters ))
In setup the timer options are set:
void setup()
{
/* Use 4th timer of 4.
1 tick 1/(80MHZ/80) = 1us set divider 80 and count up.
Attach onTimer function to timer
Set alarm to call timer ISR, every 1000uS and repeat / reset ISR (true) after each alarm
Start an timer alarm
*/
timer = timerBegin( TIMER_FOUR, TimerDivider, true );
timerAttachInterrupt( timer, &onTimer, true );
/// can set call back to 500 for .5mS
timerAlarmWrite(timer, OneK, true);
timerAlarmEnable(timer);
}
There you have it, a working example for using a hardware timer on an ESP32, changing the TimerDivider and the variable OneK will change the trigger times of the timer.
For you, you'd configure an if statement to react when the iTicCount got to a 30Hz value to trigger a task event.