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.
VL6180.cpp
00001 /****************************************************************************** 00002 * SFE_VL6180.cpp 00003 * Library for VL6180 time of flight range finder. 00004 * Casey Kuhns @ SparkFun Electronics 00005 * 10/29/2014 00006 * https://github.com/sparkfun/ 00007 * 00008 * The VL6180 by ST micro is a time of flight range finder that 00009 * uses pulsed IR light to determine distances from object at close 00010 * range. The average range of a sensor is between 0-200mm 00011 * 00012 * In this file are the functions in the VL6180 class 00013 * 00014 * Resources: 00015 * This library uses the Arduino Wire.h to complete I2C transactions. 00016 * 00017 * Development environment specifics: 00018 * IDE: Arduino 1.0.5 00019 * Hardware Platform: Arduino Pro 3.3V/8MHz 00020 * VL6180 Breakout Version: 1.0 00021 * 00022 * 00023 * This code is beerware. If you see me (or any other SparkFun employee) at the 00024 * local pub, and you've found our code helpful, please buy us a round! 00025 * 00026 * Distributed as-is; no warranty is given. 00027 ******************************************************************************/ 00028 00029 #include "VL6180.h" 00030 00031 // 00032 // Constructors 00033 // 00034 VL6180::VL6180(PinName sda, PinName scl) : i2c(sda, scl) 00035 { 00036 VL6180_i2cAddress = VL6180_DEF_ADDR; 00037 } 00038 00039 VL6180::VL6180(PinName sda, PinName scl, int i2cAddress) : i2c(sda, scl) 00040 { 00041 VL6180_i2cAddress = i2cAddress; 00042 VL6180_error_no = 0; 00043 } 00044 // 00045 // destructor 00046 // 00047 VL6180::~VL6180() 00048 { 00049 } 00050 00051 int8_t VL6180::VL6180_Init(void) 00052 { 00053 uint8_t data; //for temp data storage 00054 00055 data = VL6180_getRegister(VL6180_SYSTEM_FRESH_OUT_OF_RESET); 00056 00057 if(data != 1) return VL6180_FAILURE_RESET; 00058 00059 //Required by datasheet 00060 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf 00061 VL6180_setRegister(0x0207, 0x01); 00062 VL6180_setRegister(0x0208, 0x01); 00063 VL6180_setRegister(0x0096, 0x00); 00064 VL6180_setRegister(0x0097, 0xfd); 00065 VL6180_setRegister(0x00e3, 0x00); 00066 VL6180_setRegister(0x00e4, 0x04); 00067 VL6180_setRegister(0x00e5, 0x02); 00068 VL6180_setRegister(0x00e6, 0x01); 00069 VL6180_setRegister(0x00e7, 0x03); 00070 VL6180_setRegister(0x00f5, 0x02); 00071 VL6180_setRegister(0x00d9, 0x05); 00072 VL6180_setRegister(0x00db, 0xce); 00073 VL6180_setRegister(0x00dc, 0x03); 00074 VL6180_setRegister(0x00dd, 0xf8); 00075 VL6180_setRegister(0x009f, 0x00); 00076 VL6180_setRegister(0x00a3, 0x3c); 00077 VL6180_setRegister(0x00b7, 0x00); 00078 VL6180_setRegister(0x00bb, 0x3c); 00079 VL6180_setRegister(0x00b2, 0x09); 00080 VL6180_setRegister(0x00ca, 0x09); 00081 VL6180_setRegister(0x0198, 0x01); 00082 VL6180_setRegister(0x01b0, 0x17); 00083 VL6180_setRegister(0x01ad, 0x00); 00084 VL6180_setRegister(0x00ff, 0x05); 00085 VL6180_setRegister(0x0100, 0x05); 00086 VL6180_setRegister(0x0199, 0x05); 00087 VL6180_setRegister(0x01a6, 0x1b); 00088 VL6180_setRegister(0x01ac, 0x3e); 00089 VL6180_setRegister(0x01a7, 0x1f); 00090 VL6180_setRegister(0x0030, 0x00); 00091 00092 VL6180_setRegister(VL6180_SYSTEM_FRESH_OUT_OF_RESET, 0x00); 00093 return 0; 00094 } 00095 00096 void VL6180::VL6180_DefautSettings(void) 00097 { 00098 //Recommended settings from datasheet 00099 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf 00100 00101 //Enable Interrupts on Conversion Complete (any source) 00102 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CONFIG_GPIO, (4 << 3)|(4) ); // Set GPIO1 high when sample complete 00103 00104 00105 VL6180_setRegister(VL6180_SYSTEM_MODE_GPIO1, 0x10); // Set GPIO1 high when sample complete 00106 VL6180_setRegister(VL6180_READOUT_AVERAGING_SAMPLE_PERIOD, 0x30); //Set Avg sample period 00107 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN, 0x46); // Set the ALS gain 00108 VL6180_setRegister(VL6180_SYSRANGE_VHV_REPEAT_RATE, 0xFF); // Set auto calibration period (Max = 255)/(OFF = 0) 00109 VL6180_setRegister(VL6180_SYSALS_INTEGRATION_PERIOD, 0x63); // Set ALS integration time to 100ms 00110 VL6180_setRegister(VL6180_SYSRANGE_VHV_RECALIBRATE, 0x01); // perform a single temperature calibration 00111 //Optional settings from datasheet 00112 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf 00113 VL6180_setRegister(VL6180_SYSRANGE_INTERMEASUREMENT_PERIOD, 0x09); // Set default ranging inter-measurement period to 100ms 00114 VL6180_setRegister(VL6180_SYSALS_INTERMEASUREMENT_PERIOD, 0x0A); // Set default ALS inter-measurement period to 100ms 00115 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CONFIG_GPIO, 0x24); // Configures interrupt on 鈥楴ew Sample Ready threshold event鈥? 00116 //Additional settings defaults from community 00117 VL6180_setRegister(VL6180_SYSRANGE_MAX_CONVERGENCE_TIME, 0x32); 00118 VL6180_setRegister(VL6180_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01); 00119 VL6180_setRegister16bit(VL6180_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x7B ); 00120 VL6180_setRegister16bit(VL6180_SYSALS_INTEGRATION_PERIOD, 0x64); 00121 00122 VL6180_setRegister(VL6180_READOUT_AVERAGING_SAMPLE_PERIOD,0x30); 00123 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN,0x40); 00124 VL6180_setRegister(VL6180_FIRMWARE_RESULT_SCALER,0x01); 00125 } 00126 void VL6180::getIdentification(struct VL6180Identification *temp) 00127 { 00128 00129 temp->idModel = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_ID); 00130 temp->idModelRevMajor = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_REV_MAJOR); 00131 temp->idModelRevMinor = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_REV_MINOR); 00132 temp->idModuleRevMajor = VL6180_getRegister(VL6180_IDENTIFICATION_MODULE_REV_MAJOR); 00133 temp->idModuleRevMinor = VL6180_getRegister(VL6180_IDENTIFICATION_MODULE_REV_MINOR); 00134 00135 temp->idDate = VL6180_getRegister16bit(VL6180_IDENTIFICATION_DATE); 00136 temp->idTime = VL6180_getRegister16bit(VL6180_IDENTIFICATION_TIME); 00137 } 00138 00139 00140 uint8_t VL6180::changeAddress(uint8_t old_address, uint8_t new_address) 00141 { 00142 00143 //NOTICE: IT APPEARS THAT CHANGING THE ADDRESS IS NOT STORED IN NON-VOLATILE MEMORY 00144 // POWER CYCLING THE DEVICE REVERTS ADDRESS BACK TO 0X29 00145 00146 if( old_address == new_address) return old_address; 00147 if( new_address > 127) return old_address; 00148 00149 VL6180_setRegister(VL6180_I2C_SLAVE_DEVICE_ADDRESS, new_address); 00150 00151 return VL6180_getRegister(VL6180_I2C_SLAVE_DEVICE_ADDRESS); 00152 } 00153 00154 00155 00156 uint8_t VL6180::getDistance() 00157 { 00158 VL6180_setRegister(VL6180_SYSRANGE_START, 0x01); //Start Single shot mode 00159 wait(0.01); // 10mS 00160 return VL6180_getRegister(VL6180_RESULT_RANGE_VAL); 00161 // VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CLEAR, 0x07); 00162 // return distance; 00163 } 00164 00165 float VL6180::getAmbientLight(VL6180_als_gain VL6180_ALS_GAIN) 00166 { 00167 //First load in Gain we are using, do it everytime incase someone changes it on us. 00168 //Note: Upper nibble shoudl be set to 0x4 i.e. for ALS gain of 1.0 write 0x46 00169 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN, (0x40 | VL6180_ALS_GAIN)); // Set the ALS gain 00170 00171 //Start ALS Measurement 00172 VL6180_setRegister(VL6180_SYSALS_START, 0x01); 00173 00174 wait(0.1); //100Ms 00175 00176 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CLEAR, 0x07); 00177 00178 //Retrieve the Raw ALS value from the sensoe 00179 unsigned int alsRaw = VL6180_getRegister16bit(VL6180_RESULT_ALS_VAL); 00180 00181 //Get Integration Period for calculation, we do this everytime incase someone changes it on us. 00182 unsigned int alsIntegrationPeriodRaw = VL6180_getRegister16bit(VL6180_SYSALS_INTEGRATION_PERIOD); 00183 00184 float alsIntegrationPeriod = 100.0 / alsIntegrationPeriodRaw ; 00185 00186 //Calculate actual LUX from Appnotes 00187 00188 float alsGain = 0.0; 00189 00190 switch (VL6180_ALS_GAIN) { 00191 case GAIN_20: 00192 alsGain = 20.0; 00193 break; 00194 case GAIN_10: 00195 alsGain = 10.32; 00196 break; 00197 case GAIN_5: 00198 alsGain = 5.21; 00199 break; 00200 case GAIN_2_5: 00201 alsGain = 2.60; 00202 break; 00203 case GAIN_1_67: 00204 alsGain = 1.72; 00205 break; 00206 case GAIN_1_25: 00207 alsGain = 1.28; 00208 break; 00209 case GAIN_1: 00210 alsGain = 1.01; 00211 break; 00212 case GAIN_40: 00213 alsGain = 40.0; 00214 break; 00215 } 00216 00217 //Calculate LUX from formula in AppNotes 00218 00219 float alsCalculated = (float)0.32 * ((float)alsRaw / alsGain) * alsIntegrationPeriod; 00220 00221 return alsCalculated; 00222 } 00223 00224 // --- Private Functions --- // 00225 00226 uint8_t VL6180::VL6180_getRegister(uint16_t reg_address) 00227 { 00228 char data[2]; 00229 00230 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00231 data[1] = reg_address & 0xFF; //LSB of register address 00232 VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 2); 00233 VL6180_error_no = i2c.read(VL6180_i2cAddress, data, 1, false); 00234 return data[0]; 00235 } 00236 00237 uint16_t VL6180::VL6180_getRegister16bit(uint16_t reg_address) 00238 { 00239 char data[2]; 00240 00241 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00242 data[1] = reg_address & 0xFF; //LSB of register address 00243 VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 2); 00244 VL6180_error_no = i2c.read(VL6180_i2cAddress, data, 2, false); 00245 return (data[0] + ((data[1] << 8) & 0xFF00)); 00246 } 00247 00248 void VL6180::VL6180_setRegister(uint16_t reg_address, uint8_t value) 00249 { 00250 char data[3]; 00251 00252 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00253 data[1] = reg_address & 0xFF; //LSB of register address 00254 data[2] = value; 00255 VL6180_error_no = VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 3); 00256 } 00257 00258 void VL6180::VL6180_setRegister16bit(uint16_t reg_address, uint16_t value) 00259 { 00260 char data[4]; 00261 00262 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00263 data[1] = reg_address & 0xFF; //LSB of register address 00264 data[2] = value & 0xFF; 00265 data[3] = ((value >> 8) & 0xFF); 00266 VL6180_error_no = VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 4); 00267 } 00268 00269 int VL6180::writeSingleRegister( uint16_t reg_address, uint8_t data ) 00270 { 00271 00272 char data_write[3]; 00273 data_write[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00274 data_write[1] = reg_address & 0xFF; //LSB of register address 00275 data_write[2] = data & 0xFF; 00276 return i2c.write(VL6180_DEF_ADDR, data_write, 3); 00277 00278 // char tx[2] = { address | 160, data }; //0d160 = 0b10100000 00279 // int ack = i2c.write( SLAVE_ADDRESS << 1, tx, 2 ); 00280 // return ack; 00281 } 00282
Generated on Wed Jul 13 2022 00:50:23 by
