VL53L1CB ranging example, using embedded sensor on X-Nucleo-53L1A2 expansion board, in interrupt mode.
Dependencies: X_NUCLEO_53L1A2
Diff: main.cpp
- Revision:
- 3:c1e893e6752f
- Parent:
- 2:f0ec92af4b5f
- Child:
- 4:0ac9998b69ac
--- a/main.cpp Fri May 07 14:15:27 2021 +0000 +++ b/main.cpp Tue May 11 14:10:25 2021 +0000 @@ -62,7 +62,7 @@ static int int_left_dropped = 0; static int int_right_dropped = 0; -void print_results( int devNumber, VL53L1_MultiRangingData_t *pMultiRangingData ); +void print_results(int devNumber, VL53L1_MultiRangingData_t *pMultiRangingData ); class WaitForMeasurement { public: @@ -134,12 +134,49 @@ -VL53L1_Dev_t devCentre; -VL53L1_Dev_t devLeft; -VL53L1_Dev_t devRight; -VL53L1_DEV Dev = &devCentre; + +VL53L1_Dev_t devCentre; +VL53L1_Dev_t devLeft; +VL53L1_Dev_t devRight; +VL53L1_DEV Dev = &devCentre; +/* flags that handle interrupt request for sensor and user blue button*/ +volatile bool int_sensor = false; +volatile bool int_stop = false; + +/* ISR callback function of the centre sensor */ +void sensor_irq(void) +{ + int_sensor = true; + board->sensor_centre->disable_interrupt_measure_detection_irq(); +} + +/* Start the sensor ranging */ +int init_sensor() +{ + int status = 0; + /* start the measure on the center sensor */ + if (NULL != board->sensor_centre) { + status = board->sensor_centre->stop_measurement(); + if (status != 0) { + return status; + } + + status = board->sensor_centre->start_measurement(&sensor_irq); + if (status != 0) { + return status; + } + } + return status; +} + +/* ISR callback function of the user blue button to switch measuring sensor. */ +void measuring_stop_irq(void) +{ + int_stop = true; +} + /*=================================== Main ================================== =============================================================================*/ int main() @@ -156,16 +193,15 @@ pc.baud(115200); // baud rate is important as printf statements take a lot of time - printf("Autonomous Interruptmbed = %d \r\n",MBED_VERSION); + printf("Autonomous Interrupt, mbed = %d \r\n",MBED_VERSION); // create i2c interface ToF_DevI2C *dev_I2C = new ToF_DevI2C(I2C_SDA, I2C_SCL); + /* creates the 53L1A2 expansion board singleton obj */ + board = XNucleo53L1A2::instance(dev_I2C, CentreIntPin, LeftIntPin, RightIntPin); dev_I2C->frequency(400000); //also needs doing in spi_interface.c - - /* creates the 53L1A2 expansion board singleton obj */ - board = XNucleo53L1A2::instance(dev_I2C, CentreIntPin, LeftIntPin, RightIntPin); - + printf("board created!\r\n"); /* init the 53L1A1 expansion board with default values */ @@ -174,163 +210,108 @@ printf("Failed to init board!\r\n"); return 0; } - - + printf("board initiated! - %d\r\n", status); - // create sensor controller classes for each vl53l1 and configure each vl53l1 - for (ToFSensor=0;ToFSensor < NUM_SENSORS;ToFSensor++){ - switch(ToFSensor){ - case 0: - if (board->sensor_centre== NULL ) continue; // don't create if sensor not detected - Dev=&devCentre; - Sensor=board->sensor_centre; - Dev->i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS; - printf("configuring centre channel \n"); - break; - case 1: - if (board->sensor_left== NULL ) continue; - Dev=&devLeft; - Sensor=board->sensor_left; - Dev->i2c_slave_address = NEW_SENSOR_LEFT_ADDRESS; - printf("configuring left channel \n"); - break; - case 2: - if (board->sensor_right== NULL ) continue; - Dev=&devRight; - Sensor=board->sensor_right; - Dev->i2c_slave_address = NEW_SENSOR_RIGHT_ADDRESS; - printf("configuring right channel \n"); - break; - default: - printf(" error in switch, invalid ToF sensor \n"); - } - - // configure the sensors - Dev->comms_speed_khz = 400; + + /* init an array with chars to id the sensors */ + status = init_sensor(); + if (status != 0) { + printf("Failed to init sensors!\r\n"); + return status; + } + - Dev->comms_type = 1; + Dev=&devCentre; + Sensor=board->sensor_centre; + Dev->i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS; + printf("configuring centre channel \n"); + + // configure the sensors + Dev->comms_speed_khz = 400; + Dev->comms_type = 1; - /* Device Initialization and setting */ - status = Sensor->vl53L1_DataInit(); - status = Sensor->vl53L1_StaticInit(); - status = Sensor->vl53L1_SetPresetMode(VL53L1_PRESETMODE_AUTONOMOUS); - status = Sensor->vl53L1_SetDistanceMode(VL53L1_DISTANCEMODE_LONG); - status = Sensor->vl53L1_SetMeasurementTimingBudgetMicroSeconds( 200 * 1000); + /* Device Initialization and setting */ + status = Sensor->vl53L1_DataInit(); + status = Sensor->vl53L1_StaticInit(); + status = Sensor->vl53L1_SetPresetMode(VL53L1_PRESETMODE_AUTONOMOUS); + status = Sensor->vl53L1_SetDistanceMode(VL53L1_DISTANCEMODE_LONG); + status = Sensor->vl53L1_SetMeasurementTimingBudgetMicroSeconds( 200 * 1000); - // set the ranging and signal rate filter - VL53L1_DetectionConfig_t thresholdconfig; - thresholdconfig.DetectionMode = VL53L1_DETECTION_DISTANCE_ONLY; /// type VL53L1_DetectionMode in vl53l1_def.h - thresholdconfig.Distance.CrossMode = VL53L1_THRESHOLD_IN_WINDOW; // type VL53L1_ThresholdMode. ignore if distance outside high and low - thresholdconfig.Distance.High = 300; // high distance in mm - thresholdconfig.Distance.Low = 200; // low distance in mm - thresholdconfig.Rate.CrossMode=0; // type VL53L1_ThresholdMode VL53L1_THRESHOLD_CROSSED_LOW VL53L1_THRESHOLD_CROSSED_HIGH VL53L1_THRESHOLD_OUT_OF_WINDOW VL53L1_THRESHOLD_IN_WINDOW - thresholdconfig.Rate.High = 0; - thresholdconfig.Rate.Low = 0; - thresholdconfig.IntrNoTarget = 0 ;// if 1 produce an interrupt even if there is no target found e.g out of range - status = Sensor->vl53L1_SetThresholdConfig(&thresholdconfig); - } + // set the ranging and signal rate filter + VL53L1_DetectionConfig_t thresholdconfig; + + thresholdconfig.DetectionMode = VL53L1_DETECTION_DISTANCE_ONLY; /// type VL53L1_DetectionMode in vl53l1_def.h + thresholdconfig.Distance.CrossMode = VL53L1_THRESHOLD_IN_WINDOW; // type VL53L1_ThresholdMode. ignore if distance outside high and low + thresholdconfig.Distance.High = 300; // high distance in mm + thresholdconfig.Distance.Low = 200; // low distance in mm + thresholdconfig.Rate.CrossMode=0; // type VL53L1_ThresholdMode VL53L1_THRESHOLD_CROSSED_LOW VL53L1_THRESHOLD_CROSSED_HIGH VL53L1_THRESHOLD_OUT_OF_WINDOW VL53L1_THRESHOLD_IN_WINDOW + thresholdconfig.Rate.High = 0; + thresholdconfig.Rate.Low = 0; + thresholdconfig.IntrNoTarget = 0 ;// if 1 produce an interrupt even if there is no target found e.g out of range + + status = Sensor->vl53L1_SetThresholdConfig(&thresholdconfig); - // create interrupt handlers for the three sensors and start measurements - if (board->sensor_centre!= NULL ) + // create interrupt handlers for the three sensors and start measurements + if (board->sensor_centre!= NULL ) + { + printf("starting interrupt centre\n"); + devCentre.i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS; + int1 = new WaitForMeasurement(CentreIntPin,&devCentre); // create interrupt handler + status = board->sensor_centre->vl53L1_StartMeasurement(); + } + + printf("loop forever\n"); + + // loop waiting for interrupts to happen. This is signaled by int_centre_result,int_left_result or int_right_result + // being non zero. When the interrupts clear this is signaled by int_centre_dropped,int_left_dropped and int_right_dropped. + // These are set back to zero when processing is completed +/* while (1) + { + VL53L1_MultiRangingData_t MultiRangingData; + VL53L1_MultiRangingData_t *pMultiRangingData = &MultiRangingData; + + if ( int_left_dropped || int_centre_dropped || int_right_dropped ) + wait_ms(30); + + // when the interrupt pin goes loww start new measurement + if (int_centre_dropped != 0) { - printf("starting interrupt centre\n"); - devCentre.i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS; - int1 = new WaitForMeasurement(CentreIntPin,&devCentre); // create interrupt handler - status = board->sensor_centre->vl53L1_StartMeasurement(); + int_centre_dropped = 0; + status = board->sensor_centre->vl53L1_ClearInterruptAndStartMeasurement(); } - - if (board->sensor_left!= NULL ) + + if (int_centre_result != 0) { - printf("starting interrupt left\n"); - devLeft.i2c_slave_address = NEW_SENSOR_LEFT_ADDRESS; - int2 = new WaitForMeasurement(LeftIntPin,&devLeft); // create interrupt handler - status = board->sensor_left->vl53L1_StartMeasurement(); - printf("started interrupt left\n"); + status = board->sensor_centre->vl53L1_GetMultiRangingData( pMultiRangingData); + if (status == 0) + { + print_results( devCentre.i2c_slave_address, pMultiRangingData ); + } + + // clear interrupt flag + int_centre_result = 0; + + } + wait_ms( 1 * 10); + } +*/ + + while (true) { + if (int_sensor) { + int_sensor = false; + status = board->sensor_centre->handle_irq(&distance); + printf("distance: %d\r\n", distance); } - if (board->sensor_right!= NULL ) - { - printf("starting interrupt right\n"); - devRight.i2c_slave_address = NEW_SENSOR_RIGHT_ADDRESS; - int3 = new WaitForMeasurement(RightIntPin,&devRight); // create interrupt handler - status = board->sensor_right->vl53L1_StartMeasurement(); - } - - - printf("loop forever\n"); - - // loop waiting for interrupts to happen. This is signaled by int_centre_result,int_left_result or int_right_result - // being non zero. When the interrupts clear this is signaled by int_centre_dropped,int_left_dropped and int_right_dropped. - // These are set back to zero when processing is completed - while (1) - { - VL53L1_MultiRangingData_t MultiRangingData; - VL53L1_MultiRangingData_t *pMultiRangingData = &MultiRangingData; - - if ( int_left_dropped || int_centre_dropped || int_right_dropped ) - wait_ms(30); - - // when the interrupt pin goes loww start new measurement - if ( int_centre_dropped != 0) - { - int_centre_dropped = 0; - status = board->sensor_centre->vl53L1_ClearInterruptAndStartMeasurement(); - } - - if ( int_left_dropped != 0) - { - int_left_dropped = 0; - status = board->sensor_left->vl53L1_ClearInterruptAndStartMeasurement(); - } - - if ( int_right_dropped != 0) - { - int_right_dropped = 0; - status = board->sensor_right->vl53L1_ClearInterruptAndStartMeasurement(); - } - - if (int_right_result != 0) // interrupt seen on right sensor - { - status = board->sensor_right->vl53L1_GetMultiRangingData( pMultiRangingData); - if ( status == 0) - { - print_results( devRight.i2c_slave_address, pMultiRangingData ); - } - - // clear interrupt flag - int_right_result = 0; - } - - if (int_left_result != 0) // interrupt seen on left sensor - { - status = board->sensor_left->vl53L1_GetMultiRangingData( pMultiRangingData); - if ( status == 0) - { - print_results( devLeft.i2c_slave_address, pMultiRangingData ); - } - - // clear interrupt flag - int_left_result = 0; - } - - if (int_centre_result != 0) - { - status = board->sensor_centre->vl53L1_GetMultiRangingData( pMultiRangingData); - if ( status == 0) - { - print_results( devCentre.i2c_slave_address, pMultiRangingData ); - } - - // clear interrupt flag - int_centre_result = 0; - - } - wait_ms( 1 * 10); - + if (int_stop) { + printf("\r\nEnding loop mode \r\n"); + break; } } +} + // print what ever results are required void print_results( int devNumber, VL53L1_MultiRangingData_t *pMultiRangingData )