ST Expansion SW Team / Mbed 2 deprecated VL53L3_NoShield_1sensor_interrupt_Mb2

Dependencies:   mbed VL53L3ExpansionBoard

Committer:
charlesmn
Date:
Mon Oct 19 07:30:36 2020 +0000
Revision:
2:75271310def9
Parent:
0:34269810c435
Some name changes. No functional change.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:34269810c435 1 /*
charlesmn 0:34269810c435 2 * my_no_shield_interrupt.h
charlesmn 0:34269810c435 3 * This pogram is a simple sample program which demonstrates the VL53L3 being used without
charlesmn 0:34269810c435 4 * a nucleo sheild using interrupts to alert the program that a measurement is ready.
charlesmn 0:34269810c435 5 * The shutdown pins are directly connected to the MCU pins D9,D4 and D3
charlesmn 0:34269810c435 6 * as defined by this line:
charlesmn 0:34269810c435 7 * status = board->init_board(D9,D4,D3);
charlesmn 0:34269810c435 8 * the interrupt pins are defined in
charlesmn 0:34269810c435 9 * board = NoShield53L3::instance(dev_I2C, A2, D8, D2);
charlesmn 0:34269810c435 10 *
charlesmn 0:34269810c435 11 * This program only uses one sensor but can easily be adapted to run 3.
charlesmn 0:34269810c435 12 *
charlesmn 0:34269810c435 13 * Measured ranges are ouput on the Serial Port, running at 115200 baud.
charlesmn 0:34269810c435 14 *
charlesmn 0:34269810c435 15 * The Reset button can be used to restart the program.
charlesmn 0:34269810c435 16 */
charlesmn 0:34269810c435 17
charlesmn 0:34269810c435 18
charlesmn 0:34269810c435 19
charlesmn 0:34269810c435 20 #include <stdio.h>
charlesmn 0:34269810c435 21
charlesmn 0:34269810c435 22 #include "mbed.h"
charlesmn 0:34269810c435 23 #include "NoShield53L3.h"
charlesmn 2:75271310def9 24 #include "vl53L3_I2c.h"
charlesmn 0:34269810c435 25 #include <time.h>
charlesmn 0:34269810c435 26
charlesmn 0:34269810c435 27 // define I2C pins
charlesmn 0:34269810c435 28 #define VL53L1_I2C_SDA D14
charlesmn 0:34269810c435 29 #define VL53L1_I2C_SCL D15
charlesmn 0:34269810c435 30
charlesmn 0:34269810c435 31 #define TIMINGBUDGET 50
charlesmn 0:34269810c435 32
charlesmn 0:34269810c435 33 static NoShield53L3 *board=NULL;
charlesmn 0:34269810c435 34 Serial pc(SERIAL_TX, SERIAL_RX);
charlesmn 0:34269810c435 35
charlesmn 0:34269810c435 36 static int int_centre_dropped = 0;
charlesmn 0:34269810c435 37 static int int_left_dropped = 0;
charlesmn 0:34269810c435 38 static int int_right_dropped = 0;
charlesmn 0:34269810c435 39
charlesmn 0:34269810c435 40
charlesmn 0:34269810c435 41
charlesmn 0:34269810c435 42 class WaitForMeasurement {
charlesmn 0:34269810c435 43 public:
charlesmn 0:34269810c435 44
charlesmn 0:34269810c435 45
charlesmn 0:34269810c435 46 // this class services the interrupts from the ToF sensors.
charlesmn 0:34269810c435 47 // There is a limited amount you can do in an interrupt routine; printfs,mutexes break them among other things.
charlesmn 0:34269810c435 48 // We keep things simple by only raising a flag so all the real work is done outside the interrupt.
charlesmn 0:34269810c435 49 // 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:34269810c435 50 WaitForMeasurement(): _interrupt(A1)
charlesmn 0:34269810c435 51 {
charlesmn 0:34269810c435 52 }
charlesmn 0:34269810c435 53
charlesmn 0:34269810c435 54
charlesmn 0:34269810c435 55 // constructor - Sensor is not used and can be removed
charlesmn 0:34269810c435 56 WaitForMeasurement(PinName pin,VL53LX_DEV Dev) : _interrupt(pin) // create the InterruptIn on the pin specified to Counter
charlesmn 0:34269810c435 57 {
charlesmn 0:34269810c435 58 Devlocal = Dev;
charlesmn 0:34269810c435 59 _interrupt.fall(callback(this, &WaitForMeasurement::lost_interrupt)); // attach increment function of this counter instance
charlesmn 0:34269810c435 60
charlesmn 0:34269810c435 61 }
charlesmn 0:34269810c435 62
charlesmn 0:34269810c435 63
charlesmn 0:34269810c435 64 // function is called every time an interupt is seen. A flag is raised which allows the main routine to service the interupt.
charlesmn 0:34269810c435 65
charlesmn 0:34269810c435 66 void lost_interrupt()
charlesmn 0:34269810c435 67 {
charlesmn 0:34269810c435 68 if (Devlocal->I2cDevAddr == NEW_SENSOR_CENTRE_ADDRESS)
charlesmn 0:34269810c435 69 int_centre_dropped = 1; //flag to main that interrupt happened
charlesmn 0:34269810c435 70 if (Devlocal->I2cDevAddr == NEW_SENSOR_LEFT_ADDRESS)
charlesmn 0:34269810c435 71 int_left_dropped = 1; //flag to main that interrupt happened
charlesmn 0:34269810c435 72 if (Devlocal->I2cDevAddr == NEW_SENSOR_RIGHT_ADDRESS)
charlesmn 0:34269810c435 73 int_right_dropped = 1; //flag to main that interrupt happened
charlesmn 0:34269810c435 74 }
charlesmn 0:34269810c435 75
charlesmn 0:34269810c435 76
charlesmn 0:34269810c435 77 //destructor
charlesmn 0:34269810c435 78 ~WaitForMeasurement()
charlesmn 0:34269810c435 79 {
charlesmn 0:34269810c435 80 printf("destruction \n");
charlesmn 0:34269810c435 81 }
charlesmn 0:34269810c435 82
charlesmn 0:34269810c435 83 private:
charlesmn 0:34269810c435 84 InterruptIn _interrupt;
charlesmn 0:34269810c435 85 VL53LX_DEV Devlocal; //store the device for this instance of the class
charlesmn 0:34269810c435 86 int status;
charlesmn 0:34269810c435 87
charlesmn 0:34269810c435 88 };
charlesmn 0:34269810c435 89
charlesmn 0:34269810c435 90
charlesmn 0:34269810c435 91 // sensor classes. We don't use left and right in this program as we only have one sensor
charlesmn 0:34269810c435 92 VL53LX_Dev_t devCentre;
charlesmn 0:34269810c435 93 VL53LX_Dev_t devLeft;
charlesmn 0:34269810c435 94 VL53LX_Dev_t devRight;
charlesmn 0:34269810c435 95 //VL53LX_DEV Dev = &devCentre;
charlesmn 0:34269810c435 96
charlesmn 0:34269810c435 97
charlesmn 0:34269810c435 98
charlesmn 0:34269810c435 99
charlesmn 0:34269810c435 100
charlesmn 0:34269810c435 101 /*=================================== Main ==================================
charlesmn 0:34269810c435 102 =============================================================================*/
charlesmn 0:34269810c435 103 int main()
charlesmn 0:34269810c435 104 {
charlesmn 0:34269810c435 105 int status;
charlesmn 0:34269810c435 106 // VL53LX * Sensor;
charlesmn 0:34269810c435 107 uint16_t wordData;
charlesmn 0:34269810c435 108 uint8_t ToFSensor = 1; // 0=Left, 1=Center(default), 2=Right
charlesmn 0:34269810c435 109
charlesmn 0:34269810c435 110 // interupt classes for the sensors . we only use int1
charlesmn 0:34269810c435 111 WaitForMeasurement* int2;
charlesmn 0:34269810c435 112 WaitForMeasurement* int1;
charlesmn 0:34269810c435 113 WaitForMeasurement* int3;
charlesmn 0:34269810c435 114
charlesmn 0:34269810c435 115 pc.baud(115200); // baud rate is important as printf statements take a lot of time
charlesmn 0:34269810c435 116
charlesmn 0:34269810c435 117 printf("Hello world!\r\n");
charlesmn 0:34269810c435 118
charlesmn 0:34269810c435 119 // start the I2C interface
charlesmn 2:75271310def9 120 vl53L3_DevI2C *dev_I2C = new vl53L3_DevI2C(VL53L1_I2C_SDA, VL53L1_I2C_SCL);
charlesmn 0:34269810c435 121
charlesmn 0:34269810c435 122
charlesmn 0:34269810c435 123 /* no expansion board so don't use stmpe1600. Define interupt pins, only A2 used with one sensor */
charlesmn 0:34269810c435 124 board = NoShield53L3::instance(dev_I2C, A2, D8, D2);
charlesmn 0:34269810c435 125 printf("board created!\r\n");
charlesmn 0:34269810c435 126
charlesmn 0:34269810c435 127 /* define the shutdown pins. D4 and D3 aren't used with one sensor */
charlesmn 0:34269810c435 128 status = board->init_board(D9,D4,D3);
charlesmn 0:34269810c435 129 if (status) {
charlesmn 0:34269810c435 130 printf("Failed to init board!\r\n");
charlesmn 0:34269810c435 131 return 0;
charlesmn 0:34269810c435 132 }
charlesmn 0:34269810c435 133
charlesmn 0:34269810c435 134
charlesmn 0:34269810c435 135 printf("board initiated! - %d\r\n", status);
charlesmn 0:34269810c435 136
charlesmn 0:34269810c435 137
charlesmn 0:34269810c435 138 wait_ms(15);
charlesmn 0:34269810c435 139
charlesmn 0:34269810c435 140 if (board->sensor_centre== NULL ) {
charlesmn 0:34269810c435 141 printf("Failed to init sensor!\r\n");
charlesmn 0:34269810c435 142 return 0;
charlesmn 0:34269810c435 143 }
charlesmn 0:34269810c435 144 printf("configuring centre channel \n");
charlesmn 0:34269810c435 145
charlesmn 0:34269810c435 146
charlesmn 0:34269810c435 147
charlesmn 0:34269810c435 148 // configure the I2C interface
charlesmn 0:34269810c435 149
charlesmn 0:34269810c435 150 devCentre.I2cDevAddr = NEW_SENSOR_CENTRE_ADDRESS;
charlesmn 0:34269810c435 151 devCentre.comms_speed_khz = 400;
charlesmn 0:34269810c435 152 devCentre.comms_type = 1;
charlesmn 0:34269810c435 153
charlesmn 0:34269810c435 154 /* Device Initialization and setting */
charlesmn 0:34269810c435 155
charlesmn 0:34269810c435 156 status = board->sensor_centre->VL53LX_DataInit();
charlesmn 0:34269810c435 157 status = board->sensor_centre->VL53LX_SetDistanceMode(VL53LX_DISTANCEMODE_LONG);
charlesmn 0:34269810c435 158 status = board->sensor_centre->VL53LX_SetMeasurementTimingBudgetMicroSeconds( TIMINGBUDGET * 1000);
charlesmn 0:34269810c435 159 status = board->sensor_centre->VL53LX_SmudgeCorrectionEnable(VL53LX_SMUDGE_CORRECTION_SINGLE);
charlesmn 0:34269810c435 160 status = board->sensor_centre->VL53LX_SetXTalkCompensationEnable(1);
charlesmn 0:34269810c435 161
charlesmn 0:34269810c435 162 printf("starting interrupt centre\n");
charlesmn 0:34269810c435 163
charlesmn 0:34269810c435 164 int1 = new WaitForMeasurement(A2,&devCentre); // initialise interrupt for the sensor
charlesmn 0:34269810c435 165 status = board->sensor_centre->VL53LX_StartMeasurement();
charlesmn 0:34269810c435 166 status = board->sensor_centre->VL53LX_ClearInterruptAndStartMeasurement();
charlesmn 0:34269810c435 167
charlesmn 0:34269810c435 168
charlesmn 0:34269810c435 169
charlesmn 0:34269810c435 170 // loop waiting for interrupts to happen. This is signaled by int_centre_dropped
charlesmn 0:34269810c435 171 // being non zero. It is set back to zero when processing is completed
charlesmn 0:34269810c435 172 while (1)
charlesmn 0:34269810c435 173 {
charlesmn 0:34269810c435 174
charlesmn 0:34269810c435 175 VL53LX_MultiRangingData_t MultiRangingData;
charlesmn 0:34269810c435 176 VL53LX_MultiRangingData_t *pMultiRangingData = &MultiRangingData;
charlesmn 0:34269810c435 177
charlesmn 0:34269810c435 178 wait_ms( 1 * 10);
charlesmn 0:34269810c435 179
charlesmn 0:34269810c435 180 if (int_centre_dropped != 0)
charlesmn 0:34269810c435 181 {
charlesmn 0:34269810c435 182 int_centre_dropped = 0;
charlesmn 0:34269810c435 183 // interrupt has occurred so a measurement is waiting
charlesmn 0:34269810c435 184 status = board->sensor_centre->VL53LX_GetMultiRangingData( pMultiRangingData);
charlesmn 0:34269810c435 185 int no_of_object_found=pMultiRangingData->NumberOfObjectsFound;
charlesmn 0:34269810c435 186 if (( no_of_object_found < 10 ) && ( no_of_object_found != 0 ))
charlesmn 0:34269810c435 187 {
charlesmn 0:34269810c435 188 for(int j=0;j<no_of_object_found;j++){
charlesmn 0:34269810c435 189 if ((pMultiRangingData->RangeData[j].RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID) ||
charlesmn 0:34269810c435 190 (pMultiRangingData->RangeData[j].RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL))
charlesmn 0:34269810c435 191 {
charlesmn 0:34269810c435 192 printf("centre\t status=%d, \t D=%5dmm, \t Signal=%2.2f Mcps, \t Ambient=%2.2f Mcps \n",
charlesmn 0:34269810c435 193 pMultiRangingData->RangeData[j].RangeStatus,
charlesmn 0:34269810c435 194 pMultiRangingData->RangeData[j].RangeMilliMeter,
charlesmn 0:34269810c435 195 pMultiRangingData->RangeData[j].SignalRateRtnMegaCps/65536.0,
charlesmn 0:34269810c435 196 pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps/65536.0);
charlesmn 0:34269810c435 197 }
charlesmn 0:34269810c435 198 }
charlesmn 0:34269810c435 199 }
charlesmn 0:34269810c435 200
charlesmn 0:34269810c435 201 wait_ms( TIMINGBUDGET);
charlesmn 0:34269810c435 202 status = board->sensor_centre->VL53LX_ClearInterruptAndStartMeasurement();
charlesmn 0:34269810c435 203 }
charlesmn 0:34269810c435 204
charlesmn 0:34269810c435 205 }
charlesmn 0:34269810c435 206 printf("terminated");
charlesmn 0:34269810c435 207 }
charlesmn 0:34269810c435 208