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
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:
- on-board VL6180X proximity and ambient light sensor,
- up to three additional VL6180X Satellites,
- 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
A3pin; - to solder R47 resistor connected to
A5pin.
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
Revision 24:025afc3fe30f, committed 2015-11-02
- 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
--- 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);

X-NUCLEO-6180XA1 Proximity and Ambient Light Sensor