A demonstration program to show the use of a VL53L3CX ToF sensor in interrupt mode on a F401 board with a x-nucleo shield. This uses the Ranging Library. Mbed6.

Dependencies:   X_NUCLEO_53L3CX

Committer:
charlesmn
Date:
Thu Jul 22 11:41:52 2021 +0000
Revision:
5:d722fa004f0e
Parent:
3:2270c55c700b
I had changed the name of X_NUCLEO_53L3CX but not the repository where it is store. This fixes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:3071368672bf 1 /*
charlesmn 0:3071368672bf 2 * This VL53L3 Expansion board test application performs range measurements
charlesmn 1:3a684d948ac6 3 * using the onboard embedded sensor in interrupt mode.
charlesmn 0:3071368672bf 4 * Measured ranges are output on the Serial Port, running at 115200 baud.
charlesmn 0:3071368672bf 5 *
charlesmn 0:3071368672bf 6 * The Reset button can be used to restart the program.
charlesmn 0:3071368672bf 7 *
charlesmn 0:3071368672bf 8 * *** Note :
charlesmn 0:3071368672bf 9 * Default Mbed build system settings disable printf floating-point support.
charlesmn 0:3071368672bf 10 * Online builds seem unable to configure this.
charlesmn 0:3071368672bf 11 * Offline builds can enable printf floating-point support.
charlesmn 0:3071368672bf 12 * https://github.com/ARMmbed/mbed-os/blob/master/platform/source/minimal-printf/README.md
charlesmn 0:3071368672bf 13 * .\mbed-os\platform\mbed_lib.json
charlesmn 0:3071368672bf 14 *
charlesmn 0:3071368672bf 15 */
charlesmn 0:3071368672bf 16
charlesmn 0:3071368672bf 17 #include <stdio.h>
charlesmn 0:3071368672bf 18 #include <time.h>
charlesmn 0:3071368672bf 19
charlesmn 0:3071368672bf 20 #include "mbed.h"
charlesmn 0:3071368672bf 21
charlesmn 0:3071368672bf 22 #include "vl53L3_I2c.h"
charlesmn 0:3071368672bf 23 #include "vl53lx_platform_user_data.h"
charlesmn 0:3071368672bf 24 #include "53l3a2_ranging_sensor.h"
charlesmn 0:3071368672bf 25 #include "VL53L3A2_RangingClass.h"
charlesmn 0:3071368672bf 26 #include "pinmap.h"
charlesmn 0:3071368672bf 27
charlesmn 0:3071368672bf 28 #define BSP_ERROR_NONE 0
charlesmn 0:3071368672bf 29
charlesmn 0:3071368672bf 30
charlesmn 0:3071368672bf 31 #if (MBED_VERSION > 60300)
charlesmn 0:3071368672bf 32 UnbufferedSerial pc(USBTX, USBRX);
charlesmn 0:3071368672bf 33 extern "C" void wait_ms(int ms);
charlesmn 0:3071368672bf 34 #else
charlesmn 0:3071368672bf 35 Serial pc(SERIAL_TX, SERIAL_RX);
charlesmn 0:3071368672bf 36 #endif
charlesmn 0:3071368672bf 37
charlesmn 0:3071368672bf 38
charlesmn 0:3071368672bf 39 #include "53l3a2_ranging_sensor.h"
charlesmn 0:3071368672bf 40
charlesmn 0:3071368672bf 41 VL53L3A2_SENSOR *sensor; //class for sensor commands
charlesmn 1:3a684d948ac6 42
charlesmn 1:3a684d948ac6 43 // interrupt pins for the three sensors.
charlesmn 1:3a684d948ac6 44 // These are the default Pins but can be
charlesmn 1:3a684d948ac6 45 // changed by adding solder blobs to the x-nucleo
charlesmn 1:3a684d948ac6 46 PinName InterruptPins[] = {D8,A2,D2};
charlesmn 1:3a684d948ac6 47
charlesmn 0:3071368672bf 48
charlesmn 0:3071368672bf 49
charlesmn 0:3071368672bf 50 /* Private typedef -----------------------------------------------------------*/
charlesmn 0:3071368672bf 51
charlesmn 0:3071368672bf 52 /* Private define ------------------------------------------------------------*/
charlesmn 1:3a684d948ac6 53 #define SENSOR_LEFT_NUMBER 0
charlesmn 1:3a684d948ac6 54 #define SENSOR_CENTRE_NUMBER 1
charlesmn 1:3a684d948ac6 55 #define SENSOR_RIGHT_NUMBER 2
charlesmn 0:3071368672bf 56
charlesmn 0:3071368672bf 57 /* Private variables ---------------------------------------------------------*/
charlesmn 0:3071368672bf 58 static int32_t status = 0;
charlesmn 0:3071368672bf 59
charlesmn 0:3071368672bf 60
charlesmn 1:3a684d948ac6 61 static const char *TofDevStr[] = {
charlesmn 0:3071368672bf 62 [VL53L3A2_DEV_LEFT] = "LEFT",
charlesmn 0:3071368672bf 63 [VL53L3A2_DEV_CENTER] = "CENTER",
charlesmn 0:3071368672bf 64 [VL53L3A2_DEV_RIGHT] = "RIGHT"
charlesmn 0:3071368672bf 65 };
charlesmn 0:3071368672bf 66
charlesmn 0:3071368672bf 67 /* Private function prototypes -----------------------------------------------*/
charlesmn 0:3071368672bf 68 static void MX_53L3A2_MultiSensorRanging_Init(void);
charlesmn 0:3071368672bf 69 static void MX_53L3A2_MultiSensorRanging_Process(void);
charlesmn 2:e34aac99432a 70 static void print_result(uint8_t ToF_sensor,RANGING_SENSOR_Result_t *Result);
charlesmn 0:3071368672bf 71
charlesmn 0:3071368672bf 72 void MX_TOF_Process(void);
charlesmn 0:3071368672bf 73
charlesmn 0:3071368672bf 74 //flag to signal an interrupt has occured
charlesmn 0:3071368672bf 75 volatile uint8_t EventDetected = 0;
charlesmn 0:3071368672bf 76
charlesmn 0:3071368672bf 77 int ToF_sensor = SENSOR_CENTRE_NUMBER; // select the sensor to use
charlesmn 0:3071368672bf 78
charlesmn 0:3071368672bf 79
charlesmn 0:3071368672bf 80 /* ISR callback function of the active sensor */
charlesmn 1:3a684d948ac6 81 /* all it does set a flag which causes the main loop to get data. */
charlesmn 1:3a684d948ac6 82 /* Interrupts activated and defined in CUSTOM_RANGING_ConfigProfile() */
charlesmn 0:3071368672bf 83 void sensor_irq(void)
charlesmn 0:3071368672bf 84 {
charlesmn 0:3071368672bf 85 EventDetected = 1;
charlesmn 0:3071368672bf 86 }
charlesmn 0:3071368672bf 87
charlesmn 0:3071368672bf 88
charlesmn 0:3071368672bf 89 // initialise the sensor
charlesmn 0:3071368672bf 90 static void MX_53L3A2_MultiSensorRanging_Init(void)
charlesmn 0:3071368672bf 91 {
charlesmn 1:3a684d948ac6 92 uint16_t i2c_addr;
charlesmn 1:3a684d948ac6 93 uint32_t id;
charlesmn 0:3071368672bf 94
charlesmn 1:3a684d948ac6 95 // shut down all sensors
charlesmn 1:3a684d948ac6 96 sensor->VL53L3A2_RANGING_SetPowerMode(SENSOR_CENTRE_NUMBER, RANGING_SENSOR_POWERMODE_OFF);
charlesmn 1:3a684d948ac6 97 sensor->VL53L3A2_RANGING_SetPowerMode(SENSOR_LEFT_NUMBER, RANGING_SENSOR_POWERMODE_OFF);
charlesmn 1:3a684d948ac6 98 sensor->VL53L3A2_RANGING_SetPowerMode(SENSOR_RIGHT_NUMBER, RANGING_SENSOR_POWERMODE_OFF);
charlesmn 1:3a684d948ac6 99 wait_ms(100);
charlesmn 1:3a684d948ac6 100
charlesmn 1:3a684d948ac6 101 printf("53L3A2 Single Sensor Ranging interrupt demo application\n");
charlesmn 0:3071368672bf 102
charlesmn 1:3a684d948ac6 103 /* Power on the device, initialize it and change it's address.
charlesmn 1:3a684d948ac6 104 * Once the address is updated, the communication with the devices is checked by
charlesmn 1:3a684d948ac6 105 * reading its ID.
charlesmn 1:3a684d948ac6 106 */
charlesmn 1:3a684d948ac6 107
charlesmn 1:3a684d948ac6 108 printf("VL53L3A2_RANGING_SENSOR_Init\n");
charlesmn 1:3a684d948ac6 109 sensor->VL53L3A2_RANGING_Init(ToF_sensor);
charlesmn 1:3a684d948ac6 110 if (status) {
charlesmn 1:3a684d948ac6 111 printf("VL53L3A2_RANGING_SENSOR_Init failed for sensor %d \n",ToF_sensor);
charlesmn 1:3a684d948ac6 112 }
charlesmn 1:3a684d948ac6 113 printf("VL53L3A2_RANGING_SENSOR_SetAddress\n");
charlesmn 1:3a684d948ac6 114
charlesmn 1:3a684d948ac6 115 wait_ms(100);
charlesmn 1:3a684d948ac6 116 i2c_addr = (0x52 + (ToF_sensor + 1) * 2); /* 0x54, 0x56, 0x58 */
charlesmn 1:3a684d948ac6 117 sensor->VL53L3A2_RANGING_SetAddress(ToF_sensor, i2c_addr);
charlesmn 1:3a684d948ac6 118
charlesmn 1:3a684d948ac6 119 wait_ms(100);
charlesmn 0:3071368672bf 120 }
charlesmn 0:3071368672bf 121
charlesmn 0:3071368672bf 122
charlesmn 0:3071368672bf 123 // start ranging and enter an infinite loop to collect measurements
charlesmn 0:3071368672bf 124 // The collection of data is triggered by a flag which is set after an interrupt occurs
charlesmn 0:3071368672bf 125 static void MX_53L3A2_MultiSensorRanging_Process(void)
charlesmn 0:3071368672bf 126 {
charlesmn 0:3071368672bf 127
charlesmn 0:3071368672bf 128 // config profile details
charlesmn 0:3071368672bf 129 RANGING_SENSOR_Result_t Result;
charlesmn 0:3071368672bf 130 RANGING_SENSOR_ProfileConfig_t Profile;
charlesmn 0:3071368672bf 131 printf("MX_53L3A2_MultiSensorRanging_Process\n");
charlesmn 1:3a684d948ac6 132
charlesmn 1:3a684d948ac6 133
charlesmn 0:3071368672bf 134 Profile.RangingProfile = RS_MULTI_TARGET_LONG_RANGE;
charlesmn 0:3071368672bf 135 Profile.TimingBudget = 30; /* 16 ms < TimingBudget < 500 ms */
charlesmn 0:3071368672bf 136 Profile.Frequency = 0; /* not necessary in simple ranging */
charlesmn 0:3071368672bf 137 Profile.EnableAmbient = 0; /* Enable: 1, Disable: 0 */
charlesmn 0:3071368672bf 138 Profile.EnableSignal = 0; /* Enable: 1, Disable: 0 */
charlesmn 1:3a684d948ac6 139 Profile.pin_gpio1 = InterruptPins[ToF_sensor]; // interrupt pin
charlesmn 1:3a684d948ac6 140 Profile.Interrupt_Func = sensor_irq; // function that handles interrupts
charlesmn 1:3a684d948ac6 141 Profile.EnableInterrupt = 1; // enables interupts
charlesmn 0:3071368672bf 142
charlesmn 0:3071368672bf 143 printf("MX_53L3A2_MultiSensorRanging_Process configure sensors\n");
charlesmn 1:3a684d948ac6 144 sensor->VL53L3A2_RANGING_ConfigProfile(ToF_sensor, &Profile);
charlesmn 1:3a684d948ac6 145 if (status != BSP_ERROR_NONE) {
charlesmn 1:3a684d948ac6 146 printf("VL53L3A2_RANGING_SENSOR_ConfigProfile failed sensor %d status %d\n",ToF_sensor,(int)status);
charlesmn 0:3071368672bf 147 }
charlesmn 1:3a684d948ac6 148 wait_ms(100);
charlesmn 1:3a684d948ac6 149
charlesmn 0:3071368672bf 150
charlesmn 1:3a684d948ac6 151 printf("VL53L3A2_RANGING_Start %d\n",ToF_sensor);
charlesmn 0:3071368672bf 152 status = sensor->VL53L3A2_RANGING_Start(ToF_sensor, RS_MODE_BLOCKING_CONTINUOUS);
charlesmn 1:3a684d948ac6 153 if (status != BSP_ERROR_NONE) {
charlesmn 0:3071368672bf 154 printf("VL53L3A2_RANGING_SENSOR_Start failed sensor %d status %d\n",ToF_sensor,(int)status);
charlesmn 0:3071368672bf 155 }
charlesmn 0:3071368672bf 156
charlesmn 0:3071368672bf 157
charlesmn 1:3a684d948ac6 158 EventDetected = 1; // clear any existing interrupts
charlesmn 1:3a684d948ac6 159
charlesmn 1:3a684d948ac6 160 // repeatedly read data and start next measurement
charlesmn 1:3a684d948ac6 161 while (1) {
charlesmn 1:3a684d948ac6 162 if ( EventDetected == 1 ) { // irq detected
charlesmn 1:3a684d948ac6 163 EventDetected = 0;
charlesmn 1:3a684d948ac6 164 status = sensor->VL53L3A2_RANGING_GetDistance(ToF_sensor, &Result); // gets the data and clears irq and starts next measurement
charlesmn 3:2270c55c700b 165
charlesmn 1:3a684d948ac6 166 if ((status == BSP_ERROR_NONE) &&
charlesmn 1:3a684d948ac6 167 (Result.NumberOfZones != 0))
charlesmn 0:3071368672bf 168 {
charlesmn 2:e34aac99432a 169 print_result(ToF_sensor,&Result);
charlesmn 0:3071368672bf 170 }
charlesmn 1:3a684d948ac6 171 }
charlesmn 1:3a684d948ac6 172
charlesmn 0:3071368672bf 173 }
charlesmn 0:3071368672bf 174 }
charlesmn 0:3071368672bf 175
charlesmn 0:3071368672bf 176
charlesmn 2:e34aac99432a 177 // Note in VL53L3CX there is only one Zone so NumberOfZones is not used and is always assumed to be 1
charlesmn 2:e34aac99432a 178 static void print_result(uint8_t ToF_sensor,RANGING_SENSOR_Result_t *Result)
charlesmn 0:3071368672bf 179 {
charlesmn 2:e34aac99432a 180 uint8_t zone = 0; // in VL53L3CX there is only one zone
charlesmn 0:3071368672bf 181 uint8_t target = 0;
charlesmn 1:3a684d948ac6 182
charlesmn 2:e34aac99432a 183 for (target = 0; target < Result->ZoneResult[zone].NumberOfTargets; target++) {
charlesmn 2:e34aac99432a 184 if (Result->ZoneResult[zone].Status[target] == VL53LX_RANGESTATUS_RANGE_VALID )
charlesmn 2:e34aac99432a 185 {
charlesmn 2:e34aac99432a 186 printf("\n%s\t - ", TofDevStr[ToF_sensor]);
charlesmn 2:e34aac99432a 187 printf(" |---> ");
charlesmn 2:e34aac99432a 188 printf("Status = %d, Target %d, Distance = %5d mm",
charlesmn 2:e34aac99432a 189 Result->ZoneResult[zone].Status[target],
charlesmn 2:e34aac99432a 190 target,
charlesmn 2:e34aac99432a 191 Result->ZoneResult[zone].Distance[target]);
charlesmn 2:e34aac99432a 192 }
charlesmn 1:3a684d948ac6 193
charlesmn 2:e34aac99432a 194 }
charlesmn 0:3071368672bf 195 }
charlesmn 1:3a684d948ac6 196
charlesmn 0:3071368672bf 197
charlesmn 0:3071368672bf 198
charlesmn 0:3071368672bf 199 /*=================================== Main ==================================
charlesmn 0:3071368672bf 200 =============================================================================*/
charlesmn 0:3071368672bf 201 int main()
charlesmn 0:3071368672bf 202 {
charlesmn 1:3a684d948ac6 203
charlesmn 1:3a684d948ac6 204 pc.baud(115200); // baud rate is important as printf statements take a lot of time
charlesmn 1:3a684d948ac6 205
charlesmn 1:3a684d948ac6 206 sensor = new VL53L3A2_SENSOR();
charlesmn 0:3071368672bf 207
charlesmn 1:3a684d948ac6 208 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\r\n");
charlesmn 1:3a684d948ac6 209 printf("VL53L3CX_Shield_1Sensors_Interrupt\r\n");
charlesmn 1:3a684d948ac6 210
charlesmn 1:3a684d948ac6 211 MX_53L3A2_MultiSensorRanging_Init(); // initialise the sensor
charlesmn 1:3a684d948ac6 212
charlesmn 1:3a684d948ac6 213 while (1) {
charlesmn 1:3a684d948ac6 214 MX_53L3A2_MultiSensorRanging_Process(); // start ranging and collect data
charlesmn 1:3a684d948ac6 215 }
charlesmn 0:3071368672bf 216
charlesmn 0:3071368672bf 217 }
charlesmn 0:3071368672bf 218
charlesmn 1:3a684d948ac6 219 // needed for later version of mbed as wait_ms removed
charlesmn 0:3071368672bf 220 #if (MBED_VERSION > 60300)
charlesmn 0:3071368672bf 221 extern "C" void wait_ms(int ms)
charlesmn 0:3071368672bf 222 {
charlesmn 0:3071368672bf 223 thread_sleep_for(ms);
charlesmn 0:3071368672bf 224 }
charlesmn 0:3071368672bf 225 #endif
charlesmn 1:3a684d948ac6 226