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
* NOTE : Hard-links U11 and U18, on the underside of the X-NUCELO-53L0A1 expansion board, must be made/ON to allow interrupts to be received from the satellite boards, on INT_L and INT_R, or U10 and U15 to receive interrupts from the alternate locations. *
Diff: main.cpp
- Revision:
- 3:12cb106044f9
- Parent:
- 2:bdf097d93eca
- Child:
- 4:44629a30d6f4
--- a/main.cpp Wed Jun 14 14:42:41 2017 +0000 +++ b/main.cpp Thu Jun 15 13:52:54 2017 +0000 @@ -5,55 +5,154 @@ #include <stdio.h> #include <assert.h> -/* This VL53L0X Expansion board test application performs a range measurement in interrupt mode - on the center embedded sensor. - The measured data is displayed on the on-board 4-digit display, and sent to com port +/* + * This VL53L0X Expansion board sample application performs range measurements using + * range_continuous_interrupt mode to generate a hardware interrupt each time a new + * measurement is ready to be read. + * The application supports the centre, on-board, sensor and up two satellites. + * + * *** NOTE : Hard-links U11 and U18, on the underside of the X-NUCELO-53L0A1 + * expansion board must be made/ON to allow interrupts to be received + * from the satellite boards. *** + * + * The measured range data is displayed on the on-board 4-digit LED display, and sent + * to the COM port. + * + * The User Blue button switches between the currently selected sensor to display range + * results from. + * + * The Black Reset button is used to restart the program. + */ - User Blue button stops the current measurement and the entire program, releasing all resources. - Reset button is used to restart the program. - - Interrupt mode requires callback function which handles IRQ from given sensor. -*/ #define VL53L0_I2C_SDA D14 #define VL53L0_I2C_SCL D15 +#define CENTER_BIT 0 +#define LEFT_BIT 1 +#define RIGHT_BIT 2 + + static X_NUCLEO_53L0A1 *board=NULL; VL53L0X_RangingMeasurementData_t data_sensor; OperatingMode operating_mode; -/* flags that handle interrupt request for sensor and user blue button*/ -volatile bool int_sensor_centre=false; -volatile bool int_measuring_stop = false; +/* interrupt requests */ +volatile int upadtedSensors = 0; + +/* Current sensor number*/ +volatile int currentSensor = 0; +/* Installed sensors count */ +int sensorCnt = 0; + +struct Sensor +{ + char prefix; + int sensorBit; + VL53L0X *sensorPtr; +} installedSensors[3]; -/* ISR callback function of the center sensor */ +/* ISR callback function of the sensor_centre */ void SensorCenterIRQ(void) { - int_sensor_centre=true; + upadtedSensors |= (1 << CENTER_BIT); board->sensor_centre->DisableInterruptMeasureDetectionIRQ(); } +void SensorLeftIRQ(void) +{ + upadtedSensors |= (1 << LEFT_BIT); + board->sensor_left->DisableInterruptMeasureDetectionIRQ(); +} + +void SensorRightIRQ(void) +{ + upadtedSensors |= (1 << RIGHT_BIT); + board->sensor_right->DisableInterruptMeasureDetectionIRQ(); +} + /* ISR callback function of the user blue button to switch measuring sensor. */ -void MeasuringStopIRQ(void) +void SwitchMeasuringSensorIRQ(void) { - int_measuring_stop = true; + ++currentSensor; + if (currentSensor == sensorCnt) + currentSensor = 0; + printf("Sensor changed to %c\r\n",installedSensors[currentSensor].prefix); } /* On board 4 digit local display refresh */ -void DisplayRefresh(const VL53L0X_RangingMeasurementData_t &data) +void DisplayRefresh(OperatingMode op_mode) { + int status; char str[4]; - if (data.RangeStatus == 0) // we have a valid range. + Sensor *current; + for (int t=0; t < sensorCnt; t++) { - printf("%4d; ", data.RangeMilliMeter); - sprintf(str,"%4d", data.RangeMilliMeter); + current = &installedSensors[t]; + if (upadtedSensors & current->sensorBit) + { + status = current->sensorPtr->HandleIRQ(op_mode, &data_sensor); + upadtedSensors &= ~(current->sensorBit) ; + if (!status) + { + if (data_sensor.RangeStatus == 0) // we have a valid range. + { + printf("%c %4d; ", current->prefix,data_sensor.RangeMilliMeter); + if (currentSensor == t) + { + sprintf(str,"%c%3d", current->prefix ,data_sensor.RangeMilliMeter); + } + } + else + { + if (currentSensor == t) + { + sprintf(str,"%c%s", current->prefix, "---"); + } + } + } + } } - else + board->display->DisplayString(str); +} + +int InitSensorsArray() +{ + int status = 1; + sensorCnt = 0; + /* start the measure on the center sensor */ + if (NULL != board->sensor_centre) + { + installedSensors[sensorCnt].prefix = 'C'; + installedSensors[sensorCnt].sensorBit |= (1 << CENTER_BIT); + installedSensors[sensorCnt].sensorPtr = board->sensor_centre; + status=board->sensor_centre->StopMeasurement(operating_mode); + status=board->sensor_centre->StartMeasurement(operating_mode, &SensorCenterIRQ); + ++sensorCnt; + } + /* start the measure on the left sensor */ + if (NULL != board->sensor_left) { - sprintf(str,"%s", "----"); - } - board->display->DisplayString(str); + installedSensors[sensorCnt].prefix = 'L'; + installedSensors[sensorCnt].sensorBit |= (1 << LEFT_BIT); + installedSensors[sensorCnt].sensorPtr = board->sensor_left; + status=board->sensor_left->StopMeasurement(operating_mode); + status=board->sensor_left->StartMeasurement(operating_mode, &SensorLeftIRQ); + ++sensorCnt; + } + /* start the measure on the right sensor */ + if (NULL != board->sensor_right) + { + installedSensors[sensorCnt].prefix = 'R'; + installedSensors[sensorCnt].sensorBit |= (1 << RIGHT_BIT); + installedSensors[sensorCnt].sensorPtr = board->sensor_right; + status=board->sensor_right->StopMeasurement(operating_mode); + status=board->sensor_right->StartMeasurement(operating_mode, &SensorRightIRQ); + ++sensorCnt; + } + currentSensor = 0; + return status; } void RangeMeasure(DevI2C *device_i2c) { @@ -64,51 +163,39 @@ board->display->DisplayString("53L0"); - /* setting operating mode to continuous interrupt */ operating_mode=range_continuous_interrupt; /* init the 53L0A1 expansion board with default values */ status=board->InitBoard(); + if(status) { printf("Failed to init board!\n\r"); - return; } - //Stop any measurement before setting sensor - status=board->sensor_centre->StopMeasurement(operating_mode); - status=board->sensor_centre->StartMeasurement(operating_mode, &SensorCenterIRQ); + else + { + status = InitSensorsArray(); + } if(!status) { - printf ("Entering loop mode\r\n"); + printf ("\r\nEntering loop mode\r\n"); while (true) { - if (int_sensor_centre) - { - int_sensor_centre = false; - status = board->sensor_centre->HandleIRQ(operating_mode, &data_sensor); - DisplayRefresh(data_sensor); - } - - if (int_measuring_stop) - { - printf("\r\nEnding loop mode \r\n"); - break; - } + DisplayRefresh(operating_mode); } } - board->display->DisplayString("BYE"); delete board; } /*=================================== Main ================================== - Press the blue user button to stop the measurements in progress + Press the blue user button to switch the displayed sensor. =============================================================================*/ int main() { #if USER_BUTTON==PC_13 // we are cross compiling for Nucleo-f401 InterruptIn stop_button (USER_BUTTON); - stop_button.rise (&MeasuringStopIRQ); + stop_button.rise (&SwitchMeasuringSensorIRQ); #endif DevI2C *device_i2c =new DevI2C(VL53L0_I2C_SDA, VL53L0_I2C_SCL); RangeMeasure(device_i2c); // start continuous measures