tdk-invn-oss / motion.arduino.ICM42670P

Arduino Driver for TDK InvenSense consumer motion sensor ICM42670P
https://invensense.tdk.com/smartmotion
BSD 3-Clause "New" or "Revised" License
30 stars 3 forks source link

Can features like step counting be used when not using interrupt pins #11

Closed LHYhorion closed 5 months ago

LHYhorion commented 6 months ago

Because there are some issues with my interrupt pins currently, I am unable to use them. Is there a way to utilize features like step counting and tilt detection without using interrupt pins?

sriccardi-invn commented 6 months ago

Hi, this is not power optimize but you can try something like that:

void loop() { // Wait for interrupt to read data Pedometer status uint32_t step_count=0; float step_cadence=0; const char* activity; irq_received = 0; IMU.getPedometer(step_count,step_cadence,activity); if (step_count !=0) { Serial.print("Step count:"); Serial.println(step_count); Serial.print("Step cadence:"); Serial.println(step_cadence); Serial.print("activity:"); Serial.println(activity); } delay(1000);

}

Regards, Seb

LHYhorion commented 6 months ago

Alright, I will conduct tests based on your suggestions. Thank you for your response.

LHYhorion commented 6 months ago

After reviewing your suggested code, it mentions waiting for interrupt to read data for pedometer status, so is it necessary to have interrupts for pedometer and tilt monitoring functionalities?

sriccardi-invn commented 6 months ago

My team tested the patch proposal and it works. Only one issue without interrupt, this is the overconsumption. In a real product, if the system is on the table, no interrupt, the CPU is in low power. Without interrupt, CPU is not in low power because pooling all the time. Regards, Seb

LHYhorion commented 6 months ago

Thank you for your reply. May I ask if the function ‘IMU.startPedometer(2,irq_handler)’ still needs configuration? Do I still need to continue configuring ‘inv_imu_apex_enable_pedometer(&icm_driver)’?

rbuisson-invn commented 6 months ago

Hello, Yes, this function is required to initialize the pedometer feature. If you don't use the interrupt, you can specify a dummy pin ID and handler.

LHYhorion commented 6 months ago

Thank you for your response. After testing, the code you suggested does work indeed. However, there is another issue. I would like to know how to distinguish between interrupts triggered by the tilt detection and step detection functionalities if I want to use them simultaneously. It seems that in the code, initApex is used for interrupt registration, and it doesn't appear to differentiate between the two functionalities.

rbuisson-invn commented 6 months ago

Unfotunately current ICM4267P library API does not allow to enable several APEX at the same time. However you could add following functions to the library:

int ICM42670P::startPedometerAndTilt(uint8_t intpin, ICM42670P_irq_handler handler) { int rc = 0; step_cnt_ovflw = 0; rc |= initApex(intpin,handler); rc |= inv_imu_apex_enable_pedometer(&icm_driver); rc |= inv_imu_apex_enable_tilt(&icm_driver); return rc; }

int ICM42670P::getPedometerAndTilt(uint32_t& step_count, float& step_cadence, const char*& activity, bool& tilt) { int rc = 0; uint8_t int_status3; tilt = false;

/ Read APEX interrupt status / rc |= inv_imu_read_reg(&icm_driver, INT_STATUS3, 1, &int_status3);

if (int_status3 & INT_STATUS3_STEP_CNT_OVF_INT_MASK) step_cnt_ovflw++;

if (int_status3 & (INT_STATUS3_STEP_DET_INT_MASK)) { inv_imu_apex_step_activity_t apex_data0; float nb_samples = 0;

rc |= inv_imu_apex_get_data_activity(&icm_driver, &apex_data0);

step_count = apex_data0.step_cnt + step_cnt_ovflw*(uint32_t)UINT16_MAX;   
/* Converting u6.2 to float */
nb_samples = (apex_data0.step_cadence >> 2) +
    (float)(apex_data0.step_cadence & 0x03) * 0.25f;
if(nb_samples != 0)
{
  step_cadence = (float)50 / nb_samples;
} else {
  step_cadence = 0;
}
activity = APEX_ACTIVITY[apex_data0.activity_class];

} else if (int_status3 & (INT_STATUS3_TILT_DET_INT_MASK)) { tilt = true; } else { return -11;
}

return rc; }

Let me know if it fits your need.

Thanks,

LHYhorion commented 6 months ago

It looks effective, and I will conduct a test afterwards. Additionally, does this imply that tilt detection can also be implemented similarly through polling?

rbuisson-invn commented 6 months ago

Yes, it boils down to poll INT_STATUS3 register.

LHYhorion commented 6 months ago

Sure, thank you for your reply. I will conduct tests based on your suggestions. I find this API very useful. If possible, you could consider updating this API in the library, or I can submit a pull request.

LHYhorion commented 6 months ago

Sure, one more question: Can tilt detection be categorized into left tilt and right tilt?

rbuisson-invn commented 6 months ago

No sorry, this feature is not available on the IMU.

sriccardi-invn commented 6 months ago

Sure, one more question: Can tilt detection be categorized into left tilt and right tilt?

Tilt Left /Right Front/Rear has no sense since IMU has no Yaw reference alone in space. More than this, tilt event is an orientation change. If you would know Tilt X /- X, Y /-Y, you can just test the value of ACC X and Y. Which type of application you developing? Regards, Seb

rbuisson-invn commented 6 months ago

Hello LHYhorion,

We released the 1.0.4 version of the ICM42670P library supporting Tilt and Pedometer together, if you want to upgrade.

Regards,