mpu6050 interrupt activation by external signal

Hello arduino community;

I'm working with mpu6050 IMU sensor and an arducam (monocular camera) in arduino UNO.

I want to synchronize IMU data with camera data :

at the beginning, I the frequency of IMU output measurements abouts 100Hz and camera measurements abouts 30Hz. I want to synchronize both of them at 30 Hz .

for this I have to trigger the two sensors at the same raising edge of the clock, I knew that :

The arducam has an external trigger, so if we perform PWM signal we can trigger the camera evry 33 ms for example.

My question is about the mpu6050, I knew there is an Interrupt PIN; but how can we trigger it ??

Or how we can recover the measurements at every external raising edge of a clock signal

I hope someone can reply me ;

Thank you

The MPU has a Interrupt out pin, not an interrupt in. Why not just use the camera interrupt and read the MPU after reading the camera?

Thank you for the reply,

Yes, you are right.

The problem is that the INT pin is only configurable in input, so I trigger it.
Otherwise we can generate an interrupt signal. But reading the datasheet, I found that we have not any issue to generate an interrupt at each measurement.

And what I want is to generate an interrupt signal at each data captured at 30HZ for example.

Have a good day.

MASSENSEN:
Thank you for the reply,

Yes, you are right.

The problem is that the INT pin is only configurable in input, so I trigger it.
Otherwise we can generate an interrupt signal. But reading the datasheet, I found that we have not any issue to generate an interrupt at each measurement.

And what I want is to generate an interrupt signal at each data captured at 30HZ for example.

Have a good day.

You can use a hardware timer to generate a 30Hz signal that can serve as an interrupt. I have an example on how to generate a hardware interrupt with an ESP32 and run an interrupt service routine, but there are loads of examples on the internet on how to generate Arduino interrupts.

Hello,

Thankyou for the reply,

I will see your example to understand more.

Regards

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.

Thank you very much,

I will share my solution when done.

It will be helpful.

Regards