Mbed OS 5.x example, ranging with the VL53L1X Time-of-Flight (ToF) sensor on the X-NUCLEO-53L1A1 expansion board, and 2 VL53L1X Satellite boards, connected to the expansion board.

Dependencies:   X_NUCLEO_53L1A1

Revision:
1:e5cce6b28b6f
Parent:
0:6b7696e7df5e
Child:
2:91088f06f39e
--- a/main.cpp	Fri May 17 10:44:38 2019 +0000
+++ b/main.cpp	Fri May 17 12:24:17 2019 +0000
@@ -1,15 +1,18 @@
 /*
- *  This VL53L1X Expansion board test application performs range measurements
- *  using the onboard embedded centre sensor.
+ * This VL53L1X Expansion board sample application performs range measurements
+ * with interrupts enabled to generate a hardware interrupt each time a new
+ * measurement is ready to be read.
  *
- *  Measured ranges are ouput on the Serial Port, running at 115200 baud.
+ * Measured ranges are output on the Serial Port, running at 115200 baud.
  *
- *  The User Blue button stops the current measurement and entire program,
- *  releasing all resources.
+ * The application supports the centre, on-board, sensor and up to two satellite boards.
  *
- *  The Black Reset button is used to restart the program.
+ * The User Blue button switches between the currently selected sensor to display range
+ * results from.
  *
- *  *** NOTE : By default hardlinks U10, U11, U15 & U18, on the underside of
+ * The Black Reset button is used to restart the program.
+ *
+ * *** NOTE : By default hardlinks U10, U11, U15 & U18, on the underside of
  *            the X-NUCELO-53L0A1 expansion board are not made/OFF.
  *            These links must be made to allow interrupts from the Satellite boards
  *            to be received.
@@ -25,42 +28,167 @@
  *            Alternate INT_R is on CN9 Connector pin 5 as D2.
  *            The pinouts are shown here : https://developer.mbed.org/components/X-NUCLEO-53L1A1/
  */
-
+ 
 #include <stdio.h>
 
 #include "mbed.h"
 #include "XNucleo53L1A1.h"
 #include "vl53L1x_I2c.h"
 
-#define VL53L1_I2C_SDA   D14
-#define VL53L1_I2C_SCL   D15
+#define VL53L1_I2C_SDA   D14 
+#define VL53L1_I2C_SCL   D15 
+
+#if USER_BUTTON==PC_13  // we are cross compiling for Nucleo-64s
+InterruptIn stop_button(USER_BUTTON);
+#endif
+
+/* Installed sensors count */
+int sensorCnt = 0;
+
+/* installed sensors prefixes */
+char installedSensors[3];
 
 static XNucleo53L1A1 *board=NULL;
+Serial pc(SERIAL_TX, SERIAL_RX); 
 
-Serial pc(SERIAL_TX, SERIAL_RX);
+/* interrupt requests */
+volatile bool centerSensor = false;
+volatile bool leftSensor = false;
+volatile bool rightSensor = false;
+volatile bool int_measuring_stop = false;
+/* Current sensor number*/
+volatile int currentSensor = 0;
+
+/* current displayed sensor change IRQ */
+volatile bool switchChanged = false;
+
+/* ISR callback function of the centre sensor */
+void sensor_centre_irq(void)
+{
+    centerSensor = true;
+    board->sensor_centre->disable_interrupt_measure_detection_irq();
+}
+
+/* ISR callback function of the left sensor */
+void sensor_left_irq(void)
+{
+    leftSensor = true;
+    board->sensor_left->disable_interrupt_measure_detection_irq();
+}
+
+/* ISR callback function of the right sensor */
+void sensor_right_irq(void)
+{
+    rightSensor = true;
+    board->sensor_right->disable_interrupt_measure_detection_irq();
+}
+
+/* ISR callback function of the user blue button to switch measuring sensor. */
+void switch_measuring_sensor_irq(void)
+{
+    stop_button.disable_irq();
+    switchChanged = true;
+}
 
-/*=================================== Main ==================================
-=============================================================================*/
-int main()
+/*
+ * This function calls the interrupt handler for each sensor
+ * and outputs the range
+ */
+inline void measure_sensors()
 {
+    bool current = false;
+    uint16_t distance = 0;
 
+    /* Handle the interrupt and output the range from the centre sensor */
+    if (centerSensor) {
+        centerSensor = false;
+        board->sensor_centre->handle_irq(&distance);
+        current = (currentSensor == 0);
+        if (current) {
+            printf("Centre: %d\r\n", distance);
+        }
+    }
+
+    /* Handle the interrupt and output the range from the left sensor */
+    if (leftSensor) {
+        leftSensor = false;
+        board->sensor_left->handle_irq(&distance);
+        current = (installedSensors[currentSensor] == 'L');
+        if (current) {
+            printf("Left: %d\r\n", distance);
+        }
+    }
+
+    /* Handle the interrupt and output the range from the right sensor */
+    if (rightSensor) {
+        rightSensor = false;
+        board->sensor_right->handle_irq(&distance);
+        current = (installedSensors[currentSensor] == 'R');
+        if (current) {
+            printf("Right: %d\r\n", distance);
+        }
+    }
+}
+
+/*
+ * Add to an array a character that represents the sensor and start ranging
+ */
+int init_sensors_array()
+{
     int status = 0;
-    uint8_t ready_centre = 0;
-    uint8_t ready_left = 0;
-    uint8_t ready_right = 0;
-    uint16_t distance_centre = 0;
-    uint16_t distance_left = 0;
-    uint16_t distance_right = 0;
+    sensorCnt = 0;
+    /* start the measure on the center sensor */
+    if (NULL != board->sensor_centre) {
+        installedSensors[sensorCnt] = 'C';
+        status = board->sensor_centre->stop_measurement();
+        if (status != 0) {
+            return status;
+        }
+        status = board->sensor_centre->start_measurement(&sensor_centre_irq);
+        if (status != 0) {
+            return status;
+        }
+        ++sensorCnt;
+    }
+    /* start the measure on the left sensor */
+    if (NULL != board->sensor_left) {
+        installedSensors[sensorCnt] = 'L';
+        status = board->sensor_left->stop_measurement();
+        if (status != 0) {
+            return status;
+        }
+        status = board->sensor_left->start_measurement(&sensor_left_irq);
+        if (status != 0) {
+            return status;
+        }
+        ++sensorCnt;
+    }
+    /* start the measure on the right sensor */
+    if (NULL != board->sensor_right) {
+        installedSensors[sensorCnt] = 'R';
+        status = board->sensor_right->stop_measurement();
+        if (status != 0) {
+            return status;
+        }
+        status = board->sensor_right->start_measurement(&sensor_right_irq);
+        if (status != 0) {
+            return status;
+        }
+        ++sensorCnt;
+    }
+    currentSensor = 0;
+    return status;
+}
 
-    printf("Hello world!\r\n");
-
-    vl53L1X_DevI2C *dev_I2C = new vl53L1X_DevI2C(VL53L1_I2C_SDA, VL53L1_I2C_SCL);
-
-    printf("I2C device created!\r\n");
+/*
+ * Main ranging function
+ */
+int range_measure(vl53L1X_DevI2C *device_i2c)
+{
+    int status = 0;
 
     /* creates the 53L1A1 expansion board singleton obj */
-    board = XNucleo53L1A1::instance(dev_I2C, A2, D9, D2);
-    printf("board created!\r\n");
+    board = XNucleo53L1A1::instance(device_i2c, A2, D9, D2);
 
     /* init the 53L1A1 expansion board with default values */
     status = board->init_board();
@@ -69,55 +197,41 @@
         return status;
     }
 
-    printf("board initiated! - %d\r\n", status);
-
-    /* Start ranging on the centre sensor */
-    status = board->sensor_centre->VL53L1X_StartRanging();
+    /* init an array with chars to id the sensors */
+    status = init_sensors_array();
     if (status != 0) {
-        printf("Centre sensor failed to start ranging!\r\n");
-        return status;
-    }
-
-    /* Start ranging on the left sensor */
-    status = board->sensor_left->VL53L1X_StartRanging();
-    if (status != 0) {
-        printf("Left sensor failed to start ranging!\r\n");
-        return status;
-    }
-
-    /* Start ranging on the right sensor */
-    status = board->sensor_right->VL53L1X_StartRanging();
-    if (status != 0) {
-        printf("Right sensor failed to start ranging!\r\n");
+        printf("Failed to init sensors!\r\n");
         return status;
     }
 
-    /* Ranging loop
-     * Checks each sensor for data ready
-     */
-    while (1)
-    {
-        board->sensor_centre->VL53L1X_CheckForDataReady(&ready_centre);
-        board->sensor_left->VL53L1X_CheckForDataReady(&ready_left);
-        board->sensor_right->VL53L1X_CheckForDataReady(&ready_right);
+    printf("Entering loop mode\r\n");
 
-        if (ready_centre) {
-            board->sensor_centre->VL53L1X_GetRangeStatus(&ready_centre);
-            board->sensor_centre->VL53L1X_GetDistance(&distance_centre);
+    /* Main ranging interrupt loop */
+    while (true) {
+        measure_sensors();
+        if (switchChanged) {
+            ++currentSensor;
+            if (currentSensor == sensorCnt)
+                currentSensor = 0;
+            printf("Sensor changed to %c\r\n", installedSensors[currentSensor]);
+            switchChanged = false;
+            stop_button.enable_irq();
         }
-        if (ready_left) {
-            board->sensor_centre->VL53L1X_GetRangeStatus(&ready_left);
-            board->sensor_centre->VL53L1X_GetDistance(&distance_left);
-        }
-        if (ready_right) {
-            board->sensor_centre->VL53L1X_GetRangeStatus(&ready_right);
-            board->sensor_centre->VL53L1X_GetDistance(&distance_right);
-        }
-
-        printf("%d\t", distance_centre);
-        printf("%d\t", distance_left);
-        printf("%d\t", distance_right);
     }
-
+    delete board;
     return status;
 }
+
+/*=================================== Main ==================================
+=============================================================================*/
+int main()
+{
+#if USER_BUTTON==PC_13  // we are cross compiling for Nucleo-f401
+    stop_button.rise(&switch_measuring_sensor_irq);
+    stop_button.enable_irq();
+#endif
+    vl53L1X_DevI2C *dev_I2C = new vl53L1X_DevI2C(VL53L1_I2C_SDA, VL53L1_I2C_SCL);
+    range_measure(dev_I2C);  // start continuous measures
+return 0;
+}
+