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 return 0; 00093 } 00094 00095 void VL6180::VL6180_DefautSettings(void) 00096 { 00097 //Recommended settings from datasheet 00098 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf 00099 00100 //Enable Interrupts on Conversion Complete (any source) 00101 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CONFIG_GPIO, (4 << 3)|(4) ); // Set GPIO1 high when sample complete 00102 00103 00104 VL6180_setRegister(VL6180_SYSTEM_MODE_GPIO1, 0x10); // Set GPIO1 high when sample complete 00105 VL6180_setRegister(VL6180_READOUT_AVERAGING_SAMPLE_PERIOD, 0x30); //Set Avg sample period 00106 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN, 0x46); // Set the ALS gain 00107 VL6180_setRegister(VL6180_SYSRANGE_VHV_REPEAT_RATE, 0xFF); // Set auto calibration period (Max = 255)/(OFF = 0) 00108 VL6180_setRegister(VL6180_SYSALS_INTEGRATION_PERIOD, 0x63); // Set ALS integration time to 100ms 00109 VL6180_setRegister(VL6180_SYSRANGE_VHV_RECALIBRATE, 0x01); // perform a single temperature calibration 00110 //Optional settings from datasheet 00111 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf 00112 VL6180_setRegister(VL6180_SYSRANGE_INTERMEASUREMENT_PERIOD, 0x09); // Set default ranging inter-measurement period to 100ms 00113 VL6180_setRegister(VL6180_SYSALS_INTERMEASUREMENT_PERIOD, 0x0A); // Set default ALS inter-measurement period to 100ms 00114 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CONFIG_GPIO, 0x24); // Configures interrupt on ‘New Sample Ready threshold event’ 00115 //Additional settings defaults from community 00116 VL6180_setRegister(VL6180_SYSRANGE_MAX_CONVERGENCE_TIME, 0x32); 00117 VL6180_setRegister(VL6180_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01); 00118 VL6180_setRegister16bit(VL6180_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x7B ); 00119 VL6180_setRegister16bit(VL6180_SYSALS_INTEGRATION_PERIOD, 0x64); 00120 00121 VL6180_setRegister(VL6180_READOUT_AVERAGING_SAMPLE_PERIOD,0x30); 00122 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN,0x40); 00123 VL6180_setRegister(VL6180_FIRMWARE_RESULT_SCALER,0x01); 00124 } 00125 void VL6180::getIdentification(struct VL6180Identification *temp) 00126 { 00127 00128 temp->idModel = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_ID); 00129 temp->idModelRevMajor = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_REV_MAJOR); 00130 temp->idModelRevMinor = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_REV_MINOR); 00131 temp->idModuleRevMajor = VL6180_getRegister(VL6180_IDENTIFICATION_MODULE_REV_MAJOR); 00132 temp->idModuleRevMinor = VL6180_getRegister(VL6180_IDENTIFICATION_MODULE_REV_MINOR); 00133 00134 temp->idDate = VL6180_getRegister16bit(VL6180_IDENTIFICATION_DATE); 00135 temp->idTime = VL6180_getRegister16bit(VL6180_IDENTIFICATION_TIME); 00136 } 00137 00138 00139 uint8_t VL6180::changeAddress(uint8_t old_address, uint8_t new_address) 00140 { 00141 00142 //NOTICE: IT APPEARS THAT CHANGING THE ADDRESS IS NOT STORED IN NON-VOLATILE MEMORY 00143 // POWER CYCLING THE DEVICE REVERTS ADDRESS BACK TO 0X29 00144 00145 if( old_address == new_address) return old_address; 00146 if( new_address > 127) return old_address; 00147 00148 VL6180_setRegister(VL6180_I2C_SLAVE_DEVICE_ADDRESS, new_address); 00149 00150 return VL6180_getRegister(VL6180_I2C_SLAVE_DEVICE_ADDRESS); 00151 } 00152 00153 00154 00155 uint8_t VL6180::getDistance() 00156 { 00157 VL6180_setRegister(VL6180_SYSRANGE_START, 0x01); //Start Single shot mode 00158 wait(0.01); // 10mS 00159 return VL6180_getRegister(VL6180_RESULT_RANGE_VAL); 00160 // VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CLEAR, 0x07); 00161 // return distance; 00162 } 00163 00164 float VL6180::getAmbientLight(VL6180_als_gain VL6180_ALS_GAIN) 00165 { 00166 //First load in Gain we are using, do it everytime incase someone changes it on us. 00167 //Note: Upper nibble shoudl be set to 0x4 i.e. for ALS gain of 1.0 write 0x46 00168 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN, (0x40 | VL6180_ALS_GAIN)); // Set the ALS gain 00169 00170 //Start ALS Measurement 00171 VL6180_setRegister(VL6180_SYSALS_START, 0x01); 00172 00173 wait(0.1); //100Ms 00174 00175 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CLEAR, 0x07); 00176 00177 //Retrieve the Raw ALS value from the sensoe 00178 unsigned int alsRaw = VL6180_getRegister16bit(VL6180_RESULT_ALS_VAL); 00179 00180 //Get Integration Period for calculation, we do this everytime incase someone changes it on us. 00181 unsigned int alsIntegrationPeriodRaw = VL6180_getRegister16bit(VL6180_SYSALS_INTEGRATION_PERIOD); 00182 00183 float alsIntegrationPeriod = 100.0 / alsIntegrationPeriodRaw ; 00184 00185 //Calculate actual LUX from Appnotes 00186 00187 float alsGain = 0.0; 00188 00189 switch (VL6180_ALS_GAIN) { 00190 case GAIN_20: 00191 alsGain = 20.0; 00192 break; 00193 case GAIN_10: 00194 alsGain = 10.32; 00195 break; 00196 case GAIN_5: 00197 alsGain = 5.21; 00198 break; 00199 case GAIN_2_5: 00200 alsGain = 2.60; 00201 break; 00202 case GAIN_1_67: 00203 alsGain = 1.72; 00204 break; 00205 case GAIN_1_25: 00206 alsGain = 1.28; 00207 break; 00208 case GAIN_1: 00209 alsGain = 1.01; 00210 break; 00211 case GAIN_40: 00212 alsGain = 40.0; 00213 break; 00214 } 00215 00216 //Calculate LUX from formula in AppNotes 00217 00218 float alsCalculated = (float)0.32 * ((float)alsRaw / alsGain) * alsIntegrationPeriod; 00219 00220 return alsCalculated; 00221 } 00222 00223 // --- Private Functions --- // 00224 00225 uint8_t VL6180::VL6180_getRegister(uint16_t reg_address) 00226 { 00227 char data[2]; 00228 00229 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00230 data[1] = reg_address & 0xFF; //LSB of register address 00231 VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 2); 00232 VL6180_error_no = i2c.read(VL6180_i2cAddress, data, 1, false); 00233 return data[0]; 00234 } 00235 00236 uint16_t VL6180::VL6180_getRegister16bit(uint16_t reg_address) 00237 { 00238 char data[2]; 00239 00240 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00241 data[1] = reg_address & 0xFF; //LSB of register address 00242 VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 2); 00243 VL6180_error_no = i2c.read(VL6180_i2cAddress, data, 2, false); 00244 return (data[0] + ((data[1] << 8) & 0xFF00)); 00245 } 00246 00247 void VL6180::VL6180_setRegister(uint16_t reg_address, uint8_t value) 00248 { 00249 char data[3]; 00250 00251 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00252 data[1] = reg_address & 0xFF; //LSB of register address 00253 data[2] = value; 00254 VL6180_error_no = VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 3); 00255 } 00256 00257 void VL6180::VL6180_setRegister16bit(uint16_t reg_address, uint16_t value) 00258 { 00259 char data[4]; 00260 00261 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00262 data[1] = reg_address & 0xFF; //LSB of register address 00263 data[2] = value & 0xFF; 00264 data[3] = ((value >> 8) & 0xFF); 00265 VL6180_error_no = VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 4); 00266 } 00267 00268 int VL6180::writeSingleRegister( uint16_t reg_address, uint8_t data ) 00269 { 00270 00271 char data_write[3]; 00272 data_write[0] = (reg_address >> 8) & 0xFF; //MSB of register address 00273 data_write[1] = reg_address & 0xFF; //LSB of register address 00274 data_write[2] = data & 0xFF; 00275 return i2c.write(VL6180_DEF_ADDR, data_write, 3); 00276 00277 // char tx[2] = { address | 160, data }; //0d160 = 0b10100000 00278 // int ack = i2c.write( SLAVE_ADDRESS << 1, tx, 2 ); 00279 // return ack; 00280 }
Generated on Wed Jul 13 2022 10:33:40 by
