Library to handle the X-NUCLEO-6180XA1 Proximity and ambient light sensor expansion board based on VL6180X.

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   HelloWorld_6180XA1 SunTracker_BLE Servo_6180XA1 BLE_HR_Light ... more

Fork of X_NUCLEO_6180XA1 by ST Expansion SW Team

X-NUCLEO-6180XA1 Proximity and Ambient Light Sensor Expansion Board Firmware Package

Introduction

This firmware package includes Components Device Drivers and Board Support Package for STMicroelectronics' X-NUCLEO-6180XA1 Proximity and ambient light sensor expansion board based on VL6180X.

Firmware Library

Class X_NUCLEO_6180XA1 is intended to represent the Proximity and ambient light sensor expansion board with the same name.

The expansion board is providing the support of the following components:

  1. on-board VL6180X proximity and ambient light sensor,
  2. up to three additional VL6180X Satellites,
  3. on-board 4-digit display

It is intentionally implemented as a singleton because only one X-NUCLEO-VL6180XA1 at a time might be deployed in a HW component stack. In order to get the singleton instance you have to call class method `Instance()`, e.g.:

// Sensors expansion board singleton instance
static X_NUCLEO_6180XA1 *6180X_expansion_board = X_NUCLEO_6180XA1::Instance();

Arduino Connector Compatibility Warning

Using the X-NUCLEO-6180XA1 expansion board with the NUCLEO-F429ZI requires adopting the following patch:

  • to remove R46 resistor connected to A3 pin;
  • to solder R47 resistor connected to A5 pin.

Alternatively, you can route the Nucleo board’s A5 pin directly to the expansion board’s A3 pin with a wire. In case you patch your expansion board or route the pin, the interrupt signal for the front sensor will be driven on A5 pin rather than on A3 pin.


Example Applications

Files at this revision

API Documentation at this revision

Comitter:
gallonm
Date:
Mon Nov 02 14:02:53 2015 +0100
Parent:
23:dfb5ccc7b780
Child:
25:126b760a3f55
Commit message:
Modified file cfg.h by introducing #define EXTENDED_RANGE_50CM.
Settled StartMeasurement by removing MeasureData_t from parameters.
Settled range single shot measure and als single shot measure.
Settled GetMeasurement by introducing range_single_shot case and als_single_shot case.
Settled VL6180x_AlsSetThresholds by introducing the computation in order to pass
the arguments in lux and write the same arguments in raw device value into registers.

Changed in this revision

Components/VL6180X/vl6180x_cfg.h Show annotated file Show diff for this revision Revisions of this file
Components/VL6180X/vl6180x_class.cpp Show annotated file Show diff for this revision Revisions of this file
Components/VL6180X/vl6180x_class.h Show annotated file Show diff for this revision Revisions of this file
--- a/Components/VL6180X/vl6180x_cfg.h	Fri Oct 30 11:35:36 2015 +0100
+++ b/Components/VL6180X/vl6180x_cfg.h	Mon Nov 02 14:02:53 2015 +0100
@@ -58,7 +58,7 @@
  * @li 3 : Fixed scaling by 3
  * @li  -1 -2 -3 : Run time programmable through @a VL6180x_UpscaleSetScaling(). Default scaling factore is -VL6180x_UPSCALE_SUPPORT \n
  */
-#define VL6180x_UPSCALE_SUPPORT -1
+//#define VL6180x_UPSCALE_SUPPORT -1
 
 /**
  * @def VL6180x_ALS_SUPPORT
@@ -106,8 +106,17 @@
  * Device that do not formally support extended ranging should only be used with a scaling factor of 1.
  * Correct operation with scaling factor other than 1 (>200mm ) is not granted by ST.
  */
-#define VL6180x_EXTENDED_RANGE 0
+//#define VL6180x_EXTENDED_RANGE 0
+
+#define EXTENDED_RANGE_50CM     0
 
+#if EXTENDED_RANGE_50CM
+#define VL6180x_UPSCALE_SUPPORT -3
+#define VL6180x_EXTENDED_RANGE  1
+#else
+#define VL6180x_UPSCALE_SUPPORT -1
+#define VL6180x_EXTENDED_RANGE  0
+#endif
 
 #if (VL6180x_EXTENDED_RANGE) && (VL6180x_ALS_SUPPORT)
 #warning "Als support should be OFF for extended range"
--- a/Components/VL6180X/vl6180x_class.cpp	Fri Oct 30 11:35:36 2015 +0100
+++ b/Components/VL6180X/vl6180x_class.cpp	Mon Nov 02 14:02:53 2015 +0100
@@ -528,7 +528,7 @@
         if( status ) break;
         status = VL6180x_AlsSetAnalogueGain(dev,  0);
         if( status ) break;
-        status = VL6180x_AlsSetThresholds(dev, 0, 0xFF);
+        status = VL6180x_AlsSetThresholds(dev, 0, 0xFFFF);
         if( status ) break;
         /* set Als InterruptMode to new sample */
         status=VL6180x_AlsConfigInterrupt(dev, CONFIG_GPIO_INTERRUPT_DISABLED);
@@ -725,15 +725,27 @@
  
  
  
-int VL6180X::VL6180x_AlsSetThresholds(VL6180xDev_t dev, uint8_t low, uint8_t high) { 
+int VL6180X::VL6180x_AlsSetThresholds(VL6180xDev_t dev, uint16_t low, uint16_t high) { 
     int status;
+    uint32_t AlsAnGain, IntPeriod, AlsScaler, GainFix, RawAlsHigh, RawAlsLow;
+    const uint32_t LuxResxIntIme =(uint32_t)(0.56f* DEF_INT_PEFRIOD *(1<<LUXRES_FIX_PREC));
  
     LOG_FUNCTION_START("%d %d", (int )low, (int)high);
-    /*FIXME arguments have to be uint16_t (see SYSALS_THRESH_LOW and SYSALS_THRESH_HIGH registers)
-      Furthermore threshold values are not lux! You need to invert the computation made in VL6180x_AlsGetLux() */
-    status = VL6180x_WrByte(dev, SYSALS_THRESH_LOW, low); 
+    AlsAnGain=VL6180xDevDataGet(dev, AlsGainCode);
+    IntPeriod=VL6180xDevDataGet(dev, IntegrationPeriod);
+    AlsScaler=VL6180xDevDataGet(dev, AlsScaler);
+    GainFix=AlsGainLookUp[AlsAnGain];
+    IntPeriod++;
+    RawAlsLow=low*AlsScaler*GainFix;
+    RawAlsLow=RawAlsLow*IntPeriod;
+    RawAlsLow=RawAlsLow/LuxResxIntIme;
+    
+    RawAlsHigh=high*(AlsScaler*GainFix);
+    RawAlsHigh=RawAlsHigh*IntPeriod;
+    RawAlsHigh=RawAlsHigh/LuxResxIntIme;
+    status = VL6180x_WrByte(dev, SYSALS_THRESH_LOW, (uint16_t)RawAlsLow); 
     if(!status ){
-        status = VL6180x_WrByte(dev, SYSALS_THRESH_HIGH, high);
+        status = VL6180x_WrByte(dev, SYSALS_THRESH_HIGH, (uint16_t)RawAlsHigh);
     }
  
     LOG_FUNCTION_END(status) ;
@@ -2724,7 +2736,7 @@
 }
  
  
-int VL6180X::StartMeasurement(OperatingMode operating_mode, void (*fptr)(void), MeasureData_t *Data, uint16_t low, uint16_t high) 
+int VL6180X::StartMeasurement(OperatingMode operating_mode, void (*fptr)(void), uint16_t low, uint16_t high)
 {
    int status, r_status, l_status;
     
@@ -2734,7 +2746,7 @@
         r_status=VL6180x_RangeConfigInterrupt(Device, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY);
         l_status=VL6180x_AlsConfigInterrupt(Device, CONFIG_GPIO_INTERRUPT_DISABLED);
         if((!r_status)&&(!l_status))
-           return RangeMeasPollSingleShot(Data);
+           return RangeMeasPollSingleShot();
         else
            return (r_status|l_status);
         
@@ -2742,7 +2754,7 @@
         r_status=VL6180x_AlsConfigInterrupt(Device, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY);
         l_status=VL6180x_RangeConfigInterrupt(Device, CONFIG_GPIO_INTERRUPT_DISABLED);
         if((!r_status)&&(!l_status))
-           return AlsMeasPollSingleShot(Data);
+           return AlsMeasPollSingleShot();
         else
            return (r_status|l_status);
             
@@ -2984,39 +2996,43 @@
 }
  
  
-int VL6180X::RangeMeasPollSingleShot(MeasureData_t *Data)
+int VL6180X::RangeMeasPollSingleShot()
 {
-   VL6180x_RangeData_t RangeData;
    int status;
-    
-   status=RangePollMeasurement(&RangeData);
-   if(!status)
+            
+   status=VL6180x_RangeClearInterrupt(Device);
+   if(status)
    {
-      status=GetRangeError(Data, RangeData);
-      if(!status)
-         Data->range_mm=RangeData.range_mm;
-      else
-         Data->range_mm=0xFFFFFFFF;
+      VL6180x_ErrLog("VL6180x_RangeClearInterrupt fail");
+      return status;
    }
-   return status;  
+   status=VL6180x_ClearErrorInterrupt(Device);
+   if(status)
+   {
+      VL6180x_ErrLog("VL6180x_ClearErrorInterrupt fail");
+      return status;
+   }
+   return RangeStartSingleShot(); 
 }   
  
  
-int VL6180X::AlsMeasPollSingleShot(MeasureData_t *Data)
+int VL6180X::AlsMeasPollSingleShot()
 {
-   VL6180x_AlsData_t AlsData;
-   int status;
-    
-   status=AlsPollMeasurement(&AlsData);
-   if(!status)
+   int status;            
+     
+   status=VL6180x_AlsClearInterrupt(Device);
+   if(status)
    {
-      status=GetAlsError(Data, AlsData);
-      if(!status)
-         Data->lux=AlsData.lux;
-      else
-         Data->lux=0xFFFFFFFF;
+      VL6180x_ErrLog("VL6180x_AlsClearInterrupt fail");
+      return status;
    }
-   return status; 
+   status=VL6180x_ClearErrorInterrupt(Device);
+   if(status)
+   {
+      VL6180x_ErrLog("VL6180x_ClearErrorInterrupt fail");
+      return status;
+   }
+   return AlsStartSingleShot();
 }
  
  
@@ -3258,6 +3274,7 @@
 {
    switch(operating_mode)
    {
+      case(range_single_shot_polling):
       case(range_continuous_polling):
       case(range_continuous_interrupt):
       case(range_continuous_polling_low_threshold):
@@ -3268,6 +3285,7 @@
       case(range_continuous_interrupt_out_of_window):
         return GetRangeMeas(operating_mode, Data);
          
+      case(als_single_shot_polling):
       case(als_continuous_polling):
       case(als_continuous_interrupt):
       case(als_continuous_polling_low_threshold):
@@ -3319,7 +3337,7 @@
    }
    if(status)
       return status;
-   if((operating_mode==range_continuous_polling)||(operating_mode==range_continuous_interrupt))
+   if((operating_mode==range_single_shot_polling)||(operating_mode==range_continuous_polling)||(operating_mode==range_continuous_interrupt))
    {
       if(IntStatus.status.Range==RES_INT_STAT_GPIO_NEW_SAMPLE_READY)
          status=VL6180x_RangeGetMeasurement(Device, &RangeData);
@@ -3382,7 +3400,7 @@
    }
    if(status)
       return status;
-   if((operating_mode==als_continuous_polling)||(operating_mode==als_continuous_interrupt))
+   if((operating_mode==als_single_shot_polling)||(operating_mode==als_continuous_polling)||(operating_mode==als_continuous_interrupt))
    {
       if(IntStatus==RES_INT_STAT_GPIO_NEW_SAMPLE_READY)
          status=VL6180x_AlsGetMeasurement(Device, &AlsData);
@@ -3581,7 +3599,7 @@
       VL6180x_ErrLog("VL6180x_ClearErrorInterrupt fail");
       return status;
    }
-   status=VL6180x_AlsSetThresholds(Device, 0x0, 0xFF);
+   status=VL6180x_AlsSetThresholds(Device, 0x0, 0xFFFF);
    if(status)
       VL6180x_ErrLog("VL6180x_AlsSetThresholds fail");
    return status;
--- a/Components/VL6180X/vl6180x_class.h	Fri Oct 30 11:35:36 2015 +0100
+++ b/Components/VL6180X/vl6180x_class.h	Mon Nov 02 14:02:53 2015 +0100
@@ -145,7 +145,7 @@
     }
 		
     int InitSensor(uint8_t NewAddr);
-    int StartMeasurement(OperatingMode operating_mode, void (*fptr)(void), MeasureData_t *Data, uint16_t low, uint16_t high);
+    int StartMeasurement(OperatingMode operating_mode, void (*fptr)(void), uint16_t low, uint16_t high);
     int GetMeasurement(OperatingMode operating_mode, MeasureData_t *Data);		
     int StopMeasurement(OperatingMode operating_mode);
 
@@ -277,7 +277,7 @@
        return VL6180x_AlsSetAnalogueGain(Device, gain);
     }
 		
-    int AlsSetThresholds(uint8_t low, uint8_t high)
+    int AlsSetThresholds(uint16_t low, uint16_t high)
     {
        return VL6180x_AlsSetThresholds(Device, low, high);
     }
@@ -446,6 +446,11 @@
     {
        return VL6180x_AlsSetSystemMode(Device, MODE_START_STOP|MODE_CONTINUOUS);
     }
+    
+    int AlsStartSingleShot()
+    {
+       return VL6180x_AlsSetSystemMode(Device, MODE_START_STOP|MODE_SINGLESHOT);
+    }
 		
  private:		
     /* api.h functions */
@@ -468,7 +473,7 @@
     int VL6180x_AlsSetIntegrationPeriod(VL6180xDev_t dev, uint16_t period_ms);
     int VL6180x_AlsSetInterMeasurementPeriod(VL6180xDev_t dev,  uint16_t intermeasurement_period_ms);
     int VL6180x_AlsSetAnalogueGain(VL6180xDev_t dev, uint8_t gain);
-    int VL6180x_AlsSetThresholds(VL6180xDev_t dev, uint8_t low, uint8_t high);
+    int VL6180x_AlsSetThresholds(VL6180xDev_t dev, uint16_t low, uint16_t high);
     int VL6180x_AlsGetInterruptStatus(VL6180xDev_t dev, uint8_t *pIntStatus);
     int VL6180x_StaticInit(VL6180xDev_t dev);
     int VL6180x_RangeWaitDeviceReady(VL6180xDev_t dev, int MaxLoop );
@@ -549,8 +554,8 @@
     int AlsSetHighThreshold(uint16_t threshold);
     int GetRangeError(MeasureData_t *Data, VL6180x_RangeData_t RangeData);
     int GetAlsError(MeasureData_t *Data, VL6180x_AlsData_t AlsData);
-    int RangeMeasPollSingleShot(MeasureData_t *Data);
-    int AlsMeasPollSingleShot(MeasureData_t *Data);		
+    int RangeMeasPollSingleShot();
+    int AlsMeasPollSingleShot();		
     int RangeMeasPollContinuousMode();	
     int AlsMeasPollContinuousMode();
     int AlsGetMeasurementIfReady(VL6180xDev_t dev, VL6180x_AlsData_t *pAlsData);