Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed VL53L1ExpansionBoard
Revision 0:0754d1901845, committed 2020-10-27
- 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
--- /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