ST Expansion SW Team / Mbed 2 deprecated VL53L1_shield_MB2_3sensors_interrupt_lite_ranging

Dependencies:   mbed VL53L1ExpansionBoard

Committer:
charlesmn
Date:
Tue Oct 27 12:37:48 2020 +0000
Revision:
0:d6a9ba597c26
A sample program that talks to up to 3 VL53L1 ToF sensors on a nucleo shield. The sensor is in lite-ranging mode and interrupts occur when a measurement is available. MBed V2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:d6a9ba597c26 1 /*
charlesmn 0:d6a9ba597c26 2 * This VL53L1X Expansion board test application performs range measurements
charlesmn 0:d6a9ba597c26 3 * using the onboard embedded centre sensor and two satelites, in Lite-ranging, interrupt mode.
charlesmn 0:d6a9ba597c26 4 * Measured ranges are ouput on the Serial Port, running at 115200 baud.
charlesmn 0:d6a9ba597c26 5 *
charlesmn 0:d6a9ba597c26 6 *
charlesmn 0:d6a9ba597c26 7 * This is designed to work with MBed V2 , MBed V5 and MBed V6.
charlesmn 0:d6a9ba597c26 8 *
charlesmn 0:d6a9ba597c26 9 *
charlesmn 0:d6a9ba597c26 10 * The Reset button can be used to restart the program.
charlesmn 0:d6a9ba597c26 11 */
charlesmn 0:d6a9ba597c26 12
charlesmn 0:d6a9ba597c26 13 #include <stdio.h>
charlesmn 0:d6a9ba597c26 14
charlesmn 0:d6a9ba597c26 15 #include "mbed.h"
charlesmn 0:d6a9ba597c26 16 #include "XNucleo53L1A1.h"
charlesmn 0:d6a9ba597c26 17 #include "ToF_I2C.h"
charlesmn 0:d6a9ba597c26 18 #include <time.h>
charlesmn 0:d6a9ba597c26 19
charlesmn 0:d6a9ba597c26 20
charlesmn 0:d6a9ba597c26 21 // define the i2c comms pins
charlesmn 0:d6a9ba597c26 22 #define I2C_SDA D14
charlesmn 0:d6a9ba597c26 23 #define I2C_SCL D15
charlesmn 0:d6a9ba597c26 24
charlesmn 0:d6a9ba597c26 25 #define NUM_SENSORS 3
charlesmn 0:d6a9ba597c26 26
charlesmn 0:d6a9ba597c26 27
charlesmn 0:d6a9ba597c26 28 static XNucleo53L1A1 *board=NULL;
charlesmn 0:d6a9ba597c26 29 Serial pc(SERIAL_TX, SERIAL_RX);
charlesmn 0:d6a9ba597c26 30
charlesmn 0:d6a9ba597c26 31 static int int_centre_result = 0;
charlesmn 0:d6a9ba597c26 32 static int int_left_result = 0;
charlesmn 0:d6a9ba597c26 33 static int int_right_result = 0;
charlesmn 0:d6a9ba597c26 34
charlesmn 0:d6a9ba597c26 35
charlesmn 0:d6a9ba597c26 36 class WaitForMeasurement {
charlesmn 0:d6a9ba597c26 37 public:
charlesmn 0:d6a9ba597c26 38
charlesmn 0:d6a9ba597c26 39
charlesmn 0:d6a9ba597c26 40 // this class services the interrupts from the ToF sensors.
charlesmn 0:d6a9ba597c26 41 // There is a limited amount you can do in an interrupt routine; printfs,mutexes break them among other things.
charlesmn 0:d6a9ba597c26 42 // We keep things simple by only raising a flag so all the real work is done outside the interrupt.
charlesmn 0:d6a9ba597c26 43 // This is designed around MBED V2 which doesn't have the RTOS features that would make this work nicely e.g. semaphores/queues.
charlesmn 0:d6a9ba597c26 44 WaitForMeasurement(): _interrupt(A1)
charlesmn 0:d6a9ba597c26 45 {
charlesmn 0:d6a9ba597c26 46 }
charlesmn 0:d6a9ba597c26 47
charlesmn 0:d6a9ba597c26 48
charlesmn 0:d6a9ba597c26 49 // constructor - Sensor is not used and can be removed
charlesmn 0:d6a9ba597c26 50 WaitForMeasurement(PinName pin,VL53L1_DEV Dev) : _interrupt(pin) // create the InterruptIn on the pin specified to Counter
charlesmn 0:d6a9ba597c26 51 {
charlesmn 0:d6a9ba597c26 52 Devlocal = Dev;
charlesmn 0:d6a9ba597c26 53 _interrupt.rise(callback(this, &WaitForMeasurement::got_interrupt)); // attach increment function of this counter instance
charlesmn 0:d6a9ba597c26 54
charlesmn 0:d6a9ba597c26 55 }
charlesmn 0:d6a9ba597c26 56
charlesmn 0:d6a9ba597c26 57 void process_right_interrupt()
charlesmn 0:d6a9ba597c26 58 {
charlesmn 0:d6a9ba597c26 59 printf("processing right interrupt\n");
charlesmn 0:d6a9ba597c26 60 }
charlesmn 0:d6a9ba597c26 61
charlesmn 0:d6a9ba597c26 62 // function is called every time an interupt is seen. A flag is raised which allows the main routine to service the interupt.
charlesmn 0:d6a9ba597c26 63 void got_interrupt()
charlesmn 0:d6a9ba597c26 64 {
charlesmn 0:d6a9ba597c26 65
charlesmn 0:d6a9ba597c26 66 _count++;
charlesmn 0:d6a9ba597c26 67
charlesmn 0:d6a9ba597c26 68 if (Devlocal->i2c_slave_address == NEW_SENSOR_CENTRE_ADDRESS)
charlesmn 0:d6a9ba597c26 69 int_centre_result = 1; //flag to main that interrupt happened
charlesmn 0:d6a9ba597c26 70 if (Devlocal->i2c_slave_address == NEW_SENSOR_LEFT_ADDRESS)
charlesmn 0:d6a9ba597c26 71 int_left_result = 1; //flag to main that interrupt happened
charlesmn 0:d6a9ba597c26 72 if (Devlocal->i2c_slave_address == NEW_SENSOR_RIGHT_ADDRESS)
charlesmn 0:d6a9ba597c26 73 {
charlesmn 0:d6a9ba597c26 74 int_right_result = 1; //flag to main that interrupt happened
charlesmn 0:d6a9ba597c26 75 }
charlesmn 0:d6a9ba597c26 76 }
charlesmn 0:d6a9ba597c26 77
charlesmn 0:d6a9ba597c26 78 //destructor
charlesmn 0:d6a9ba597c26 79 ~WaitForMeasurement()
charlesmn 0:d6a9ba597c26 80 {
charlesmn 0:d6a9ba597c26 81 printf("destruction \n");
charlesmn 0:d6a9ba597c26 82 }
charlesmn 0:d6a9ba597c26 83
charlesmn 0:d6a9ba597c26 84 private:
charlesmn 0:d6a9ba597c26 85 InterruptIn _interrupt;
charlesmn 0:d6a9ba597c26 86 volatile int _count;
charlesmn 0:d6a9ba597c26 87 VL53L1_DEV Devlocal;
charlesmn 0:d6a9ba597c26 88 int status;
charlesmn 0:d6a9ba597c26 89
charlesmn 0:d6a9ba597c26 90 };
charlesmn 0:d6a9ba597c26 91
charlesmn 0:d6a9ba597c26 92
charlesmn 0:d6a9ba597c26 93
charlesmn 0:d6a9ba597c26 94 VL53L1_Dev_t devCentre;
charlesmn 0:d6a9ba597c26 95 VL53L1_Dev_t devLeft;
charlesmn 0:d6a9ba597c26 96 VL53L1_Dev_t devRight;
charlesmn 0:d6a9ba597c26 97 VL53L1_DEV Dev = &devCentre;
charlesmn 0:d6a9ba597c26 98
charlesmn 0:d6a9ba597c26 99
charlesmn 0:d6a9ba597c26 100 /*=================================== Main ==================================
charlesmn 0:d6a9ba597c26 101 =============================================================================*/
charlesmn 0:d6a9ba597c26 102 int main()
charlesmn 0:d6a9ba597c26 103 {
charlesmn 0:d6a9ba597c26 104 int status;
charlesmn 0:d6a9ba597c26 105 VL53L1X * Sensor;
charlesmn 0:d6a9ba597c26 106 uint16_t wordData;
charlesmn 0:d6a9ba597c26 107 uint8_t ToFSensor = 1; // 0=Left, 1=Center(default), 2=Right
charlesmn 0:d6a9ba597c26 108
charlesmn 0:d6a9ba597c26 109
charlesmn 0:d6a9ba597c26 110 WaitForMeasurement* int2;
charlesmn 0:d6a9ba597c26 111 WaitForMeasurement* int1;
charlesmn 0:d6a9ba597c26 112 WaitForMeasurement* int3;
charlesmn 0:d6a9ba597c26 113
charlesmn 0:d6a9ba597c26 114 pc.baud(115200); // baud rate is important as printf statements take a lot of time
charlesmn 0:d6a9ba597c26 115
charlesmn 0:d6a9ba597c26 116 printf("Interrupt Lite-ranging\r\n");
charlesmn 0:d6a9ba597c26 117
charlesmn 0:d6a9ba597c26 118 // create i2c interface
charlesmn 0:d6a9ba597c26 119 ToF_DevI2C *dev_I2C = new ToF_DevI2C(I2C_SDA, I2C_SCL);
charlesmn 0:d6a9ba597c26 120
charlesmn 0:d6a9ba597c26 121 dev_I2C->frequency(400000); //also needs doing in spi_interface.c
charlesmn 0:d6a9ba597c26 122
charlesmn 0:d6a9ba597c26 123 /* creates the 53L1A1 expansion board singleton obj */
charlesmn 0:d6a9ba597c26 124 board = XNucleo53L1A1::instance(dev_I2C, A2, D8, D2);
charlesmn 0:d6a9ba597c26 125 printf("board created!\r\n");
charlesmn 0:d6a9ba597c26 126
charlesmn 0:d6a9ba597c26 127 /* init the 53L1A1 expansion board with default values */
charlesmn 0:d6a9ba597c26 128 status = board->init_board();
charlesmn 0:d6a9ba597c26 129 if (status) {
charlesmn 0:d6a9ba597c26 130 return 0;
charlesmn 0:d6a9ba597c26 131 }
charlesmn 0:d6a9ba597c26 132
charlesmn 0:d6a9ba597c26 133
charlesmn 0:d6a9ba597c26 134 printf("board initiated! - %d\r\n", status);
charlesmn 0:d6a9ba597c26 135
charlesmn 0:d6a9ba597c26 136
charlesmn 0:d6a9ba597c26 137 // create sensor controller classes for each vl53l1 and configure each vl53l1
charlesmn 0:d6a9ba597c26 138 for (ToFSensor=0;ToFSensor<NUM_SENSORS ;ToFSensor++)
charlesmn 0:d6a9ba597c26 139 {
charlesmn 0:d6a9ba597c26 140 switch(ToFSensor){
charlesmn 0:d6a9ba597c26 141 case 1:
charlesmn 0:d6a9ba597c26 142 if (board->sensor_centre== NULL ) continue; // don't create if sensor not detected
charlesmn 0:d6a9ba597c26 143 Dev=&devCentre;
charlesmn 0:d6a9ba597c26 144 Sensor=board->sensor_centre;
charlesmn 0:d6a9ba597c26 145 Dev->i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS;
charlesmn 0:d6a9ba597c26 146 printf("configuring centre channel \n");
charlesmn 0:d6a9ba597c26 147 break;
charlesmn 0:d6a9ba597c26 148 case 0:
charlesmn 0:d6a9ba597c26 149 if (board->sensor_left== NULL ) continue;
charlesmn 0:d6a9ba597c26 150 Dev=&devLeft;
charlesmn 0:d6a9ba597c26 151 Sensor=board->sensor_left;
charlesmn 0:d6a9ba597c26 152 Dev->i2c_slave_address = NEW_SENSOR_LEFT_ADDRESS;
charlesmn 0:d6a9ba597c26 153 printf("configuring left channel \n");
charlesmn 0:d6a9ba597c26 154 break;
charlesmn 0:d6a9ba597c26 155 case 2:
charlesmn 0:d6a9ba597c26 156 if (board->sensor_right== NULL ) continue;
charlesmn 0:d6a9ba597c26 157 Dev=&devRight;
charlesmn 0:d6a9ba597c26 158 Sensor=board->sensor_right;
charlesmn 0:d6a9ba597c26 159 Dev->i2c_slave_address = NEW_SENSOR_RIGHT_ADDRESS;
charlesmn 0:d6a9ba597c26 160 printf("configuring right channel \n");
charlesmn 0:d6a9ba597c26 161 break;
charlesmn 0:d6a9ba597c26 162 default:
charlesmn 0:d6a9ba597c26 163 printf(" error in switch, invalid ToF sensor \n");
charlesmn 0:d6a9ba597c26 164 } // end of switch
charlesmn 0:d6a9ba597c26 165
charlesmn 0:d6a9ba597c26 166 // configure the sensors
charlesmn 0:d6a9ba597c26 167 Dev->comms_speed_khz = 400;
charlesmn 0:d6a9ba597c26 168 Dev->comms_type = 1;
charlesmn 0:d6a9ba597c26 169
charlesmn 0:d6a9ba597c26 170 /* Device Initialization and setting */
charlesmn 0:d6a9ba597c26 171 status = Sensor->vl53L1_DataInit();
charlesmn 0:d6a9ba597c26 172 status = Sensor->vl53L1_StaticInit();
charlesmn 0:d6a9ba597c26 173 status = Sensor->vl53L1_SetPresetMode( VL53L1_PRESETMODE_LITE_RANGING);
charlesmn 0:d6a9ba597c26 174 status = Sensor->vl53L1_SetDistanceMode( VL53L1_DISTANCEMODE_LONG);
charlesmn 0:d6a9ba597c26 175 // status = Sensor->vl53L1_SetMeasurementTimingBudgetMicroSeconds( 50000);
charlesmn 0:d6a9ba597c26 176 // status = Sensor->vl53L1_SetInterMeasurementPeriodMilliSeconds( 100);
charlesmn 0:d6a9ba597c26 177 } // end of sensor loop
charlesmn 0:d6a9ba597c26 178 printf("starting sensors \n");
charlesmn 0:d6a9ba597c26 179
charlesmn 0:d6a9ba597c26 180 // initialise sensor interrupts
charlesmn 0:d6a9ba597c26 181 if (board->sensor_centre!= NULL )
charlesmn 0:d6a9ba597c26 182 {
charlesmn 0:d6a9ba597c26 183 Sensor=board->sensor_centre;
charlesmn 0:d6a9ba597c26 184 devCentre.i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS;
charlesmn 0:d6a9ba597c26 185 int1 = new WaitForMeasurement(A2,&devCentre); // initialise sensor interrupts
charlesmn 0:d6a9ba597c26 186 status = Sensor->vl53L1_StartMeasurement();
charlesmn 0:d6a9ba597c26 187 printf("started interrupt centre %d\n",status);
charlesmn 0:d6a9ba597c26 188 }
charlesmn 0:d6a9ba597c26 189
charlesmn 0:d6a9ba597c26 190
charlesmn 0:d6a9ba597c26 191 if (board->sensor_left!= NULL )
charlesmn 0:d6a9ba597c26 192 {
charlesmn 0:d6a9ba597c26 193 Sensor=board->sensor_left;
charlesmn 0:d6a9ba597c26 194 devLeft.i2c_slave_address = NEW_SENSOR_LEFT_ADDRESS;
charlesmn 0:d6a9ba597c26 195 int2 = new WaitForMeasurement(D8,&devLeft);
charlesmn 0:d6a9ba597c26 196 status = Sensor->vl53L1_StartMeasurement();
charlesmn 0:d6a9ba597c26 197 printf("started interrupt left %d\n",status);
charlesmn 0:d6a9ba597c26 198 }
charlesmn 0:d6a9ba597c26 199
charlesmn 0:d6a9ba597c26 200 if (board->sensor_right!= NULL )
charlesmn 0:d6a9ba597c26 201 {
charlesmn 0:d6a9ba597c26 202 Sensor=board->sensor_right;
charlesmn 0:d6a9ba597c26 203 devRight.i2c_slave_address = NEW_SENSOR_RIGHT_ADDRESS;
charlesmn 0:d6a9ba597c26 204 int3 = new WaitForMeasurement(D2,&devRight);
charlesmn 0:d6a9ba597c26 205 status = board->sensor_right->vl53L1_StartMeasurement();
charlesmn 0:d6a9ba597c26 206 printf("started interrupt sensor_right %d\n",status);
charlesmn 0:d6a9ba597c26 207 }
charlesmn 0:d6a9ba597c26 208
charlesmn 0:d6a9ba597c26 209
charlesmn 0:d6a9ba597c26 210
charlesmn 0:d6a9ba597c26 211 // loop waiting for interrupts to happen. This is signaled by int_centre_result,int_left_result or int_right_result
charlesmn 0:d6a9ba597c26 212 // being non zero. The are set back to zero when processing is completed
charlesmn 0:d6a9ba597c26 213 while (1)
charlesmn 0:d6a9ba597c26 214 {
charlesmn 0:d6a9ba597c26 215 static VL53L1_RangingMeasurementData_t RangingData;
charlesmn 0:d6a9ba597c26 216
charlesmn 0:d6a9ba597c26 217 wait_ms( 1 * 30);
charlesmn 0:d6a9ba597c26 218 if (int_centre_result != 0)
charlesmn 0:d6a9ba597c26 219 {
charlesmn 0:d6a9ba597c26 220 // read result
charlesmn 0:d6a9ba597c26 221 status = board->sensor_centre->vl53L1_GetRangingMeasurementData( &RangingData);
charlesmn 0:d6a9ba597c26 222 // if valid result print it
charlesmn 0:d6a9ba597c26 223 if (RangingData.RangeStatus != 255)
charlesmn 0:d6a9ba597c26 224 printf("c %d,%d \n",RangingData.RangeStatus,RangingData.RangeMilliMeter);
charlesmn 0:d6a9ba597c26 225 // clear interrupt flag
charlesmn 0:d6a9ba597c26 226 int_centre_result = 0;
charlesmn 0:d6a9ba597c26 227 // clear theinterrupt and wait for another result
charlesmn 0:d6a9ba597c26 228 status = board->sensor_centre->vl53L1_ClearInterruptAndStartMeasurement();
charlesmn 0:d6a9ba597c26 229 }
charlesmn 0:d6a9ba597c26 230
charlesmn 0:d6a9ba597c26 231
charlesmn 0:d6a9ba597c26 232 if (int_left_result != 0)
charlesmn 0:d6a9ba597c26 233 {
charlesmn 0:d6a9ba597c26 234 // read result
charlesmn 0:d6a9ba597c26 235 status = board->sensor_left->vl53L1_GetRangingMeasurementData( &RangingData);
charlesmn 0:d6a9ba597c26 236 // if valid result print it
charlesmn 0:d6a9ba597c26 237 if (RangingData.RangeStatus != 255)
charlesmn 0:d6a9ba597c26 238 printf("l %d,%d\n",RangingData.RangeStatus,RangingData.RangeMilliMeter);
charlesmn 0:d6a9ba597c26 239 // clear interrupt flag
charlesmn 0:d6a9ba597c26 240 int_left_result = 0;
charlesmn 0:d6a9ba597c26 241 // clear theinterrupt and wait for another result
charlesmn 0:d6a9ba597c26 242 status = board->sensor_left->vl53L1_ClearInterruptAndStartMeasurement();
charlesmn 0:d6a9ba597c26 243 }
charlesmn 0:d6a9ba597c26 244
charlesmn 0:d6a9ba597c26 245
charlesmn 0:d6a9ba597c26 246 if (int_right_result != 0)
charlesmn 0:d6a9ba597c26 247 {
charlesmn 0:d6a9ba597c26 248 // read result
charlesmn 0:d6a9ba597c26 249 status = board->sensor_right->vl53L1_GetRangingMeasurementData( &RangingData);
charlesmn 0:d6a9ba597c26 250 // if valid result print it
charlesmn 0:d6a9ba597c26 251 if (RangingData.RangeStatus != 255)
charlesmn 0:d6a9ba597c26 252 printf("r %d,%d\n",RangingData.RangeStatus,RangingData.RangeMilliMeter);
charlesmn 0:d6a9ba597c26 253 // clear interrupt flag
charlesmn 0:d6a9ba597c26 254 int_right_result = 0;
charlesmn 0:d6a9ba597c26 255 // clear theinterrupt and wait for another result
charlesmn 0:d6a9ba597c26 256 status = board->sensor_right->vl53L1_ClearInterruptAndStartMeasurement();
charlesmn 0:d6a9ba597c26 257 }
charlesmn 0:d6a9ba597c26 258
charlesmn 0:d6a9ba597c26 259 }
charlesmn 0:d6a9ba597c26 260 printf("terminated");
charlesmn 0:d6a9ba597c26 261 }
charlesmn 0:d6a9ba597c26 262