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

* 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. *

Files at this revision

API Documentation at this revision

Comitter:
johnAlexander
Date:
Tue Jun 20 08:14:49 2017 +0000
Parent:
3:12cb106044f9
Child:
5:906aa7aede10
Commit message:
Refactored example code and updated comment section to mention expansion board hardware configuration needs.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Thu Jun 15 13:52:54 2017 +0000
+++ b/main.cpp	Tue Jun 20 08:14:49 2017 +0000
@@ -9,112 +9,136 @@
  * 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.
+ * The application supports the centre, on-board, sensor and up two satellite boards.
  *
- * *** 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 measured range data is displayed on the on-board 4-digit LED display.
  *
  * 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. 
+ *
+ * *** 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.
+ *            U11 and U18 must be made/ON to allow interrupts to be received from the
+ *            INT_L & INT_R positions; or
+ *            U10 and U15 must be made/ON to allow interrupts to be received from the
+ *            Alternate INT_L & INT_R positions. 
+ *            The X_NUCLEO_53L0A1 firmware library defaults to use the INT_L/INT_R 
+ *            positions. 
+ *            INT_L is available on expansion board Arduino Connector CN5, pin 1 as D8.
+ *            Alternate INT_L is on CN5 Connector pin 2 as D9.
+ *            INT_R is available on expansion board Arduino Connector CN9, pin 3 as D2.
+ *            Alternate INT_R is on CN9 Connector pin 5 as D4. 
+ *            The pinouts are shown here : https://developer.mbed.org/components/X-NUCLEO-53L0A1/
+ *   
  */
 
-
 #define VL53L0_I2C_SDA   D14 
 #define VL53L0_I2C_SCL   D15 
 
-#define CENTER_BIT  0
-#define LEFT_BIT    1
-#define RIGHT_BIT   2
-
+#if USER_BUTTON==PC_13  // we are cross compiling for Nucleo-64s
+   InterruptIn stop_button (USER_BUTTON);
+#endif   
 
 static X_NUCLEO_53L0A1 *board=NULL;
 VL53L0X_RangingMeasurementData_t data_sensor;
 OperatingMode operating_mode;
-    
+
+/* current displayed sensor change IRQ */
+volatile bool switchChanged = false;
+
 /* interrupt requests */
-volatile int upadtedSensors = 0;
+volatile bool centerSensor = false;
+volatile bool leftSensor = false;
+volatile bool rightSensor = false; 
 
 /* Current sensor number*/
 volatile int currentSensor = 0;
 /* Installed sensors count */ 
 int sensorCnt = 0; 
 
-struct Sensor
-{
-    char prefix;
-    int sensorBit;
-    VL53L0X *sensorPtr;
-} installedSensors[3];
-
+/* installed sensors prefixes */
+char installedSensors[3];
 
 /* ISR callback function of the sensor_centre */
 void SensorCenterIRQ(void)
 {
-   upadtedSensors |= (1 << CENTER_BIT); 
+   centerSensor = true;
    board->sensor_centre->DisableInterruptMeasureDetectionIRQ();
 }   
 
 void SensorLeftIRQ(void)
 {
-   upadtedSensors |= (1 << LEFT_BIT); 
+   leftSensor = true;
    board->sensor_left->DisableInterruptMeasureDetectionIRQ();
 } 
 
 void SensorRightIRQ(void)
-{      
-   upadtedSensors |= (1 << RIGHT_BIT); 
+{    
+   rightSensor = true;  
    board->sensor_right->DisableInterruptMeasureDetectionIRQ();
 } 
 
 /* ISR callback function of the user blue button to switch measuring sensor. */
 void SwitchMeasuringSensorIRQ(void)
 {
-    ++currentSensor;
-    if (currentSensor == sensorCnt)
-        currentSensor = 0;
-    printf("Sensor changed to %c\r\n",installedSensors[currentSensor].prefix);
+    stop_button.disable_irq();
+    switchChanged = true;
 }
 
+
 /* On board 4 digit local display refresh */
-void DisplayRefresh(OperatingMode op_mode)
-{   
-    int status;
-    char str[4];
-    Sensor *current;
-    for (int t=0; t < sensorCnt; t++)
+void RefreshDisplay(const VL53L0X_RangingMeasurementData_t &data, char prefix)
+{
+    static char str[5];
+    if (data_sensor.RangeStatus == 0) // we have a valid range.
+    {
+        sprintf(str, "%c%3d", prefix ,data.RangeMilliMeter);
+        board->display->DisplayString(str);
+    }
+    else
     {
-        current = &installedSensors[t];
-        if (upadtedSensors & current->sensorBit)
+        sprintf(str, "%c%s", prefix, "---");
+        board->display->DisplayString(str);
+    }
+}
+
+inline void MeasureSensors(OperatingMode op_mode)
+{
+    bool current = false;
+    if (centerSensor)
+    {
+        centerSensor = false;
+        board->sensor_centre->HandleIRQ(op_mode, &data_sensor);
+        current = (currentSensor == 0);
+        if (current)
         {
-            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, "---");
-                    }   
-                }       
-            }
+            RefreshDisplay(data_sensor, 'C');
         }
     }
-    board->display->DisplayString(str);
+    if (leftSensor)
+    {
+        leftSensor = false;
+        board->sensor_left->HandleIRQ(op_mode, &data_sensor);
+        current = (installedSensors[currentSensor] == 'L');
+        if (current)
+        {
+            RefreshDisplay(data_sensor, 'L');
+        }
+    }
+    if (rightSensor)
+    {
+        rightSensor = false;
+        board->sensor_right->HandleIRQ(op_mode, &data_sensor);
+        current = (installedSensors[currentSensor] == 'R');        
+        if (current)
+        {
+            RefreshDisplay(data_sensor, 'R');
+        }
+    }
 }
 
 int InitSensorsArray()
@@ -124,9 +148,7 @@
     /* 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; 
+        installedSensors[sensorCnt] = 'C';
         status=board->sensor_centre->StopMeasurement(operating_mode);
         status=board->sensor_centre->StartMeasurement(operating_mode, &SensorCenterIRQ); 
         ++sensorCnt;
@@ -134,9 +156,7 @@
     /* start the measure on the left sensor */
     if (NULL != board->sensor_left)
     {
-        installedSensors[sensorCnt].prefix = 'L';
-        installedSensors[sensorCnt].sensorBit |= (1 << LEFT_BIT);
-        installedSensors[sensorCnt].sensorPtr = board->sensor_left; 
+        installedSensors[sensorCnt] = 'L';
         status=board->sensor_left->StopMeasurement(operating_mode);
         status=board->sensor_left->StartMeasurement(operating_mode, &SensorLeftIRQ);
         ++sensorCnt;
@@ -144,9 +164,7 @@
     /* 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; 
+        installedSensors[sensorCnt] = 'R';
         status=board->sensor_right->StopMeasurement(operating_mode);
         status=board->sensor_right->StartMeasurement(operating_mode, &SensorRightIRQ);
         ++sensorCnt;
@@ -155,11 +173,13 @@
     return status;
 }
 
+
 void RangeMeasure(DevI2C *device_i2c) {
    int status;
 
    /* creates the 53L0A1 expansion board singleton obj */
    board=X_NUCLEO_53L0A1::Instance(device_i2c, A2, D8, D2);
+   //board=X_NUCLEO_53L0A1::Instance(device_i2c, A2, D9, D4); // Alternate INT_L/INT_R settings.
     
    board->display->DisplayString("53L0");
    
@@ -182,7 +202,17 @@
      printf ("\r\nEntering loop mode\r\n");
      while (true)
      { 
-        DisplayRefresh(operating_mode);
+        MeasureSensors(operating_mode);
+        if (switchChanged)
+        {
+            ++currentSensor;
+            if (currentSensor == sensorCnt)
+                currentSensor = 0;
+            
+            printf("Sensor changed to %c\r\n",installedSensors[currentSensor]);   
+            switchChanged = false;
+            stop_button.enable_irq(); 
+        }
      }
    }
    delete board;        
@@ -194,11 +224,12 @@
 int main()
 {   
 #if USER_BUTTON==PC_13  // we are cross compiling for Nucleo-f401 
-   InterruptIn stop_button (USER_BUTTON);
    stop_button.rise (&SwitchMeasuringSensorIRQ);  
+   stop_button.enable_irq();
 #endif   
    DevI2C *device_i2c =new DevI2C(VL53L0_I2C_SDA, VL53L0_I2C_SCL);        
    RangeMeasure(device_i2c);  // start continuous measures
 }
 
 
+