ST Expansion SW Team / Mbed 2 deprecated VL6180_MB2_4sensors_interrupts

Dependencies:   X_NUCLEO_6180 mbed

Committer:
charlesmn
Date:
Mon May 03 09:45:46 2021 +0000
Revision:
1:7e59bdb20309
Parent:
0:ed39e596d896
Sample program for the VL6180 ToF sensor. Runs up to 4 sensors. Use interrupt mode. MBed V2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:ed39e596d896 1 /**
charlesmn 0:ed39e596d896 2 ******************************************************************************
charlesmn 0:ed39e596d896 3 * File Name : main.c
charlesmn 1:7e59bdb20309 4 * Date : 21/10/2020 09:21:14
charlesmn 0:ed39e596d896 5 * Description : Main program body
charlesmn 0:ed39e596d896 6 ******************************************************************************
charlesmn 0:ed39e596d896 7 *
charlesmn 1:7e59bdb20309 8 * COPYRIGHT(c) 2020 STMicroelectronics
charlesmn 0:ed39e596d896 9 *
charlesmn 0:ed39e596d896 10 * Redistribution and use in source and binary forms, with or without modification,
charlesmn 0:ed39e596d896 11 * are permitted provided that the following conditions are met:
charlesmn 0:ed39e596d896 12 * 1. Redistributions of source code must retain the above copyright notice,
charlesmn 0:ed39e596d896 13 * this list of conditions and the following disclaimer.
charlesmn 0:ed39e596d896 14 * 2. Redistributions in binary form must reproduce the above copyright notice,
charlesmn 0:ed39e596d896 15 * this list of conditions and the following disclaimer in the documentation
charlesmn 0:ed39e596d896 16 * and/or other materials provided with the distribution.
charlesmn 0:ed39e596d896 17 * 3. Neither the name of STMicroelectronics nor the names of its contributors
charlesmn 0:ed39e596d896 18 * may be used to endorse or promote products derived from this software
charlesmn 0:ed39e596d896 19 * without specific prior written permission.
charlesmn 0:ed39e596d896 20 *
charlesmn 0:ed39e596d896 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
charlesmn 0:ed39e596d896 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
charlesmn 0:ed39e596d896 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
charlesmn 0:ed39e596d896 24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
charlesmn 0:ed39e596d896 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
charlesmn 0:ed39e596d896 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
charlesmn 0:ed39e596d896 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
charlesmn 0:ed39e596d896 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
charlesmn 0:ed39e596d896 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
charlesmn 0:ed39e596d896 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
charlesmn 0:ed39e596d896 31 *
charlesmn 0:ed39e596d896 32 ******************************************************************************
charlesmn 0:ed39e596d896 33
charlesmn 0:ed39e596d896 34 This program controls VL6180 ToF sensors running on an STM32F401 card with the
charlesmn 0:ed39e596d896 35 VL6180 shield and up to 3 VL6180 satelite boards. This program works in interrupt
charlesmn 0:ed39e596d896 36 mode with all 4 VL6180s operating at the same time.
charlesmn 0:ed39e596d896 37
charlesmn 0:ed39e596d896 38 Because this program is designed to run on MBed V2 the normal RTOS features
charlesmn 0:ed39e596d896 39 such as threads and the signalling between them don't exist. Because of this
charlesmn 0:ed39e596d896 40 the interupt routine signals the main program by setting flags, there is one to
charlesmn 0:ed39e596d896 41 signal that an interupt has been received from each VL6180. The mainloop then polls
charlesmn 0:ed39e596d896 42 these flags to know that an interrupt has occured.
charlesmn 0:ed39e596d896 43
charlesmn 0:ed39e596d896 44 The display is very crude with no storing of the last digits, each digit is written
charlesmn 0:ed39e596d896 45 and then a wait occurs and then the next digit is written. Tjis means that a lot of time is
charlesmn 0:ed39e596d896 46 taken writing tyhe display and any loong period when the display is not serviced
charlesmn 0:ed39e596d896 47 will cause the display to flicker.
charlesmn 0:ed39e596d896 48
charlesmn 0:ed39e596d896 49 In this program access to the VL6180 api is through wrapper functions in
charlesmn 0:ed39e596d896 50 vl6180_class.cpp. It is also possible to access the api directly. E.G both the lines below
charlesmn 0:ed39e596d896 51 do the same thing.
charlesmn 0:ed39e596d896 52
charlesmn 0:ed39e596d896 53 status = VL6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 54 status = sensor->vl6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 55 */
charlesmn 0:ed39e596d896 56
charlesmn 0:ed39e596d896 57 /* Includes ------------------------------------------------------------------*/
charlesmn 0:ed39e596d896 58 #include <stdio.h>
charlesmn 1:7e59bdb20309 59 #include <string.h>
charlesmn 1:7e59bdb20309 60 #include <stdlib.h>
charlesmn 1:7e59bdb20309 61 #include <stdio.h>
charlesmn 0:ed39e596d896 62
charlesmn 0:ed39e596d896 63 #include "mbed.h"
charlesmn 0:ed39e596d896 64 #include "XNucleo6810.h"
charlesmn 0:ed39e596d896 65 #include <time.h>
charlesmn 0:ed39e596d896 66
charlesmn 0:ed39e596d896 67 #include "spi_interface.h"
charlesmn 1:7e59bdb20309 68 #include "vl6180_api.h"
charlesmn 1:7e59bdb20309 69 #include "6180a1.h"
charlesmn 0:ed39e596d896 70
charlesmn 0:ed39e596d896 71
charlesmn 0:ed39e596d896 72 //VL6180_SINGLE_DEVICE_DRIVER
charlesmn 0:ed39e596d896 73
charlesmn 0:ed39e596d896 74 // i2c tx and rx pins
charlesmn 0:ed39e596d896 75 #define I2C_SDA D14
charlesmn 0:ed39e596d896 76 #define I2C_SCL D15
charlesmn 0:ed39e596d896 77
charlesmn 0:ed39e596d896 78 #define DigitDisplay_ms 1 /* ms each digit is kept on */
charlesmn 0:ed39e596d896 79
charlesmn 1:7e59bdb20309 80 #define NUM_SENSORS 4
charlesmn 1:7e59bdb20309 81
charlesmn 1:7e59bdb20309 82 // Define interrupt pins
charlesmn 1:7e59bdb20309 83 // The interrupt pins depend on solder blobs on the back of the shield.
charlesmn 1:7e59bdb20309 84 // Each interupt can have two possible pins, this allows all interrupts to be on the same gpio or different gpio
charlesmn 1:7e59bdb20309 85 // The first values are those an unmodified board has
charlesmn 1:7e59bdb20309 86 // see ST document UM2657 for more details
charlesmn 1:7e59bdb20309 87 PinName CentreIntPin = A3;
charlesmn 1:7e59bdb20309 88 PinName LeftIntPin = D13;
charlesmn 1:7e59bdb20309 89 PinName RightIntPin = D2;
charlesmn 1:7e59bdb20309 90 PinName BottomIntPin = A2;
charlesmn 1:7e59bdb20309 91 // alternate set
charlesmn 1:7e59bdb20309 92 //PinName CentreIntPin = A5;
charlesmn 1:7e59bdb20309 93 //PinName LeftIntPin = D8;
charlesmn 1:7e59bdb20309 94 //PinName RightIntPin = D4;
charlesmn 1:7e59bdb20309 95 //PinName BottomIntPin = A4;
charlesmn 0:ed39e596d896 96
charlesmn 0:ed39e596d896 97
charlesmn 1:7e59bdb20309 98 // flags that indicate an interrupt has occured
charlesmn 0:ed39e596d896 99 static int int_centre_result = 0;
charlesmn 0:ed39e596d896 100 static int int_left_result = 0;
charlesmn 0:ed39e596d896 101 static int int_right_result = 0;
charlesmn 0:ed39e596d896 102 static int int_bottom_result = 0;
charlesmn 0:ed39e596d896 103 static int int_result = 0;
charlesmn 0:ed39e596d896 104
charlesmn 0:ed39e596d896 105 void start_sensor(VL6180Dev_t dev ,VL6180 *sensor);
charlesmn 0:ed39e596d896 106 int get_sensor_data(VL6180Dev_t dev ,VL6180 *sensor);
charlesmn 0:ed39e596d896 107
charlesmn 0:ed39e596d896 108
charlesmn 0:ed39e596d896 109 class WaitForMeasurement {
charlesmn 0:ed39e596d896 110 public:
charlesmn 0:ed39e596d896 111
charlesmn 0:ed39e596d896 112
charlesmn 0:ed39e596d896 113 // this class services the interrupts from the ToF sensors.
charlesmn 0:ed39e596d896 114 // There is a limited amount you can do in an interrupt routine; printfs,mutexes break them among other things.
charlesmn 0:ed39e596d896 115 // We keep things simple by only raising a flag so all the real work is done outside the interrupt.
charlesmn 0:ed39e596d896 116 // This is designed around MBED V2 which doesn't have the RTOS features that would make this work nicely e.g. semaphores/queues.
charlesmn 0:ed39e596d896 117 WaitForMeasurement(): _interrupt(A1)
charlesmn 0:ed39e596d896 118 {
charlesmn 0:ed39e596d896 119 }
charlesmn 0:ed39e596d896 120
charlesmn 0:ed39e596d896 121
charlesmn 0:ed39e596d896 122 // constructor - Sensor is not used and can be removed
charlesmn 1:7e59bdb20309 123 WaitForMeasurement(PinName pin,int i2c_address) : _interrupt(pin) // create the InterruptIn on the pin specified to Counter
charlesmn 0:ed39e596d896 124 {
charlesmn 0:ed39e596d896 125 int_result = 1;
charlesmn 1:7e59bdb20309 126 i2c_addr = i2c_address;
charlesmn 0:ed39e596d896 127 _interrupt.rise(callback(this, &WaitForMeasurement::got_interrupt)); // attach increment function of this counter instance
charlesmn 0:ed39e596d896 128
charlesmn 0:ed39e596d896 129 }
charlesmn 0:ed39e596d896 130
charlesmn 0:ed39e596d896 131 // function is called every time an interupt is seen. A flag is raised which allows the main routine to service the interupt.
charlesmn 0:ed39e596d896 132 void got_interrupt()
charlesmn 0:ed39e596d896 133 {
charlesmn 1:7e59bdb20309 134 if (i2c_addr == NEW_SENSOR_CENTRE_ADDRESS)
charlesmn 0:ed39e596d896 135 int_centre_result = 1; //flag to main that interrupt happened
charlesmn 1:7e59bdb20309 136 if (i2c_addr == NEW_SENSOR_LEFT_ADDRESS)
charlesmn 0:ed39e596d896 137 int_left_result = 1; //flag to main that interrupt happened
charlesmn 1:7e59bdb20309 138 if (i2c_addr == NEW_SENSOR_RIGHT_ADDRESS)
charlesmn 0:ed39e596d896 139 int_right_result = 1; //flag to main that interrupt happened
charlesmn 1:7e59bdb20309 140 if (i2c_addr == NEW_SENSOR_BOTTOM_ADDRESS)
charlesmn 0:ed39e596d896 141 int_bottom_result = 1; //flag to main that interrupt happened
charlesmn 1:7e59bdb20309 142 }
charlesmn 0:ed39e596d896 143
charlesmn 0:ed39e596d896 144 //destructor
charlesmn 0:ed39e596d896 145 ~WaitForMeasurement()
charlesmn 0:ed39e596d896 146 {
charlesmn 0:ed39e596d896 147 printf("destruction \n");
charlesmn 0:ed39e596d896 148 }
charlesmn 0:ed39e596d896 149
charlesmn 0:ed39e596d896 150 private:
charlesmn 0:ed39e596d896 151 InterruptIn _interrupt;
charlesmn 0:ed39e596d896 152 int status;
charlesmn 1:7e59bdb20309 153 int i2c_addr;
charlesmn 0:ed39e596d896 154
charlesmn 0:ed39e596d896 155 };
charlesmn 0:ed39e596d896 156
charlesmn 0:ed39e596d896 157
charlesmn 0:ed39e596d896 158
charlesmn 0:ed39e596d896 159
charlesmn 0:ed39e596d896 160 MyVL6180Dev_t devCentre; //data for each of the vl6180
charlesmn 0:ed39e596d896 161 MyVL6180Dev_t devLeft;
charlesmn 0:ed39e596d896 162 MyVL6180Dev_t devRight;
charlesmn 0:ed39e596d896 163 MyVL6180Dev_t devBottom;
charlesmn 0:ed39e596d896 164 VL6180Dev_t Dev = &devCentre; // the currently used vl6180
charlesmn 0:ed39e596d896 165
charlesmn 0:ed39e596d896 166 volatile int IntrFired=0;
charlesmn 0:ed39e596d896 167
charlesmn 0:ed39e596d896 168 VL6180 *Sensor;
charlesmn 0:ed39e596d896 169
charlesmn 0:ed39e596d896 170 static XNucleo53L1A1 *board=NULL;
charlesmn 0:ed39e596d896 171
charlesmn 1:7e59bdb20309 172 // MBed V6.4 has renamed wait_ms and UnbufferedSerial replaces Serial
charlesmn 1:7e59bdb20309 173 #if (MBED_VERSION > 60300)
charlesmn 1:7e59bdb20309 174 UnbufferedSerial pc(SERIAL_TX, SERIAL_RX);
charlesmn 1:7e59bdb20309 175 extern "C" void wait_ms(int ms);
charlesmn 1:7e59bdb20309 176 #else
charlesmn 0:ed39e596d896 177 Serial pc(SERIAL_TX, SERIAL_RX);
charlesmn 1:7e59bdb20309 178 #endif
charlesmn 0:ed39e596d896 179
charlesmn 0:ed39e596d896 180 vl6180_DevI2C *dev_I2C = new vl6180_DevI2C(I2C_SDA, I2C_SCL);
charlesmn 0:ed39e596d896 181
charlesmn 0:ed39e596d896 182
charlesmn 1:7e59bdb20309 183 #define theVL6180Dev 0x52 //the address of a sensor on power up
charlesmn 0:ed39e596d896 184
charlesmn 0:ed39e596d896 185 #define i2c_bus (&hi2c1)
charlesmn 0:ed39e596d896 186 #define def_i2c_time_out 100
charlesmn 0:ed39e596d896 187
charlesmn 1:7e59bdb20309 188 static char DISP_CurString[10]; // used to store what is to be displayed on the display
charlesmn 0:ed39e596d896 189
charlesmn 0:ed39e596d896 190 VL6180_RangeData_t Range; /* Range measurmeent */
charlesmn 0:ed39e596d896 191 uint16_t range; /* range average distance */
charlesmn 0:ed39e596d896 192
charlesmn 0:ed39e596d896 193
charlesmn 0:ed39e596d896 194 int main(void)
charlesmn 0:ed39e596d896 195 {
charlesmn 0:ed39e596d896 196
charlesmn 0:ed39e596d896 197 WaitForMeasurement* int1; // the interrupt handler
charlesmn 0:ed39e596d896 198 WaitForMeasurement* int2; // the interrupt handler
charlesmn 0:ed39e596d896 199 WaitForMeasurement* int3; // the interrupt handler
charlesmn 0:ed39e596d896 200 WaitForMeasurement* int4; // the interrupt handler
charlesmn 0:ed39e596d896 201
charlesmn 0:ed39e596d896 202 pc.baud(115200); // baud rate is important as printf statements take a lot of time
charlesmn 1:7e59bdb20309 203
charlesmn 1:7e59bdb20309 204 printf("Interrupt 4 sensors mbed = %d \r\n",MBED_VERSION);
charlesmn 0:ed39e596d896 205
charlesmn 0:ed39e596d896 206 //create I2C channel
charlesmn 0:ed39e596d896 207 vl6180_DevI2C *dev_I2C = new vl6180_DevI2C(I2C_SDA, I2C_SCL);
charlesmn 0:ed39e596d896 208
charlesmn 0:ed39e596d896 209 int status;
charlesmn 0:ed39e596d896 210
charlesmn 0:ed39e596d896 211 // create instances for the sensors
charlesmn 1:7e59bdb20309 212 board = XNucleo53L1A1::instance(dev_I2C, CentreIntPin, LeftIntPin, RightIntPin ,BottomIntPin);
charlesmn 0:ed39e596d896 213 // find the sensors we have and initialise
charlesmn 0:ed39e596d896 214 status = board->init_board();
charlesmn 0:ed39e596d896 215 if (status) {
charlesmn 0:ed39e596d896 216 printf("Failed to init board!\r\n");
charlesmn 0:ed39e596d896 217 return 0;
charlesmn 0:ed39e596d896 218 }
charlesmn 0:ed39e596d896 219
charlesmn 0:ed39e596d896 220
charlesmn 0:ed39e596d896 221 //select centre sensor
charlesmn 0:ed39e596d896 222 if (board->sensor_centre != NULL ) {
charlesmn 0:ed39e596d896 223 devCentre.i2c_addr = NEW_SENSOR_CENTRE_ADDRESS;
charlesmn 1:7e59bdb20309 224 int1 = new WaitForMeasurement(CentreIntPin,NEW_SENSOR_CENTRE_ADDRESS); // create a interrupt class for this interrupt pin
charlesmn 1:7e59bdb20309 225 start_sensor(&devCentre ,board->sensor_centre);
charlesmn 0:ed39e596d896 226 }
charlesmn 0:ed39e596d896 227
charlesmn 0:ed39e596d896 228 if (board->sensor_left != NULL ) {
charlesmn 0:ed39e596d896 229 devLeft.i2c_addr = NEW_SENSOR_LEFT_ADDRESS;
charlesmn 1:7e59bdb20309 230 int2 = new WaitForMeasurement(LeftIntPin,NEW_SENSOR_LEFT_ADDRESS); // create a interrupt class for this interrupt pin
charlesmn 1:7e59bdb20309 231 start_sensor(&devLeft ,board->sensor_left);
charlesmn 0:ed39e596d896 232 }
charlesmn 0:ed39e596d896 233
charlesmn 0:ed39e596d896 234 if (board->sensor_right != NULL ) {
charlesmn 0:ed39e596d896 235 devRight.i2c_addr = NEW_SENSOR_RIGHT_ADDRESS;
charlesmn 1:7e59bdb20309 236 int2 = new WaitForMeasurement(RightIntPin,NEW_SENSOR_RIGHT_ADDRESS); // create a interrupt class for this interrupt pin
charlesmn 1:7e59bdb20309 237 start_sensor(&devRight ,board->sensor_right);
charlesmn 0:ed39e596d896 238 }
charlesmn 0:ed39e596d896 239
charlesmn 1:7e59bdb20309 240 if (board->sensor_bottom != NULL ) {
charlesmn 0:ed39e596d896 241 devBottom.i2c_addr = NEW_SENSOR_BOTTOM_ADDRESS;
charlesmn 1:7e59bdb20309 242 int2 = new WaitForMeasurement(BottomIntPin,NEW_SENSOR_BOTTOM_ADDRESS); // create a interrupt class for this interrupt pin
charlesmn 1:7e59bdb20309 243 start_sensor(&devBottom ,board->sensor_bottom);
charlesmn 0:ed39e596d896 244 }
charlesmn 0:ed39e596d896 245
charlesmn 0:ed39e596d896 246
charlesmn 0:ed39e596d896 247
charlesmn 0:ed39e596d896 248 /* Infinite loop */
charlesmn 0:ed39e596d896 249 while (1) {
charlesmn 1:7e59bdb20309 250
charlesmn 1:7e59bdb20309 251 // process interrupts
charlesmn 0:ed39e596d896 252 if ( int_centre_result == 1 )
charlesmn 0:ed39e596d896 253 {
charlesmn 0:ed39e596d896 254 int_centre_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 255 Dev = &devCentre;
charlesmn 0:ed39e596d896 256 Sensor=board->sensor_centre;
charlesmn 0:ed39e596d896 257
charlesmn 0:ed39e596d896 258 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 259 if ( result != 0)
charlesmn 0:ed39e596d896 260 printf("C %d \n",result);
charlesmn 0:ed39e596d896 261 }
charlesmn 0:ed39e596d896 262
charlesmn 0:ed39e596d896 263 if ( int_left_result == 1 )
charlesmn 0:ed39e596d896 264 {
charlesmn 0:ed39e596d896 265 int_left_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 266 Dev = &devLeft;
charlesmn 0:ed39e596d896 267 Sensor=board->sensor_left;
charlesmn 0:ed39e596d896 268
charlesmn 0:ed39e596d896 269 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 270 if ( result != 0)
charlesmn 0:ed39e596d896 271 printf("L %d \n",result);
charlesmn 0:ed39e596d896 272 }
charlesmn 0:ed39e596d896 273
charlesmn 0:ed39e596d896 274 if ( int_right_result == 1 )
charlesmn 0:ed39e596d896 275 {
charlesmn 0:ed39e596d896 276 int_right_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 277 Dev = &devRight;
charlesmn 0:ed39e596d896 278 Sensor=board->sensor_right;
charlesmn 0:ed39e596d896 279
charlesmn 0:ed39e596d896 280 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 281 if ( result != 0)
charlesmn 0:ed39e596d896 282 printf("R %d \n",result);
charlesmn 0:ed39e596d896 283 }
charlesmn 0:ed39e596d896 284
charlesmn 0:ed39e596d896 285 if ( int_bottom_result == 1 )
charlesmn 0:ed39e596d896 286 {
charlesmn 0:ed39e596d896 287 int_bottom_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 288 Dev = &devBottom;
charlesmn 0:ed39e596d896 289 Sensor=board->sensor_bottom;
charlesmn 0:ed39e596d896 290
charlesmn 0:ed39e596d896 291 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 292 if ( result != 0)
charlesmn 0:ed39e596d896 293 printf("B %d \n",result);
charlesmn 0:ed39e596d896 294 }
charlesmn 0:ed39e596d896 295
charlesmn 0:ed39e596d896 296
charlesmn 0:ed39e596d896 297 // the display is very simple and requires written to frequently so
charlesmn 0:ed39e596d896 298 // we are writing to the display when we would normally sleep.
charlesmn 0:ed39e596d896 299 // when we are not writing to the display it is blank
charlesmn 0:ed39e596d896 300 {
charlesmn 0:ed39e596d896 301 for (int i = 0 ;i < 10;i++)
charlesmn 0:ed39e596d896 302 { // write to display
charlesmn 0:ed39e596d896 303 XNUCLEO6180XA1_DisplayString(DISP_CurString, DigitDisplay_ms* 5);
charlesmn 0:ed39e596d896 304 }
charlesmn 0:ed39e596d896 305 }
charlesmn 0:ed39e596d896 306
charlesmn 0:ed39e596d896 307 }
charlesmn 0:ed39e596d896 308 }
charlesmn 0:ed39e596d896 309
charlesmn 0:ed39e596d896 310
charlesmn 1:7e59bdb20309 311 // start a sensor
charlesmn 0:ed39e596d896 312 void start_sensor(VL6180Dev_t dev ,VL6180 *sensor)
charlesmn 0:ed39e596d896 313 {
charlesmn 0:ed39e596d896 314
charlesmn 0:ed39e596d896 315 /* Note that if we waited 1msec we could bypass VL6180_WaitDeviceBooted(&Dev); */
charlesmn 0:ed39e596d896 316 int status;
charlesmn 0:ed39e596d896 317 status = sensor->vl6180_WaitDeviceBooted(dev);
charlesmn 0:ed39e596d896 318 printf("vl6180_WaitDeviceBooted %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 319 status = sensor->vl6180_InitData(dev);
charlesmn 0:ed39e596d896 320 printf("vl6180_InitData %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 321
charlesmn 0:ed39e596d896 322 status = sensor->vl6180_FilterSetState(dev,0); // disbale as not effective in continuous mose
charlesmn 0:ed39e596d896 323 printf("vl6180_FilterSetState %d \n",status);
charlesmn 0:ed39e596d896 324 status = sensor->vl6180_Prepare(dev); // sensor init
charlesmn 0:ed39e596d896 325 printf("vl6180_Prepare %d \n",status);
charlesmn 0:ed39e596d896 326
charlesmn 0:ed39e596d896 327 status = sensor->vl6180_UpscaleSetScaling(dev, 2); // set scaling by 2 to get ranging in range 0 to 400mm
charlesmn 0:ed39e596d896 328 printf("vl6180_UpscaleSetScaling %d \n",status);
charlesmn 0:ed39e596d896 329
charlesmn 0:ed39e596d896 330 // if slow reaction is enough then set a high time like 100 ms (up to 2550 msec)
charlesmn 0:ed39e596d896 331 // if fastest reaction is required then set 0 that will set minimal possible
charlesmn 0:ed39e596d896 332 status = sensor->vl6180_RangeSetInterMeasPeriod(dev, 100);
charlesmn 0:ed39e596d896 333 printf("vl6180_RangeSetInterMeasPeriod %d \n",status);
charlesmn 0:ed39e596d896 334 // set vl6180x gpio1 pin to range interrupt output with high polarity (rising edge)
charlesmn 0:ed39e596d896 335 status = sensor->vl6180_SetupGPIO1(dev, GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT, INTR_POL_HIGH);
charlesmn 0:ed39e596d896 336 printf("vl6180_SetupGPIO1 %d \n",status);
charlesmn 0:ed39e596d896 337 // set range interrupt reporting to low threshold
charlesmn 0:ed39e596d896 338 status = sensor->vl6180_RangeConfigInterrupt(dev, CONFIG_GPIO_INTERRUPT_LEVEL_LOW);
charlesmn 0:ed39e596d896 339 printf("vl6180_RangeConfigInterrupt %d \n",status);
charlesmn 0:ed39e596d896 340 // we don't care of high threshold as we don't use it , group hold is managed externaly
charlesmn 0:ed39e596d896 341 status = sensor->vl6180_RangeSetThresholds(dev, 100, 00, 0);
charlesmn 0:ed39e596d896 342 printf("vl6180_RangeSetThresholds %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 343
charlesmn 0:ed39e596d896 344 status = sensor->vl6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 345 printf("vl6180_ClearInterrupt %d \n",status);
charlesmn 0:ed39e596d896 346
charlesmn 0:ed39e596d896 347 status = sensor->vl6180_RangeStartContinuousMode(dev);
charlesmn 0:ed39e596d896 348 printf("vl6180_RangeStartContinuousMode %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 349 }
charlesmn 0:ed39e596d896 350
charlesmn 0:ed39e596d896 351
charlesmn 0:ed39e596d896 352 int get_sensor_data(VL6180Dev_t dev ,VL6180 *sensor)
charlesmn 0:ed39e596d896 353 {
charlesmn 0:ed39e596d896 354 int status;
charlesmn 0:ed39e596d896 355 int result = 0;
charlesmn 0:ed39e596d896 356 status = sensor->vl6180_RangeGetMeasurement(dev, &Range);
charlesmn 0:ed39e596d896 357 if( status == 0 ){
charlesmn 0:ed39e596d896 358 // Application must check Range.errorStatus before accessing the other data
charlesmn 0:ed39e596d896 359 // If Range.errorStatus is DataNotReady, application knows that it has to wait a bit before getting a new data
charlesmn 0:ed39e596d896 360 // If Range.errorStatus is 0, application knows it is a valid distance
charlesmn 0:ed39e596d896 361 // If Range.errorStatus is not 0, application knows that reported distance is invalid so may take some decisions depending on the errorStatus
charlesmn 0:ed39e596d896 362 if (Range.errorStatus == DataNotReady){
charlesmn 0:ed39e596d896 363 printf("notready \n");
charlesmn 0:ed39e596d896 364
charlesmn 0:ed39e596d896 365 return result;
charlesmn 0:ed39e596d896 366 }
charlesmn 0:ed39e596d896 367
charlesmn 1:7e59bdb20309 368 // only display the centre sensors values. All sensors values and printed out
charlesmn 0:ed39e596d896 369 if((Range.errorStatus == 0) && (status == 0))
charlesmn 0:ed39e596d896 370 {
charlesmn 0:ed39e596d896 371 // only display the centre sensors values
charlesmn 0:ed39e596d896 372 if ( dev->i2c_addr == NEW_SENSOR_CENTRE_ADDRESS )
charlesmn 0:ed39e596d896 373 {
charlesmn 0:ed39e596d896 374 sprintf(DISP_CurString, " %d", (int)Range.range_mm);
charlesmn 0:ed39e596d896 375 }
charlesmn 0:ed39e596d896 376 result = (int)Range.range_mm;
charlesmn 0:ed39e596d896 377 }
charlesmn 0:ed39e596d896 378 else
charlesmn 0:ed39e596d896 379 {
charlesmn 0:ed39e596d896 380 // only display the centre sensors values
charlesmn 0:ed39e596d896 381 if ( dev->i2c_addr == NEW_SENSOR_CENTRE_ADDRESS )
charlesmn 0:ed39e596d896 382 {
charlesmn 0:ed39e596d896 383 sprintf(DISP_CurString, " %4d", 0);
charlesmn 0:ed39e596d896 384 }
charlesmn 0:ed39e596d896 385 result = 0;
charlesmn 0:ed39e596d896 386 }
charlesmn 0:ed39e596d896 387
charlesmn 0:ed39e596d896 388
charlesmn 0:ed39e596d896 389 /* re-arm next measurement */
charlesmn 0:ed39e596d896 390 sensor->vl6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 391
charlesmn 0:ed39e596d896 392 } // status != 0
charlesmn 0:ed39e596d896 393 else{
charlesmn 0:ed39e596d896 394 // it is an critical error
charlesmn 0:ed39e596d896 395 // HandleError("critical error on VL6180x_RangeCheckAndGetMeasurement");
charlesmn 0:ed39e596d896 396 }
charlesmn 0:ed39e596d896 397 return result;
charlesmn 0:ed39e596d896 398
charlesmn 0:ed39e596d896 399 }
charlesmn 0:ed39e596d896 400
charlesmn 0:ed39e596d896 401
charlesmn 1:7e59bdb20309 402 // wait_ms was removed in MBed V6.4
charlesmn 1:7e59bdb20309 403 #if (MBED_VERSION > 60300)
charlesmn 1:7e59bdb20309 404 void wait_ms(int ms)
charlesmn 1:7e59bdb20309 405 {
charlesmn 1:7e59bdb20309 406 thread_sleep_for(ms);
charlesmn 1:7e59bdb20309 407 }
charlesmn 1:7e59bdb20309 408 #endif
charlesmn 1:7e59bdb20309 409
charlesmn 1:7e59bdb20309 410
charlesmn 0:ed39e596d896 411 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/