Test

Dependents:   final

Committer:
brucewthomson
Date:
Fri Oct 14 00:47:55 2016 +0000
Revision:
0:82297674d72d
Test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
brucewthomson 0:82297674d72d 1 /******************************************************************************
brucewthomson 0:82297674d72d 2 * SFE_VL6180.cpp
brucewthomson 0:82297674d72d 3 * Library for VL6180 time of flight range finder.
brucewthomson 0:82297674d72d 4 * Casey Kuhns @ SparkFun Electronics
brucewthomson 0:82297674d72d 5 * 10/29/2014
brucewthomson 0:82297674d72d 6 * https://github.com/sparkfun/
brucewthomson 0:82297674d72d 7 *
brucewthomson 0:82297674d72d 8 * The VL6180 by ST micro is a time of flight range finder that
brucewthomson 0:82297674d72d 9 * uses pulsed IR light to determine distances from object at close
brucewthomson 0:82297674d72d 10 * range. The average range of a sensor is between 0-200mm
brucewthomson 0:82297674d72d 11 *
brucewthomson 0:82297674d72d 12 * In this file are the functions in the VL6180 class
brucewthomson 0:82297674d72d 13 *
brucewthomson 0:82297674d72d 14 * Resources:
brucewthomson 0:82297674d72d 15 * This library uses the Arduino Wire.h to complete I2C transactions.
brucewthomson 0:82297674d72d 16 *
brucewthomson 0:82297674d72d 17 * Development environment specifics:
brucewthomson 0:82297674d72d 18 * IDE: Arduino 1.0.5
brucewthomson 0:82297674d72d 19 * Hardware Platform: Arduino Pro 3.3V/8MHz
brucewthomson 0:82297674d72d 20 * VL6180 Breakout Version: 1.0
brucewthomson 0:82297674d72d 21 *
brucewthomson 0:82297674d72d 22 *
brucewthomson 0:82297674d72d 23 * This code is beerware. If you see me (or any other SparkFun employee) at the
brucewthomson 0:82297674d72d 24 * local pub, and you've found our code helpful, please buy us a round!
brucewthomson 0:82297674d72d 25 *
brucewthomson 0:82297674d72d 26 * Distributed as-is; no warranty is given.
brucewthomson 0:82297674d72d 27 ******************************************************************************/
brucewthomson 0:82297674d72d 28
brucewthomson 0:82297674d72d 29 #include "VL6180.h"
brucewthomson 0:82297674d72d 30
brucewthomson 0:82297674d72d 31 //
brucewthomson 0:82297674d72d 32 // Constructors
brucewthomson 0:82297674d72d 33 //
brucewthomson 0:82297674d72d 34 VL6180::VL6180(PinName sda, PinName scl) : i2c(sda, scl)
brucewthomson 0:82297674d72d 35 {
brucewthomson 0:82297674d72d 36 VL6180_i2cAddress = VL6180_DEF_ADDR;
brucewthomson 0:82297674d72d 37 }
brucewthomson 0:82297674d72d 38
brucewthomson 0:82297674d72d 39 VL6180::VL6180(PinName sda, PinName scl, int i2cAddress) : i2c(sda, scl)
brucewthomson 0:82297674d72d 40 {
brucewthomson 0:82297674d72d 41 VL6180_i2cAddress = i2cAddress;
brucewthomson 0:82297674d72d 42 VL6180_error_no = 0;
brucewthomson 0:82297674d72d 43 }
brucewthomson 0:82297674d72d 44 //
brucewthomson 0:82297674d72d 45 // destructor
brucewthomson 0:82297674d72d 46 //
brucewthomson 0:82297674d72d 47 VL6180::~VL6180()
brucewthomson 0:82297674d72d 48 {
brucewthomson 0:82297674d72d 49 }
brucewthomson 0:82297674d72d 50
brucewthomson 0:82297674d72d 51 int8_t VL6180::VL6180_Init(void)
brucewthomson 0:82297674d72d 52 {
brucewthomson 0:82297674d72d 53 uint8_t data; //for temp data storage
brucewthomson 0:82297674d72d 54
brucewthomson 0:82297674d72d 55 data = VL6180_getRegister(VL6180_SYSTEM_FRESH_OUT_OF_RESET);
brucewthomson 0:82297674d72d 56
brucewthomson 0:82297674d72d 57 if(data != 1) return VL6180_FAILURE_RESET;
brucewthomson 0:82297674d72d 58
brucewthomson 0:82297674d72d 59 //Required by datasheet
brucewthomson 0:82297674d72d 60 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf
brucewthomson 0:82297674d72d 61 VL6180_setRegister(0x0207, 0x01);
brucewthomson 0:82297674d72d 62 VL6180_setRegister(0x0208, 0x01);
brucewthomson 0:82297674d72d 63 VL6180_setRegister(0x0096, 0x00);
brucewthomson 0:82297674d72d 64 VL6180_setRegister(0x0097, 0xfd);
brucewthomson 0:82297674d72d 65 VL6180_setRegister(0x00e3, 0x00);
brucewthomson 0:82297674d72d 66 VL6180_setRegister(0x00e4, 0x04);
brucewthomson 0:82297674d72d 67 VL6180_setRegister(0x00e5, 0x02);
brucewthomson 0:82297674d72d 68 VL6180_setRegister(0x00e6, 0x01);
brucewthomson 0:82297674d72d 69 VL6180_setRegister(0x00e7, 0x03);
brucewthomson 0:82297674d72d 70 VL6180_setRegister(0x00f5, 0x02);
brucewthomson 0:82297674d72d 71 VL6180_setRegister(0x00d9, 0x05);
brucewthomson 0:82297674d72d 72 VL6180_setRegister(0x00db, 0xce);
brucewthomson 0:82297674d72d 73 VL6180_setRegister(0x00dc, 0x03);
brucewthomson 0:82297674d72d 74 VL6180_setRegister(0x00dd, 0xf8);
brucewthomson 0:82297674d72d 75 VL6180_setRegister(0x009f, 0x00);
brucewthomson 0:82297674d72d 76 VL6180_setRegister(0x00a3, 0x3c);
brucewthomson 0:82297674d72d 77 VL6180_setRegister(0x00b7, 0x00);
brucewthomson 0:82297674d72d 78 VL6180_setRegister(0x00bb, 0x3c);
brucewthomson 0:82297674d72d 79 VL6180_setRegister(0x00b2, 0x09);
brucewthomson 0:82297674d72d 80 VL6180_setRegister(0x00ca, 0x09);
brucewthomson 0:82297674d72d 81 VL6180_setRegister(0x0198, 0x01);
brucewthomson 0:82297674d72d 82 VL6180_setRegister(0x01b0, 0x17);
brucewthomson 0:82297674d72d 83 VL6180_setRegister(0x01ad, 0x00);
brucewthomson 0:82297674d72d 84 VL6180_setRegister(0x00ff, 0x05);
brucewthomson 0:82297674d72d 85 VL6180_setRegister(0x0100, 0x05);
brucewthomson 0:82297674d72d 86 VL6180_setRegister(0x0199, 0x05);
brucewthomson 0:82297674d72d 87 VL6180_setRegister(0x01a6, 0x1b);
brucewthomson 0:82297674d72d 88 VL6180_setRegister(0x01ac, 0x3e);
brucewthomson 0:82297674d72d 89 VL6180_setRegister(0x01a7, 0x1f);
brucewthomson 0:82297674d72d 90 VL6180_setRegister(0x0030, 0x00);
brucewthomson 0:82297674d72d 91
brucewthomson 0:82297674d72d 92 return 0;
brucewthomson 0:82297674d72d 93 }
brucewthomson 0:82297674d72d 94
brucewthomson 0:82297674d72d 95 void VL6180::VL6180_DefautSettings(void)
brucewthomson 0:82297674d72d 96 {
brucewthomson 0:82297674d72d 97 //Recommended settings from datasheet
brucewthomson 0:82297674d72d 98 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf
brucewthomson 0:82297674d72d 99
brucewthomson 0:82297674d72d 100 //Enable Interrupts on Conversion Complete (any source)
brucewthomson 0:82297674d72d 101 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CONFIG_GPIO, (4 << 3)|(4) ); // Set GPIO1 high when sample complete
brucewthomson 0:82297674d72d 102
brucewthomson 0:82297674d72d 103
brucewthomson 0:82297674d72d 104 VL6180_setRegister(VL6180_SYSTEM_MODE_GPIO1, 0x10); // Set GPIO1 high when sample complete
brucewthomson 0:82297674d72d 105 VL6180_setRegister(VL6180_READOUT_AVERAGING_SAMPLE_PERIOD, 0x30); //Set Avg sample period
brucewthomson 0:82297674d72d 106 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN, 0x46); // Set the ALS gain
brucewthomson 0:82297674d72d 107 VL6180_setRegister(VL6180_SYSRANGE_VHV_REPEAT_RATE, 0xFF); // Set auto calibration period (Max = 255)/(OFF = 0)
brucewthomson 0:82297674d72d 108 VL6180_setRegister(VL6180_SYSALS_INTEGRATION_PERIOD, 0x63); // Set ALS integration time to 100ms
brucewthomson 0:82297674d72d 109 VL6180_setRegister(VL6180_SYSRANGE_VHV_RECALIBRATE, 0x01); // perform a single temperature calibration
brucewthomson 0:82297674d72d 110 //Optional settings from datasheet
brucewthomson 0:82297674d72d 111 //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf
brucewthomson 0:82297674d72d 112 VL6180_setRegister(VL6180_SYSRANGE_INTERMEASUREMENT_PERIOD, 0x09); // Set default ranging inter-measurement period to 100ms
brucewthomson 0:82297674d72d 113 VL6180_setRegister(VL6180_SYSALS_INTERMEASUREMENT_PERIOD, 0x0A); // Set default ALS inter-measurement period to 100ms
brucewthomson 0:82297674d72d 114 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CONFIG_GPIO, 0x24); // Configures interrupt on ‘New Sample Ready threshold event’
brucewthomson 0:82297674d72d 115 //Additional settings defaults from community
brucewthomson 0:82297674d72d 116 VL6180_setRegister(VL6180_SYSRANGE_MAX_CONVERGENCE_TIME, 0x32);
brucewthomson 0:82297674d72d 117 VL6180_setRegister(VL6180_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01);
brucewthomson 0:82297674d72d 118 VL6180_setRegister16bit(VL6180_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x7B );
brucewthomson 0:82297674d72d 119 VL6180_setRegister16bit(VL6180_SYSALS_INTEGRATION_PERIOD, 0x64);
brucewthomson 0:82297674d72d 120
brucewthomson 0:82297674d72d 121 VL6180_setRegister(VL6180_READOUT_AVERAGING_SAMPLE_PERIOD,0x30);
brucewthomson 0:82297674d72d 122 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN,0x40);
brucewthomson 0:82297674d72d 123 VL6180_setRegister(VL6180_FIRMWARE_RESULT_SCALER,0x01);
brucewthomson 0:82297674d72d 124 }
brucewthomson 0:82297674d72d 125 void VL6180::getIdentification(struct VL6180Identification *temp)
brucewthomson 0:82297674d72d 126 {
brucewthomson 0:82297674d72d 127
brucewthomson 0:82297674d72d 128 temp->idModel = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_ID);
brucewthomson 0:82297674d72d 129 temp->idModelRevMajor = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_REV_MAJOR);
brucewthomson 0:82297674d72d 130 temp->idModelRevMinor = VL6180_getRegister(VL6180_IDENTIFICATION_MODEL_REV_MINOR);
brucewthomson 0:82297674d72d 131 temp->idModuleRevMajor = VL6180_getRegister(VL6180_IDENTIFICATION_MODULE_REV_MAJOR);
brucewthomson 0:82297674d72d 132 temp->idModuleRevMinor = VL6180_getRegister(VL6180_IDENTIFICATION_MODULE_REV_MINOR);
brucewthomson 0:82297674d72d 133
brucewthomson 0:82297674d72d 134 temp->idDate = VL6180_getRegister16bit(VL6180_IDENTIFICATION_DATE);
brucewthomson 0:82297674d72d 135 temp->idTime = VL6180_getRegister16bit(VL6180_IDENTIFICATION_TIME);
brucewthomson 0:82297674d72d 136 }
brucewthomson 0:82297674d72d 137
brucewthomson 0:82297674d72d 138
brucewthomson 0:82297674d72d 139 uint8_t VL6180::changeAddress(uint8_t old_address, uint8_t new_address)
brucewthomson 0:82297674d72d 140 {
brucewthomson 0:82297674d72d 141
brucewthomson 0:82297674d72d 142 //NOTICE: IT APPEARS THAT CHANGING THE ADDRESS IS NOT STORED IN NON-VOLATILE MEMORY
brucewthomson 0:82297674d72d 143 // POWER CYCLING THE DEVICE REVERTS ADDRESS BACK TO 0X29
brucewthomson 0:82297674d72d 144
brucewthomson 0:82297674d72d 145 if( old_address == new_address) return old_address;
brucewthomson 0:82297674d72d 146 if( new_address > 127) return old_address;
brucewthomson 0:82297674d72d 147
brucewthomson 0:82297674d72d 148 VL6180_setRegister(VL6180_I2C_SLAVE_DEVICE_ADDRESS, new_address);
brucewthomson 0:82297674d72d 149
brucewthomson 0:82297674d72d 150 return VL6180_getRegister(VL6180_I2C_SLAVE_DEVICE_ADDRESS);
brucewthomson 0:82297674d72d 151 }
brucewthomson 0:82297674d72d 152
brucewthomson 0:82297674d72d 153
brucewthomson 0:82297674d72d 154
brucewthomson 0:82297674d72d 155 uint8_t VL6180::getDistance()
brucewthomson 0:82297674d72d 156 {
brucewthomson 0:82297674d72d 157 VL6180_setRegister(VL6180_SYSRANGE_START, 0x01); //Start Single shot mode
brucewthomson 0:82297674d72d 158 wait(0.01); // 10mS
brucewthomson 0:82297674d72d 159 return VL6180_getRegister(VL6180_RESULT_RANGE_VAL);
brucewthomson 0:82297674d72d 160 // VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CLEAR, 0x07);
brucewthomson 0:82297674d72d 161 // return distance;
brucewthomson 0:82297674d72d 162 }
brucewthomson 0:82297674d72d 163
brucewthomson 0:82297674d72d 164 float VL6180::getAmbientLight(VL6180_als_gain VL6180_ALS_GAIN)
brucewthomson 0:82297674d72d 165 {
brucewthomson 0:82297674d72d 166 //First load in Gain we are using, do it everytime incase someone changes it on us.
brucewthomson 0:82297674d72d 167 //Note: Upper nibble shoudl be set to 0x4 i.e. for ALS gain of 1.0 write 0x46
brucewthomson 0:82297674d72d 168 VL6180_setRegister(VL6180_SYSALS_ANALOGUE_GAIN, (0x40 | VL6180_ALS_GAIN)); // Set the ALS gain
brucewthomson 0:82297674d72d 169
brucewthomson 0:82297674d72d 170 //Start ALS Measurement
brucewthomson 0:82297674d72d 171 VL6180_setRegister(VL6180_SYSALS_START, 0x01);
brucewthomson 0:82297674d72d 172
brucewthomson 0:82297674d72d 173 wait(0.1); //100Ms
brucewthomson 0:82297674d72d 174
brucewthomson 0:82297674d72d 175 VL6180_setRegister(VL6180_SYSTEM_INTERRUPT_CLEAR, 0x07);
brucewthomson 0:82297674d72d 176
brucewthomson 0:82297674d72d 177 //Retrieve the Raw ALS value from the sensoe
brucewthomson 0:82297674d72d 178 unsigned int alsRaw = VL6180_getRegister16bit(VL6180_RESULT_ALS_VAL);
brucewthomson 0:82297674d72d 179
brucewthomson 0:82297674d72d 180 //Get Integration Period for calculation, we do this everytime incase someone changes it on us.
brucewthomson 0:82297674d72d 181 unsigned int alsIntegrationPeriodRaw = VL6180_getRegister16bit(VL6180_SYSALS_INTEGRATION_PERIOD);
brucewthomson 0:82297674d72d 182
brucewthomson 0:82297674d72d 183 float alsIntegrationPeriod = 100.0 / alsIntegrationPeriodRaw ;
brucewthomson 0:82297674d72d 184
brucewthomson 0:82297674d72d 185 //Calculate actual LUX from Appnotes
brucewthomson 0:82297674d72d 186
brucewthomson 0:82297674d72d 187 float alsGain = 0.0;
brucewthomson 0:82297674d72d 188
brucewthomson 0:82297674d72d 189 switch (VL6180_ALS_GAIN) {
brucewthomson 0:82297674d72d 190 case GAIN_20:
brucewthomson 0:82297674d72d 191 alsGain = 20.0;
brucewthomson 0:82297674d72d 192 break;
brucewthomson 0:82297674d72d 193 case GAIN_10:
brucewthomson 0:82297674d72d 194 alsGain = 10.32;
brucewthomson 0:82297674d72d 195 break;
brucewthomson 0:82297674d72d 196 case GAIN_5:
brucewthomson 0:82297674d72d 197 alsGain = 5.21;
brucewthomson 0:82297674d72d 198 break;
brucewthomson 0:82297674d72d 199 case GAIN_2_5:
brucewthomson 0:82297674d72d 200 alsGain = 2.60;
brucewthomson 0:82297674d72d 201 break;
brucewthomson 0:82297674d72d 202 case GAIN_1_67:
brucewthomson 0:82297674d72d 203 alsGain = 1.72;
brucewthomson 0:82297674d72d 204 break;
brucewthomson 0:82297674d72d 205 case GAIN_1_25:
brucewthomson 0:82297674d72d 206 alsGain = 1.28;
brucewthomson 0:82297674d72d 207 break;
brucewthomson 0:82297674d72d 208 case GAIN_1:
brucewthomson 0:82297674d72d 209 alsGain = 1.01;
brucewthomson 0:82297674d72d 210 break;
brucewthomson 0:82297674d72d 211 case GAIN_40:
brucewthomson 0:82297674d72d 212 alsGain = 40.0;
brucewthomson 0:82297674d72d 213 break;
brucewthomson 0:82297674d72d 214 }
brucewthomson 0:82297674d72d 215
brucewthomson 0:82297674d72d 216 //Calculate LUX from formula in AppNotes
brucewthomson 0:82297674d72d 217
brucewthomson 0:82297674d72d 218 float alsCalculated = (float)0.32 * ((float)alsRaw / alsGain) * alsIntegrationPeriod;
brucewthomson 0:82297674d72d 219
brucewthomson 0:82297674d72d 220 return alsCalculated;
brucewthomson 0:82297674d72d 221 }
brucewthomson 0:82297674d72d 222
brucewthomson 0:82297674d72d 223 // --- Private Functions --- //
brucewthomson 0:82297674d72d 224
brucewthomson 0:82297674d72d 225 uint8_t VL6180::VL6180_getRegister(uint16_t reg_address)
brucewthomson 0:82297674d72d 226 {
brucewthomson 0:82297674d72d 227 char data[2];
brucewthomson 0:82297674d72d 228
brucewthomson 0:82297674d72d 229 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address
brucewthomson 0:82297674d72d 230 data[1] = reg_address & 0xFF; //LSB of register address
brucewthomson 0:82297674d72d 231 VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 2);
brucewthomson 0:82297674d72d 232 VL6180_error_no = i2c.read(VL6180_i2cAddress, data, 1, false);
brucewthomson 0:82297674d72d 233 return data[0];
brucewthomson 0:82297674d72d 234 }
brucewthomson 0:82297674d72d 235
brucewthomson 0:82297674d72d 236 uint16_t VL6180::VL6180_getRegister16bit(uint16_t reg_address)
brucewthomson 0:82297674d72d 237 {
brucewthomson 0:82297674d72d 238 char data[2];
brucewthomson 0:82297674d72d 239
brucewthomson 0:82297674d72d 240 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address
brucewthomson 0:82297674d72d 241 data[1] = reg_address & 0xFF; //LSB of register address
brucewthomson 0:82297674d72d 242 VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 2);
brucewthomson 0:82297674d72d 243 VL6180_error_no = i2c.read(VL6180_i2cAddress, data, 2, false);
brucewthomson 0:82297674d72d 244 return (data[0] + ((data[1] << 8) & 0xFF00));
brucewthomson 0:82297674d72d 245 }
brucewthomson 0:82297674d72d 246
brucewthomson 0:82297674d72d 247 void VL6180::VL6180_setRegister(uint16_t reg_address, uint8_t value)
brucewthomson 0:82297674d72d 248 {
brucewthomson 0:82297674d72d 249 char data[3];
brucewthomson 0:82297674d72d 250
brucewthomson 0:82297674d72d 251 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address
brucewthomson 0:82297674d72d 252 data[1] = reg_address & 0xFF; //LSB of register address
brucewthomson 0:82297674d72d 253 data[2] = value;
brucewthomson 0:82297674d72d 254 VL6180_error_no = VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 3);
brucewthomson 0:82297674d72d 255 }
brucewthomson 0:82297674d72d 256
brucewthomson 0:82297674d72d 257 void VL6180::VL6180_setRegister16bit(uint16_t reg_address, uint16_t value)
brucewthomson 0:82297674d72d 258 {
brucewthomson 0:82297674d72d 259 char data[4];
brucewthomson 0:82297674d72d 260
brucewthomson 0:82297674d72d 261 data[0] = (reg_address >> 8) & 0xFF; //MSB of register address
brucewthomson 0:82297674d72d 262 data[1] = reg_address & 0xFF; //LSB of register address
brucewthomson 0:82297674d72d 263 data[2] = value & 0xFF;
brucewthomson 0:82297674d72d 264 data[3] = ((value >> 8) & 0xFF);
brucewthomson 0:82297674d72d 265 VL6180_error_no = VL6180_error_no = i2c.write(VL6180_i2cAddress, data, 4);
brucewthomson 0:82297674d72d 266 }
brucewthomson 0:82297674d72d 267
brucewthomson 0:82297674d72d 268 int VL6180::writeSingleRegister( uint16_t reg_address, uint8_t data )
brucewthomson 0:82297674d72d 269 {
brucewthomson 0:82297674d72d 270
brucewthomson 0:82297674d72d 271 char data_write[3];
brucewthomson 0:82297674d72d 272 data_write[0] = (reg_address >> 8) & 0xFF; //MSB of register address
brucewthomson 0:82297674d72d 273 data_write[1] = reg_address & 0xFF; //LSB of register address
brucewthomson 0:82297674d72d 274 data_write[2] = data & 0xFF;
brucewthomson 0:82297674d72d 275 return i2c.write(VL6180_DEF_ADDR, data_write, 3);
brucewthomson 0:82297674d72d 276
brucewthomson 0:82297674d72d 277 // char tx[2] = { address | 160, data }; //0d160 = 0b10100000
brucewthomson 0:82297674d72d 278 // int ack = i2c.write( SLAVE_ADDRESS << 1, tx, 2 );
brucewthomson 0:82297674d72d 279 // return ack;
brucewthomson 0:82297674d72d 280 }