VL53L1CB expansion shield autonomous interrupt example.
main.cpp
- Committer:
- johnAlexander
- Date:
- 2021-05-11
- Revision:
- 4:0ac9998b69ac
- Parent:
- 3:c1e893e6752f
File content as of revision 4:0ac9998b69ac:
/*
* This VL53L1X Expansion board test application performs range measurements
* using the onboard embedded centre sensor and two satelites, in autonomous, interrupt mode.
* Measured ranges are ouput on the Serial Port, running at 115200 baud.
*
* This is designed to work with MBed V2 , MBed V5 and MBed V6.
*
* The Reset button can be used to restart the program.
*
* *** Note :
* Default Mbed build system settings disable print floating-point support.
* Offline builds can enable this, again.
* https://github.com/ARMmbed/mbed-os/blob/master/platform/source/minimal-printf/README.md
* .\mbed-os\platform\mbed_lib.json
*
*/
#include <stdio.h>
#include <time.h>
#include "mbed.h"
#include "XNucleo53L1A2.h"
#include "ToF_I2C.h"
// i2c comms port pins
#define I2C_SDA D14
#define I2C_SCL D15
#define NUM_SENSORS 3
// define the interrupt pins
PinName CentreIntPin = A2;
// the satellite pins depend on solder blobs on the back of the shield.
// they may not exist or may be one of two sets.
// the centre pin always exists
PinName LeftIntPin = D9;
PinName RightIntPin = D4;
// alternate set
//PinName LeftIntPin = D8;
//PinName RightIntPin = D2;
static XNucleo53L1A2 *board=NULL;
#if (MBED_VERSION > 60300)
UnbufferedSerial pc(USBTX, USBRX);
extern "C" void wait_ms(int ms);
#else
Serial pc(SERIAL_TX, SERIAL_RX);
#endif
void print_results(int devNumber, VL53L1_MultiRangingData_t *pMultiRangingData );
VL53L1_Dev_t devCentre;
VL53L1_Dev_t devLeft;
VL53L1_Dev_t devRight;
VL53L1_DEV Dev = &devCentre;
VL53L1 *Sensor;
/* 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;
Dev=&devCentre;
Sensor=board->sensor_centre;
// configure the sensors
Dev->comms_speed_khz = 400;
Dev->comms_type = 1;
Dev->i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS;
printf("configuring centre channel \n");
/* 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);
// create interrupt handler and start measurements
if (board->sensor_centre!= NULL) {
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()
{
#if (MBED_VERSION < 60000)
#if USER_BUTTON==PC_13 // we are cross compiling for Nucleo-f401
InterruptIn stop_button(USER_BUTTON);
stop_button.rise(&measuring_stop_irq);
#endif
#endif
int status;
uint16_t distance = 0;
pc.baud(115200); // baud rate is important as printf statements take a lot of time
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
printf("board created!\r\n");
/* init the 53L1A1 expansion board with default values */
status = board->init_board();
if (status) {
printf("Failed to init board!\r\n");
return 0;
}
printf("board initiated! - %d\r\n", status);
/* init an array with chars to id the sensors */
status = init_sensor();
if (status != 0) {
printf("Failed to init sensors!\r\n");
return status;
}
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_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);
}
*/
VL53L1_MultiRangingData_t MultiRangingData;
VL53L1_MultiRangingData_t *pMultiRangingData = NULL;
while (true) {
pMultiRangingData = &MultiRangingData;
if (int_sensor) {
int_sensor = false;
/*
// status = board->sensor_centre->handle_irq(&distance);
// status = get_measurement(distance);
// status = board->sensor_centre->VL53L1_GetDistance(&distance);
status = board->sensor_centre->VL53L1_ClearInterrupt();
board->sensor_centre->enable_interrupt_measure_detection_irq();
printf("distance: %d\r\n", distance);
*/
status = board->sensor_centre->vl53L1_GetMultiRangingData( pMultiRangingData);
if (status == 0)
{
print_results( devCentre.i2c_slave_address, pMultiRangingData );
}
status = board->sensor_centre->VL53L1_ClearInterrupt();
// status = board->sensor_centre->vl53L1_ClearInterruptAndStartMeasurement(); // doesnt run!
board->sensor_centre->enable_interrupt_measure_detection_irq();
}
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 )
{
int no_of_object_found=pMultiRangingData->NumberOfObjectsFound;
int RoiNumber=pMultiRangingData->RoiNumber;
if (( no_of_object_found < 10 ) && ( no_of_object_found != 0))
{
for(int j=0;j<no_of_object_found;j++){
if ((pMultiRangingData->RangeData[j].RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID) ||
(pMultiRangingData->RangeData[j].RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL))
{
printf("\t i2cAddr=%d \t RoiNumber=%d \t status=%d, \t D=%5dmm, \t Signal=%2.2f Mcps, \t Ambient=%2.2f Mcps \n",
devNumber, RoiNumber,
pMultiRangingData->RangeData[j].RangeStatus,
pMultiRangingData->RangeData[j].RangeMilliMeter,
pMultiRangingData->RangeData[j].SignalRateRtnMegaCps / 65535.0,
pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps / 65535.0);
}
}
} // if (( no_of_object_found < 10 ) && ( no_of_object_found != 0))
}
#if (MBED_VERSION > 60300)
extern "C" void wait_ms(int ms)
{
thread_sleep_for(ms);
}
#endif