Kenji Arai / VL53L0X_simple

Dependents:   Check_VL53L0X_simple_with_three_ToF Check_VL53L0X_simple_ToF_Sensor Check_VL53L0X_simple_with_three_ToF Check_VL53L0X_simple_ToF_Sensor ... more

Fork of VL53L0X by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VL53L0X.h Source File

VL53L0X.h

00001 /*******************************************************************************
00002  Copyright © 2016, STMicroelectronics International N.V.
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without
00006  modification, are permitted provided that the following conditions are met:
00007  * Redistributions of source code must retain the above copyright
00008  notice, this list of conditions and the following disclaimer.
00009  * Redistributions in binary form must reproduce the above copyright
00010  notice, this list of conditions and the following disclaimer in the
00011  documentation and/or other materials provided with the distribution.
00012  * Neither the name of STMicroelectronics nor the
00013  names of its contributors may be used to endorse or promote products
00014  derived from this software without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
00019  NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
00020  IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
00021  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  *****************************************************************************/
00028 
00029 #ifndef __VL53L0X_CLASS_H
00030 #define __VL53L0X_CLASS_H
00031 
00032 //------- Feburary 6th, 2018 by JH1PJL / K.Arai --------------------------------
00033 //------- Updated on Feburary 26th, 2020 ---------------------------------------
00034 //ORIGINAL=1 does NOT mean anything but just keep original source code as it is!
00035 //You can NOT compile with ORIGINAL=1 !!
00036 #define     ORIGINAL        0   // Just keep = 0
00037 #define     USE_I2C_2V8
00038 //------------------------------------------------------------------------------
00039 
00040 #if ORIGINAL
00041 #ifdef _MSC_VER
00042 #   ifdef VL53L0X_API_EXPORTS
00043 #       define VL53L0X_API  __declspec(dllexport)
00044 #   else
00045 #       define VL53L0X_API
00046 #   endif
00047 #else
00048 #   define VL53L0X_API
00049 #endif
00050 #endif
00051 
00052 /* Includes ------------------------------------------------------------------*/
00053 #include "mbed.h"
00054 #if ORIGINAL
00055 #include "RangeSensor.h"
00056 #include "DevI2C.h"
00057 #include "PinNames.h"
00058 #endif
00059 #include "VL53L0X_def.h"
00060 #include "VL53L0X_platform.h"
00061 #if ORIGINAL
00062 #include "Stmpe1600.h"
00063 #endif
00064 
00065 #if !ORIGINAL
00066 //------- Feburary 4th, 2018 by JH1PJL / K.Arai --------------------------------
00067 //  moved to following header file
00068 #include "VL53L0X_1st.h"
00069 //------------------------------------------------------------------------------
00070 #endif
00071 
00072 /* sensor operating modes */
00073 typedef enum {
00074     range_single_shot_polling = 1,
00075     range_continuous_polling,
00076     range_continuous_interrupt,
00077     range_continuous_polling_low_threshold,
00078     range_continuous_polling_high_threshold,
00079     range_continuous_polling_out_of_window,
00080     range_continuous_interrupt_low_threshold,
00081     range_continuous_interrupt_high_threshold,
00082     range_continuous_interrupt_out_of_window,
00083 } OperatingMode;
00084 
00085 #if !ORIGINAL
00086 /* sensor range profiles */
00087 typedef enum {
00088     range_long_distance_33ms_200cm = 1,
00089     range_hi_accurate_200ms_120cm,
00090     range_hi_speed_20ms_120cm,
00091 } RangeProfile;
00092 #endif
00093 
00094 /** default device address */
00095 #if ORIGINAL
00096 #define VL53L0X_DEFAULT_ADDRESS     0x52 /* (8-bit) */
00097 #else
00098 // No other choice
00099 #define VL53L0X_DEFAULT_ADDRESS 0x52 // 8-bit(0x53/Read & 0x52?Write) 0x29(7bit)
00100 #endif
00101 
00102 #if !ORIGINAL
00103 #if (MBED_MAJOR_VERSION == 2)
00104 #define WAIT_MS(x)              wait_ms(x)
00105 #define VL53L0X_OsDelay(...)    wait_ms(2)
00106 #elif (MBED_MAJOR_VERSION == 5)
00107 #define WAIT_MS(x)              ThisThread::sleep_for(x)
00108 #define VL53L0X_OsDelay(...)    ThisThread::sleep_for(2)
00109 #else
00110 #warning "I cannot control wait_ms()!!"
00111 #endif
00112 #endif  // !ORIGINAL
00113 
00114 #if !ORIGINAL
00115 
00116 //--------------- Simple debug -------------------------------------------------
00117 //extern DigitalOut myled;
00118 //------------------------------------------------------------------------------
00119 
00120 /** Interface for STMicronics VL53L0X
00121  *  World smallest Time-of-Flight (ToF) ranging sensor
00122  *
00123  * @code
00124  * #include "mbed.h"
00125  *
00126  * // I2C Communication
00127  * VL53L0X      sensor(I2C_SDA, I2C_SCL, D8);   // SDA, SCL & XSHUT
00128  * // If you connected I2C line not only this device but also other devices,
00129  * //     you need to declare following method.
00130  * I2C          i2c(I2C_SDA, I2C_SCL);
00131  * VL53L0X      sensor(i2c, D8);                // I2C, XSHUT
00132  *
00133  * int main()
00134  * {
00135  *     int status = VL53L0X_ERROR_NONE;
00136  *     uint32_t data;
00137  *
00138  *     status = sensor.init_sensor(0x33<<1U); //new addres(not equal others)
00139  *     status = sensor.set_mode(range_long_distance_33ms_200cm);
00140  *     //status = sensor.set_mode(range_hi_accurate_200ms_120cm);
00141  *     //status = sensor.set_mode(range_hi_speed_20ms_120cm);
00142  *     while (true) {
00143  *         status = sensor.get_distance(&data);
00144  *         if (status == VL53L0X_ERROR_NONE) {
00145  *             printf("%5d\r\n", data);
00146  *         } else {
00147  *             printf("error\r\n");
00148  *         }
00149  *     }
00150  * }
00151  * @endcode
00152  */
00153 
00154 
00155 /* Classes -------------------------------------------------------------------*/
00156 /** Class representing a VL53L0 sensor component
00157  */
00158 class VL53L0X
00159 {
00160 public:
00161     /** Constructor
00162      * @param[in] &i2c device I2C to be used for communication
00163      * @param[in] pin Mbed DigitalInOut PinName to be used for XSHUT
00164      * @param[in] &pin_gpio1 pin Mbed InterruptIn PinName
00165      *             to be used as component GPIO_1 INT
00166      */
00167     VL53L0X(I2C& i2c, PinName xshut, PinName pin_gpio1) : _i2c(i2c),
00168         _gpio0(xshut)
00169     {
00170         _gpio1Int = NULL;
00171         preparation();
00172     }
00173 
00174     /** Constructor 2 (another simple way)
00175      * @param[in] Pin for I2C SDA & SDL
00176      * @param[in] pin Mbed DigitalInOut PinName to be used for XSHUT
00177      */
00178     VL53L0X(PinName p_sda, PinName p_scl, PinName xshut)
00179         : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p), _gpio0(xshut) {
00180         _gpio1Int = NULL;
00181         preparation();
00182     }
00183 
00184     /** Constructor 3 (another simple way)
00185      * @param[in] &i2c device I2C to be used for communication
00186      * @param[in] pin Mbed DigitalInOut PinName to be used for XSHUT
00187      */
00188     VL53L0X(I2C& p_i2c, PinName xshut) : _i2c(p_i2c), _gpio0(xshut) {
00189         _gpio1Int = NULL;
00190         preparation();
00191     }
00192 
00193     /** Destructor
00194      */
00195     virtual ~VL53L0X()
00196     {
00197         if (_gpio1Int != NULL) {
00198             delete _gpio1Int;
00199         }
00200     }
00201 #else
00202 #warning "please recover original constractor form VL53L0X_header_original.txt"
00203 #endif
00204 
00205     /*** Interface Methods ***/
00206     /*** High level API ***/
00207 #if !ORIGINAL
00208     /**
00209      * @brief       initialize
00210      * @return      void
00211      */
00212     /* turns on the sensor */
00213     void preparation(void)
00214     {
00215         _my_device.I2cDevAddr  = VL53L0X_DEFAULT_ADDRESS;
00216         _my_device.comms_type  = 1; // VL53L0X_COMMS_I2C
00217         _my_device.comms_speed_khz  = 400;
00218         _device = &_my_device;
00219         _range_mode = range_long_distance_33ms_200cm;
00220         VL53L0X_off();
00221     }
00222 #endif
00223 
00224     /**
00225      * @brief       PowerOn the sensor
00226      * @return      void
00227      */
00228     /* turns on the sensor */
00229     void VL53L0X_on(void)
00230     {
00231 #if ORIGINAL
00232         if (_gpio0) {
00233             *_gpio0 = 1;
00234         } else {
00235             if (_expgpio0) {
00236                 *_expgpio0 = 1;
00237             }
00238         }
00239         wait_ms(10);
00240 #else
00241         if (_gpio0.is_connected()){
00242             _gpio0.output();
00243             _gpio0 = 1;
00244             _gpio0.input();
00245         }
00246         WAIT_MS(1);
00247 #endif
00248     }
00249 
00250     /**
00251      * @brief       PowerOff the sensor
00252      * @return      void
00253      */
00254     /* turns off the sensor */
00255     void VL53L0X_off(void)
00256     {
00257 #if ORIGINAL
00258         if (_gpio0) {
00259             *_gpio0 = 0;
00260         } else {
00261             if (_expgpio0) {
00262                 *_expgpio0 = 0;
00263             }
00264         }
00265         wait_ms(10);
00266 #else
00267         if (_gpio0.is_connected()){
00268             _gpio0 = 0;
00269             _gpio0.output();
00270         }
00271         WAIT_MS(10);
00272 #endif
00273     }
00274 
00275     /**
00276      * @brief       Initialize the sensor with default values
00277      * @param[in]   new I2C address
00278      * @return      "0" on success
00279      */
00280     int init_sensor(uint8_t new_addr);
00281 
00282 #if !ORIGINAL
00283     /**
00284      * @brief       Start the measure by single shot operating mode
00285      * @param[in]   operating mode
00286      * @return      "0" on success
00287      */
00288     int set_mode(RangeProfile range_mode) {
00289         _range_mode = range_mode;
00290         return start_measurement(range_single_shot_polling, NULL);
00291     }
00292 
00293     /**
00294      * @brief Get ranging result and only that
00295      *
00296      * @par Function Description
00297      * Unlike @a VL53L0X_get_ranging_measurement_data()
00298      * this function only retrieves the range in millimeter \n
00299      * It does any required up-scale translation\n
00300      * It can be called after success status polling or in interrupt mode \n
00301      * @warning these function is not doing wrap around filtering \n
00302      * This function doesn't perform any data ready check!
00303      *
00304      * @param p_data  Pointer to range distance
00305      * @return        "0" on success
00306      */
00307     virtual int get_distance(uint32_t *p_data)
00308     {
00309         int status = 0;
00310         VL53L0X_RangingMeasurementData_t p_ranging_measurement_data;
00311 
00312 #if ORIGINAL
00313         status = start_measurement(range_single_shot_polling, NULL);
00314 #else
00315         status = VL53L0X_start_measurement(_device);
00316 #endif
00317         if (!status) {
00318             status = get_measurement(range_single_shot_polling,
00319                                      &p_ranging_measurement_data);
00320         }
00321         if (p_ranging_measurement_data.RangeStatus == 0) {
00322             // we have a valid range.
00323             *p_data = p_ranging_measurement_data.RangeMilliMeter;
00324         } else {
00325             *p_data = 0;
00326             status = VL53L0X_ERROR_RANGE_ERROR;
00327         }
00328         stop_measurement(range_single_shot_polling);
00329         return status;
00330     }
00331 #endif
00332 
00333 #if !ORIGINAL
00334 //------- Feburary 4th, 2018 by JH1PJL / K.Arai --------------------------------
00335 //  moved to following header file
00336 #include "VL53L0X_2nd.h"
00337 //------------------------------------------------------------------------------
00338 #else
00339 #warning "please recover original functions form VL53L0X_2nd.h"
00340 #endif
00341 
00342 private:
00343 
00344 #if !ORIGINAL
00345 //------- Feburary 4th, 2018 by JH1PJL / K.Arai --------------------------------
00346 //  moved to following header file
00347 #include "VL53L0X_3rd.h"
00348 //------------------------------------------------------------------------------
00349 #else
00350 #warning "please recover original functions form VL53L0X_3rd.h"
00351 #endif
00352 #if !ORIGINAL
00353     static const unsigned int TEMP_BUF_SIZE = 32;
00354 
00355     int i2c_write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr,
00356                   uint16_t NumByteToWrite) {
00357         int ret;
00358         uint8_t tmp[TEMP_BUF_SIZE];
00359 
00360         if(NumByteToWrite >= TEMP_BUF_SIZE) return -2;
00361         /* First, send device address. Then, send data and STOP condition */
00362         tmp[0] = RegisterAddr;
00363         memcpy(tmp+1, pBuffer, NumByteToWrite);
00364         ret = _i2c.write(DeviceAddr, (const char*)tmp, NumByteToWrite+1, false);
00365         if(ret) return -1;
00366         return 0;
00367     }
00368 
00369     int i2c_read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr,
00370                  uint16_t NumByteToRead) {
00371         int ret;
00372 
00373         //--debug--
00374         //myled = 1;
00375         /* Send device address, with no STOP condition */
00376         ret = _i2c.write(DeviceAddr, (const char*)&RegisterAddr, 1, true);
00377         //--debug--
00378         //myled = 0;
00379         if(!ret) {
00380             /* Read data, with STOP condition  */
00381             ret = _i2c.read(DeviceAddr, (char*)pBuffer, NumByteToRead, false);
00382         }
00383         if(ret) return -1;
00384         return 0;
00385     }
00386 #endif
00387 
00388     VL53L0X_DeviceInfo_t _device_info;
00389 
00390 #if !ORIGINAL
00391     RangeProfile _range_mode;
00392 #endif
00393 
00394 #if ORIGINAL
00395     /* IO Device */
00396     DevI2C *_dev_i2c;
00397     /* Digital out pin */
00398     DigitalOut *_gpio0;
00399     /* GPIO expander */
00400     Stmpe1600DigiOut *_expgpio0;
00401 #else
00402     /* IO Device */
00403     I2C     *_i2c_p;
00404     I2C     &_i2c;
00405     /* Digital in and out pin */
00406     DigitalInOut _gpio0;
00407 #endif
00408     /* Measure detection IRQ */
00409     InterruptIn *_gpio1Int;
00410     /* Device data */
00411     VL53L0X_Dev_t _my_device;
00412     VL53L0X_DEV _device;
00413 };
00414 
00415 #endif /* _VL53L0X_CLASS_H_ */