ST Expansion SW Team / Mbed 2 deprecated VL53L1_shield_MB2_3sensors_interrupt_ranging

Dependencies:   mbed VL53L1ExpansionBoard

Files at this revision

API Documentation at this revision

Comitter:
charlesmn
Date:
Tue Oct 27 14:15:50 2020 +0000
Commit message:
A sample program that talks to up to 3 VL53L1 ToF sensors on a nucleo shield. The sensors are in ranging mode and and interrupts occur when a measurement is available. MBed V2

Changed in this revision

VL53L1ExpansionBoard.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VL53L1ExpansionBoard.lib	Tue Oct 27 14:15:50 2020 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/ST-Expansion-SW-Team/code/VL53L1ExpansionBoard/#91e6528a6780
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Oct 27 14:15:50 2020 +0000
@@ -0,0 +1,296 @@
+/*
+ *  This VL53L1X Expansion board test application performs range measurements
+ *  using the onboard embedded centre sensor and two satelites, in ranging, interrupt mode.
+ *  Measured ranges are ouput on the Serial Port, running at 9600 baud.
+ *
+ * This is designed to work with MBed V2 , MBed V5 and MBed V6.
+ *
+ *
+ *  The Reset button can be used to restart the program.
+ */
+ 
+#include <stdio.h>
+
+#include "mbed.h"
+#include "XNucleo53L1A1.h"
+#include "ToF_I2C.h"
+#include <time.h>
+
+// i2c comms pins
+#define I2C_SDA   D14 
+#define I2C_SCL   D15 
+
+#define NUM_SENSORS 3
+
+static XNucleo53L1A1 *board=NULL;
+Serial pc(SERIAL_TX, SERIAL_RX); 
+
+static int int_centre_result = 0;
+static int int_left_result = 0;
+static int int_right_result = 0;
+
+
+class WaitForMeasurement {
+public:
+
+
+// this class services the interrupts from the ToF sensors.
+// There is a limited amount you can do in an interrupt routine; printfs,mutexes break them among other things.
+// We keep things simple by only raising a flag so all the real work is done outside the interrupt.
+// This is designed around MBED V2 which doesn't have the RTOS features that would make this work nicely e.g. semaphores/queues.
+WaitForMeasurement(): _interrupt(A1)
+{
+}
+
+
+    // constructor - Sensor is not used and can be removed
+    WaitForMeasurement(PinName pin,VL53L1_DEV Dev) : _interrupt(pin)          // create the InterruptIn on the pin specified to Counter
+    {
+         Devlocal = Dev;
+        _interrupt.rise(callback(this, &WaitForMeasurement::got_interrupt)); // attach increment function of this counter instance
+        
+    }
+    
+    void process_right_interrupt()
+    {
+          printf("processing right interrupt\n");
+    }
+
+  // function is called every time an interupt is seen. A flag is raised which allows the main routine to service the interupt.
+    void got_interrupt()
+    {
+    
+        _count++;
+
+        if (Devlocal->i2c_slave_address == NEW_SENSOR_CENTRE_ADDRESS)
+            int_centre_result = 1;  //flag to main that interrupt happened
+        if (Devlocal->i2c_slave_address == NEW_SENSOR_LEFT_ADDRESS)
+            int_left_result = 1;   //flag to main that interrupt happened
+        if (Devlocal->i2c_slave_address == NEW_SENSOR_RIGHT_ADDRESS)
+        {
+            int_right_result = 1;  //flag to main that interrupt happened
+        }
+    }
+
+    
+    //destructor
+    ~WaitForMeasurement()
+    {
+        printf("destruction \n");
+    }
+
+private:
+    InterruptIn _interrupt;
+    volatile int _count;
+    VL53L1_DEV Devlocal;
+    int status;
+    
+};
+
+
+
+VL53L1_Dev_t                   devCentre;
+VL53L1_Dev_t                   devLeft;
+VL53L1_Dev_t                   devRight;
+VL53L1_DEV                     Dev = &devCentre;
+ 
+/*=================================== Main ==================================
+=============================================================================*/
+int main()
+{   
+    int status;
+    VL53L1X * Sensor;
+    uint16_t wordData;
+    uint8_t ToFSensor = 1; // 0=Left, 1=Center(default), 2=Right
+  
+    
+    WaitForMeasurement* int2;
+    WaitForMeasurement* int1;
+    WaitForMeasurement* int3;
+
+    pc.baud(115200);  // baud rate is important as printf statements take a lot of time
+
+    printf("Hello world!\r\n");
+
+// create the i2c instance
+    ToF_DevI2C *dev_I2C = new ToF_DevI2C(I2C_SDA, I2C_SCL);
+
+ //   printf("I2C device created! %d %d\r\n",dev_I2C,*dev_I2C);
+    
+    /* creates the 53L1A1 expansion board singleton obj */
+    board = XNucleo53L1A1::instance(dev_I2C, A2, D8, D2);
+    printf("board created!\r\n");
+
+    /* init the 53L1A1 expansion board with default values */
+    status = board->init_board();
+    if (status) {
+        printf("Failed to init board!\r\n");
+        return 0;
+    }
+       
+        
+    printf("board initiated! - %d\r\n", status);
+                                                
+        for (ToFSensor=0;ToFSensor< NUM_SENSORS ;ToFSensor++){
+        switch(ToFSensor){
+            case 1:
+                if (board->sensor_centre== NULL ) continue;
+                Dev=&devCentre;
+                Sensor=board->sensor_centre;
+                Dev->i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS;
+                printf("configuring centre channel \n");
+                break;
+            case 0:
+                if (board->sensor_left== NULL ) continue;
+                Dev=&devLeft; 
+                Sensor=board->sensor_left;
+                Dev->i2c_slave_address = NEW_SENSOR_LEFT_ADDRESS;
+                printf("configuring left channel \n");
+                break;
+            case 2:
+                if (board->sensor_right== NULL ) continue;
+                Dev=&devRight;  
+                Sensor=board->sensor_right;
+                Dev->i2c_slave_address = NEW_SENSOR_RIGHT_ADDRESS;
+                printf("configuring right channel \n");
+                break;      
+            default:
+               printf(" error in switch, invalid ToF sensor \n");
+        }
+        
+// configure the sensors
+        Dev->comms_speed_khz = 400;
+
+        Dev->comms_type = 1;
+
+        Sensor->VL53L1_RdWord(Dev, 0x01, &wordData);
+        printf("VL53L1X: %02X   %d\n\r", wordData,Dev->i2c_slave_address);
+/* Device Initialization and setting */  
+        status = Sensor->vl53L1_DataInit();
+        status = Sensor->vl53L1_StaticInit();
+        status = Sensor->vl53L1_SetPresetMode( VL53L1_PRESETMODE_RANGING);
+        status = Sensor->vl53L1_SetDistanceMode( VL53L1_DISTANCEMODE_LONG);
+        status = Sensor->vl53L1_SetMeasurementTimingBudgetMicroSeconds( 50000);
+        status = Sensor->vl53L1_SetInterMeasurementPeriodMilliSeconds( 100);
+        }
+        
+        if (board->sensor_centre!= NULL )
+        {
+            printf("starting interrupt centre\n");
+            Sensor=board->sensor_centre;
+            devCentre.i2c_slave_address = NEW_SENSOR_CENTRE_ADDRESS;
+            int1 =  new WaitForMeasurement(A2,&devCentre);
+            status = Sensor->vl53L1_StartMeasurement();
+        }
+        
+
+        if (board->sensor_left!= NULL )
+        {
+            printf("starting interrupt left\n");
+            Sensor=board->sensor_left;
+            devLeft.i2c_slave_address = NEW_SENSOR_LEFT_ADDRESS;
+            int2 = new WaitForMeasurement(D8,&devLeft);
+            status = Sensor->vl53L1_StartMeasurement();
+        }
+
+        if (board->sensor_right!= NULL )
+        {
+            printf("starting interrupt right\n");
+            Sensor=board->sensor_right;
+            devRight.i2c_slave_address = NEW_SENSOR_RIGHT_ADDRESS;
+            int3 = new WaitForMeasurement(D2,&devRight);
+            status = Sensor->vl53L1_StartMeasurement();
+        }
+    
+       // loop waiting for interrupts to happen. This is signaled by   int_centre_result,int_left_result or int_right_result
+       // being non zero. The are set back to zero when processing is completed
+        while (1)
+        {
+            static VL53L1_RangingMeasurementData_t RangingData;  
+            VL53L1_MultiRangingData_t MultiRangingData;
+             VL53L1_MultiRangingData_t *pMultiRangingData = &MultiRangingData;   
+            
+            wait_ms( 1 * 100);
+            if (int_centre_result != 0)
+            {
+                status = board->sensor_centre->vl53L1_GetMultiRangingData( pMultiRangingData);
+                int no_of_object_found=pMultiRangingData->NumberOfObjectsFound;
+                if ( no_of_object_found < 10 ) 
+                {
+                    for(int j=0;j<no_of_object_found;j++){
+                        if ((pMultiRangingData->RangeData[j].RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID) || 
+                            (pMultiRangingData->RangeData[j].RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL))
+                        {
+                            printf("centre\t status=%d, \t D=%5dmm, \t Signal=%2.2f Mcps, \t Ambient=%2.2f Mcps \n",
+                            pMultiRangingData->RangeData[j].RangeStatus,
+                            pMultiRangingData->RangeData[j].RangeMilliMeter,
+                            pMultiRangingData->RangeData[j].SignalRateRtnMegaCps/65536.0,
+                            pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps/65536.0);
+                        }
+                    }
+                }
+                int_centre_result = 0;
+                status = board->sensor_centre->vl53L1_ClearInterruptAndStartMeasurement();
+            }
+
+
+            if (int_left_result != 0)
+            {
+                status = board->sensor_left->vl53L1_GetMultiRangingData( pMultiRangingData);
+                if ( status == 0)
+                {
+                    int no_of_object_found=pMultiRangingData->NumberOfObjectsFound;
+                    if ( no_of_object_found < 10 ) 
+                    {
+                        for(int j=0;j<no_of_object_found;j++){
+                                if ((pMultiRangingData->RangeData[j].RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID) || 
+                                    (pMultiRangingData->RangeData[j].RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL))
+                                {
+
+                                    printf("left  \t status=%d, \t D=%5dmm, \t Signal=%2.2f Mcps, \t Ambient=%2.2f Mcps \n",
+                                    pMultiRangingData->RangeData[j].RangeStatus,
+                                    pMultiRangingData->RangeData[j].RangeMilliMeter,
+                                    pMultiRangingData->RangeData[j].SignalRateRtnMegaCps/65536.0,
+                                    pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps/65536.0);
+                                }
+                        }
+                    }
+                }
+ 
+                int_left_result = 0;
+                status = board->sensor_left->vl53L1_ClearInterruptAndStartMeasurement();
+
+            }
+            
+            
+            if (int_right_result != 0)
+            {
+                status = board->sensor_right->vl53L1_GetMultiRangingData( pMultiRangingData);
+                if ( status == 0)
+                {
+                    // if valid result print it
+                    int no_of_object_found=pMultiRangingData->NumberOfObjectsFound;
+                    if ( no_of_object_found < 10 ) 
+                    {
+                        for(int j=0;j<no_of_object_found;j++){
+                                if (pMultiRangingData->RangeData[j].RangeStatus == 0) 
+                                {
+                                    printf("right \t status=%d, \t D=%5dmm, \t Signal=%2.2f Mcps, \t Ambient=%2.2f Mcps \n",
+                                    pMultiRangingData->RangeData[j].RangeStatus,
+                                    pMultiRangingData->RangeData[j].RangeMilliMeter,
+                                    pMultiRangingData->RangeData[j].SignalRateRtnMegaCps/65536.0,
+                                    pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps/65536.0);
+                                }
+                        }
+                    }
+                }
+                // clear interrupt flag
+                int_right_result = 0;
+                // clear theinterrupt and wait for another result
+                status = board->sensor_right->vl53L1_ClearInterruptAndStartMeasurement();
+
+            }
+        }
+        printf("terminated");
+    }
+  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Oct 27 14:15:50 2020 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file