VL53L1x People Count by using Interrupt method
Dear Team,
We are using VL53l1X in our application to detect people leaving and entry, we got 5 vl53l1x breakout boards from one of my distributors for prototyping.
People count programming working without any issues when using it in polling/continuous mode, but for power optimization we want to use an interrupt method, Count increment and decrement should happen when there is an interrupt, rest of the time the main controller and other things to be in sleep mode.
- Took code from -> en.STSW-IMG010.zip
- Polling method works fine here
- Played with ROI, timing budget as per my application everything works fine
- Modified the given code for interrupt method, we are getting interrupt but we are getting wrong path most of the time and wrong count.
Here is the code...
//Event CallBack
void interrupt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
nrf_drv_gpiote_in_event_disable(INTERRUPT_PIN);
event = true;
printf("Event occured\n");
}
//Main code
int main(void)
{
uint8_t byteData, sensorState=0;
uint16_t wordData;
uint16_t Distance, Signal;
uint8_t RangeStatus;
uint8_t dataReady;
uint8_t intPolarity;
int PplCounter;
int center[2] = {FRONT_ZONE_CENTER, BACK_ZONE_CENTER}; /* these are the spad center of the 2 4*16 zones */
//int Zone = 0;
gpio_init();
printf("\r\nTWI sensor example started.\n");
twi_init();
detect_slave_device();
// Those basic I2C read functions can be used to check your own I2C functions */
status = VL53L1_RdByte(dev, 0x010F, &byteData);
printf("VL53L1X Model_ID: %X\n", byteData);
status = VL53L1_RdByte(dev, 0x0110, &byteData);
printf("VL53L1X Module_Type: %X\n", byteData);
status = VL53L1_RdWord(dev, 0x010F, &wordData);
printf("VL53L1X: %X\n", wordData);
while (sensorState == 0) {
status = VL53L1X_BootState(dev, &sensorState);
nrf_delay_ms(2);
}
printf("Chip booted\n");
status = VL53L1X_SensorInit(dev);
status += VL53L1X_SetDistanceMode(dev, DISTANCE_MODE); /* 1=short, 2=long */
status += VL53L1X_SetTimingBudgetInMs(dev, TIMING_BUDGET); /* in ms possible values [15, 20, 50, 100, 200, 500] */
status += VL53L1X_SetInterMeasurementInMs(dev, TIMING_BUDGET);
status += VL53L1X_SetROI(dev, ROWS_OF_SPADS, 16); /* minimum ROI 4,4 */
if (status != 0) {
printf("Initialization or configuration of the device\n");
return (-1);
}
VL53L1X_SetInterruptPolarity(dev, 0);
VL53L1X_SetDistanceThreshold(dev,50,1000,3,0);
VL53L1X_GetInterruptPolarity(dev, &intPolarity);
printf("Interrupt mode : %d\n", intPolarity);
printf("Start counting people with profile : %s...\n", PROFILE_STRING);
status = VL53L1X_StartRanging(dev);
while(1)
{
if(event == true){
status += VL53L1X_GetRangeStatus(dev, &RangeStatus);
status += VL53L1X_GetDistance(dev, &Distance);
status += VL53L1X_GetSignalPerSpad(dev, &Signal);
//event = false;
status += VL53L1X_ClearInterrupt(dev);
if (status != 0) {
printf("Error in operating the device\n");
return (-1);
}
status = VL53L1X_SetROICenter(dev, center[Zone]);
if (status != 0) {
printf("Error in chaning the center of the ROI\n");
return (-1);
}
if ((RangeStatus == 0) || (RangeStatus == 4) || (RangeStatus == 7)) {
if (Distance <= MIN_DISTANCE) // wraparound case see the explanation at the constants definition place
Distance = MAX_DISTANCE + MIN_DISTANCE;
}
else // severe error cases
Distance = MAX_DISTANCE;
PplCounter = ProcessPeopleCountingData(Distance, Zone, RangeStatus);
Zone++;
Zone = Zone%2;
}
}
}
Making event = false and nrf_drv_gpiote_in_event_enable(INTERRUPT_PIN) , when there is a entry or exit or wrong path.
Please provide with us VL53L1X APIs for interrupt method.
Thanks & Regards
Mariswamy M
AXISCADES Engineering Technologies PVT Ltd, Bangalore
mariswamy.m@axiscades.com
