Sample application using interrupts, and range_continuous_interrupts mode, to receive range data from the on-board and satellite sensors. Results are displayed on the on-board, 4 digit display and on the COM port.

Dependencies:   mbed X_NUCLEO_53L0A1

Fork of Display_53L0A1_Interrupts by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "XNucleo53L0A1.h"
00003 #include <string.h>
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include <assert.h>
00007 
00008 /*
00009  * This VL53L0X Expansion board sample application performs range measurements using
00010  * range_continuous_interrupt mode to generate a hardware interrupt each time a new
00011  * measurement is ready to be read.
00012  * The application supports the centre, on-board, sensor and up two satellite boards.
00013  *
00014  * The measured range data is displayed on the on-board 4-digit LED display.
00015  *
00016  * The User Blue button switches between the currently selected sensor to display range
00017  * results from.
00018  *
00019  * The Black Reset button is used to restart the program.
00020  *
00021  * *** NOTE : By default hardlinks U10, U11, U15 & U18, on the underside of
00022  *            the X-NUCELO-53L0A1 expansion board are not made/OFF.
00023  *            These links must be made to allow interrupts from the Satellite boards
00024  *            to be received.
00025  *            U11 and U18 must be made/ON to allow interrupts to be received from the
00026  *            INT_L & INT_R positions; or
00027  *            U10 and U15 must be made/ON to allow interrupts to be received from the
00028  *            Alternate INT_L & INT_R positions.
00029  *            The X_NUCLEO_53L0A1 firmware library defaults to use the INT_L/INT_R
00030  *            positions.
00031  *            INT_L is available on expansion board Arduino Connector CN5, pin 1 as D8.
00032  *            Alternate INT_L is on CN5 Connector pin 2 as D9.
00033  *            INT_R is available on expansion board Arduino Connector CN9, pin 3 as D2.
00034  *            Alternate INT_R is on CN9 Connector pin 5 as D4.
00035  *            The pinouts are shown here : https://developer.mbed.org/components/X-NUCLEO-53L0A1/
00036  *
00037  */
00038 
00039 #define VL53L0_I2C_SDA   D14
00040 #define VL53L0_I2C_SCL   D15
00041 
00042 #if USER_BUTTON==PC_13  // we are cross compiling for Nucleo-64s
00043 InterruptIn stop_button(USER_BUTTON);
00044 #endif
00045 
00046 static XNucleo53L0A1 *board = NULL;
00047 VL53L0X_RangingMeasurementData_t data_sensor;
00048 OperatingMode operating_mode;
00049 
00050 /* current displayed sensor change IRQ */
00051 volatile bool switchChanged = false;
00052 
00053 /* interrupt requests */
00054 volatile bool centerSensor = false;
00055 volatile bool leftSensor = false;
00056 volatile bool rightSensor = false;
00057 
00058 /* Current sensor number*/
00059 volatile int currentSensor = 0;
00060 /* Installed sensors count */
00061 int sensorCnt = 0;
00062 
00063 /* installed sensors prefixes */
00064 char installedSensors[3];
00065 
00066 /* ISR callback function of the sensor_centre */
00067 void sensor_centre_irq(void)
00068 {
00069     centerSensor = true;
00070     board->sensor_centre->disable_interrupt_measure_detection_irq();
00071 }
00072 
00073 void sensor_left_irq(void)
00074 {
00075     leftSensor = true;
00076     board->sensor_left->disable_interrupt_measure_detection_irq();
00077 }
00078 
00079 void sensor_right_irq(void)
00080 {
00081     rightSensor = true;
00082     board->sensor_right->disable_interrupt_measure_detection_irq();
00083 }
00084 
00085 /* ISR callback function of the user blue button to switch measuring sensor. */
00086 void switch_measuring_sensor_irq(void)
00087 {
00088     stop_button.disable_irq();
00089     switchChanged = true;
00090 }
00091 
00092 
00093 /* On board 4 digit local display refresh */
00094 void refresh_display(const VL53L0X_RangingMeasurementData_t &data, char prefix)
00095 {
00096     static char str[5];
00097     if (data_sensor.RangeStatus == 0) { // we have a valid range.
00098         sprintf(str, "%c%3d", prefix, data.RangeMilliMeter);
00099         board->display->display_string(str);
00100     } else {
00101         sprintf(str, "%c%s", prefix, "---");
00102         board->display->display_string(str);
00103     }
00104 }
00105 
00106 inline void measure_sensors(OperatingMode op_mode)
00107 {
00108     bool current = false;
00109     if (centerSensor) {
00110         centerSensor = false;
00111         board->sensor_centre->handle_irq(op_mode, &data_sensor);
00112         current = (currentSensor == 0);
00113         if (current) {
00114             refresh_display(data_sensor, 'C');
00115         }
00116     }
00117     if (leftSensor) {
00118         leftSensor = false;
00119         board->sensor_left->handle_irq(op_mode, &data_sensor);
00120         current = (installedSensors[currentSensor] == 'L');
00121         if (current) {
00122             refresh_display(data_sensor, 'L');
00123         }
00124     }
00125     if (rightSensor) {
00126         rightSensor = false;
00127         board->sensor_right->handle_irq(op_mode, &data_sensor);
00128         current = (installedSensors[currentSensor] == 'R');
00129         if (current) {
00130             refresh_display(data_sensor, 'R');
00131         }
00132     }
00133 }
00134 
00135 int init_sensors_array()
00136 {
00137     int status = 1;
00138     sensorCnt = 0;
00139     /* start the measure on the center sensor */
00140     if (NULL != board->sensor_centre) {
00141         installedSensors[sensorCnt] = 'C';
00142         status = board->sensor_centre->stop_measurement(operating_mode);
00143         status = board->sensor_centre->start_measurement(operating_mode, &sensor_centre_irq);
00144         ++sensorCnt;
00145     }
00146     /* start the measure on the left sensor */
00147     if (NULL != board->sensor_left) {
00148         installedSensors[sensorCnt] = 'L';
00149         status = board->sensor_left->stop_measurement(operating_mode);
00150         status = board->sensor_left->start_measurement(operating_mode, &sensor_left_irq);
00151         ++sensorCnt;
00152     }
00153     /* start the measure on the right sensor */
00154     if (NULL != board->sensor_right) {
00155         installedSensors[sensorCnt] = 'R';
00156         status = board->sensor_right->stop_measurement(operating_mode);
00157         status = board->sensor_right->start_measurement(operating_mode, &sensor_right_irq);
00158         ++sensorCnt;
00159     }
00160     currentSensor = 0;
00161     return status;
00162 }
00163 
00164 
00165 void range_measure(DevI2C *device_i2c)
00166 {
00167     int status;
00168 
00169     /* creates the 53L0A1 expansion board singleton obj */
00170     board = XNucleo53L0A1::instance(device_i2c, A2, D8, D2);
00171     //board=XNucleo53L0A1::instance(device_i2c, A2, D9, D4); // Alternate INT_L/INT_R settings.
00172 
00173     board->display->display_string("53L0");
00174 
00175     operating_mode = range_continuous_interrupt;
00176 
00177     /* init the 53L0A1 expansion board with default values */
00178     status = board->init_board();
00179 
00180     if (status) {
00181         printf("Failed to init board!\n\r");
00182     } else {
00183         status = init_sensors_array();
00184     }
00185 
00186     if (!status) {
00187         printf("\r\nEntering loop mode\r\n");
00188         while (true) {
00189             measure_sensors(operating_mode);
00190             if (switchChanged) {
00191                 ++currentSensor;
00192                 if (currentSensor == sensorCnt)
00193                     currentSensor = 0;
00194 
00195                 printf("Sensor changed to %c\r\n", installedSensors[currentSensor]);
00196                 switchChanged = false;
00197                 stop_button.enable_irq();
00198             }
00199         }
00200     }
00201     delete board;
00202 }
00203 
00204 /*=================================== Main ==================================
00205  Press the blue user button to switch the displayed sensor.
00206 =============================================================================*/
00207 int main()
00208 {
00209 #if USER_BUTTON==PC_13  // we are cross compiling for Nucleo-f401 
00210     stop_button.rise(&switch_measuring_sensor_irq);
00211     stop_button.enable_irq();
00212 #endif
00213     DevI2C *device_i2c = new DevI2C(VL53L0_I2C_SDA, VL53L0_I2C_SCL);
00214     range_measure(device_i2c);  // start continuous measures
00215 }
00216 
00217 
00218