ST Expansion SW Team / Mbed OS VL6180_MB5_1sensor_singleshot_poll

Dependencies:   X_NUCLEO_6180

Committer:
charlesmn
Date:
Mon May 03 16:28:21 2021 +0000
Revision:
1:860eb432852b
Parent:
0:d531d84af4c9
This program controls a VL6180 ToF sensor running on an STM32F401 card with the VL6180 shield. It works in single shot mode where the program polls for the measurement. Result is outputted to the Screen. MBed V5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:d531d84af4c9 1 /**
charlesmn 0:d531d84af4c9 2 ******************************************************************************
charlesmn 0:d531d84af4c9 3 * File Name : main.c
charlesmn 0:d531d84af4c9 4 * Date : 29/10/2020
charlesmn 0:d531d84af4c9 5 * Description : Main program body
charlesmn 0:d531d84af4c9 6 ******************************************************************************
charlesmn 0:d531d84af4c9 7 *
charlesmn 0:d531d84af4c9 8 * COPYRIGHT(c) 2020 STMicroelectronics
charlesmn 0:d531d84af4c9 9 *
charlesmn 0:d531d84af4c9 10 * Redistribution and use in source and binary forms, with or without modification,
charlesmn 0:d531d84af4c9 11 * are permitted provided that the following conditions are met:
charlesmn 0:d531d84af4c9 12 * 1. Redistributions of source code must retain the above copyright notice,
charlesmn 0:d531d84af4c9 13 * this list of conditions and the following disclaimer.
charlesmn 0:d531d84af4c9 14 * 2. Redistributions in binary form must reproduce the above copyright notice,
charlesmn 0:d531d84af4c9 15 * this list of conditions and the following disclaimer in the documentation
charlesmn 0:d531d84af4c9 16 * and/or other materials provided with the distribution.
charlesmn 0:d531d84af4c9 17 * 3. Neither the name of STMicroelectronics nor the names of its contributors
charlesmn 0:d531d84af4c9 18 * may be used to endorse or promote products derived from this software
charlesmn 0:d531d84af4c9 19 * without specific prior written permission.
charlesmn 0:d531d84af4c9 20 *
charlesmn 0:d531d84af4c9 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
charlesmn 0:d531d84af4c9 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
charlesmn 0:d531d84af4c9 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
charlesmn 0:d531d84af4c9 24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
charlesmn 0:d531d84af4c9 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
charlesmn 0:d531d84af4c9 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
charlesmn 0:d531d84af4c9 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
charlesmn 0:d531d84af4c9 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
charlesmn 0:d531d84af4c9 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
charlesmn 0:d531d84af4c9 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
charlesmn 0:d531d84af4c9 31 *
charlesmn 0:d531d84af4c9 32 ******************************************************************************
charlesmn 0:d531d84af4c9 33 This program controls a VL6180 ToF sensor running on an STM32F401 card with the
charlesmn 0:d531d84af4c9 34 VL6180 shield. This program works in single shot mode where the program polls for
charlesmn 0:d531d84af4c9 35 the measurement finishing. This allows for the display to be updated while the
charlesmn 0:d531d84af4c9 36 measurement occurs.
charlesmn 0:d531d84af4c9 37
charlesmn 0:d531d84af4c9 38 The display is very crude with no storing of the last digits, each digit is written
charlesmn 0:d531d84af4c9 39 and then a wait occurs and then the next digit is written. This means that a lot of time is
charlesmn 0:d531d84af4c9 40 taken writing the display and any long period when the display is not serviced
charlesmn 0:d531d84af4c9 41 will cause the display to flicker.
charlesmn 0:d531d84af4c9 42
charlesmn 0:d531d84af4c9 43 In this program access to the VL6180 api is through wrapper functions in
charlesmn 0:d531d84af4c9 44 vl6180_class.cpp. It is also possible to access the api directly. E.G both the lines below
charlesmn 0:d531d84af4c9 45 do the same thing.
charlesmn 0:d531d84af4c9 46
charlesmn 0:d531d84af4c9 47 status = VL6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:d531d84af4c9 48 status = sensor->vl6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:d531d84af4c9 49 */
charlesmn 0:d531d84af4c9 50
charlesmn 0:d531d84af4c9 51
charlesmn 0:d531d84af4c9 52 /* Includes ------------------------------------------------------------------*/
charlesmn 0:d531d84af4c9 53 //#include "stm32xxx_hal.h"
charlesmn 0:d531d84af4c9 54
charlesmn 0:d531d84af4c9 55 /* Private variables ---------------------------------------------------------*/
charlesmn 0:d531d84af4c9 56
charlesmn 0:d531d84af4c9 57 #include <stdio.h>
charlesmn 0:d531d84af4c9 58
charlesmn 0:d531d84af4c9 59 #include "mbed.h"
charlesmn 0:d531d84af4c9 60 #include "XNucleo6810.h"
charlesmn 0:d531d84af4c9 61 #include <time.h>
charlesmn 0:d531d84af4c9 62
charlesmn 0:d531d84af4c9 63 #include "spi_interface.h"
charlesmn 0:d531d84af4c9 64
charlesmn 0:d531d84af4c9 65
charlesmn 0:d531d84af4c9 66 //VL6180_SINGLE_DEVICE_DRIVER
charlesmn 0:d531d84af4c9 67
charlesmn 0:d531d84af4c9 68
charlesmn 0:d531d84af4c9 69 #define VL6180_I2C_SDA D14
charlesmn 0:d531d84af4c9 70 #define VL6180_I2C_SCL D15
charlesmn 0:d531d84af4c9 71
charlesmn 0:d531d84af4c9 72 /* USER CODE BEGIN 0 */
charlesmn 0:d531d84af4c9 73 #include <string.h>
charlesmn 0:d531d84af4c9 74 #include <stdlib.h>
charlesmn 0:d531d84af4c9 75 #include <stdio.h>
charlesmn 0:d531d84af4c9 76
charlesmn 0:d531d84af4c9 77 #include "vl6180_api.h"
charlesmn 0:d531d84af4c9 78 #include "6180a1.h"
charlesmn 0:d531d84af4c9 79
charlesmn 0:d531d84af4c9 80 #ifdef DEBUG
charlesmn 0:d531d84af4c9 81 //TODO
charlesmn 0:d531d84af4c9 82 #include "diag/trace.h"
charlesmn 0:d531d84af4c9 83 #define debug(msg, ...) trace_printf(msg,__VA_ARGS__)
charlesmn 0:d531d84af4c9 84 #define trace_warn(msg,...) trace_printf("W %s %d" msg "\n", __func__, __LINE__, __VA_ARGS__)
charlesmn 0:d531d84af4c9 85 #else
charlesmn 0:d531d84af4c9 86 #define debug(msg, ...) (void)0
charlesmn 0:d531d84af4c9 87 #endif
charlesmn 0:d531d84af4c9 88
charlesmn 0:d531d84af4c9 89 #define DigitDisplay_ms 1 /* ms each digit is kept on */
charlesmn 0:d531d84af4c9 90 #if VL6180_HAVE_DMAX_RANGING
charlesmn 0:d531d84af4c9 91 #define DMaxDispTime 0 /* Set to 1000 to display Dmax during 1 sec when no target is detected */
charlesmn 0:d531d84af4c9 92 #else
charlesmn 0:d531d84af4c9 93 #define DMaxDispTime 0
charlesmn 0:d531d84af4c9 94 #endif
charlesmn 0:d531d84af4c9 95
charlesmn 0:d531d84af4c9 96
charlesmn 0:d531d84af4c9 97 MyVL6180Dev_t devCentre; //data for each of the vl6180
charlesmn 0:d531d84af4c9 98 MyVL6180Dev_t devLeft;
charlesmn 0:d531d84af4c9 99 MyVL6180Dev_t devRight;
charlesmn 0:d531d84af4c9 100 MyVL6180Dev_t devBottom;
charlesmn 0:d531d84af4c9 101 VL6180Dev_t Dev = &devCentre; // the currently used vl6180
charlesmn 0:d531d84af4c9 102
charlesmn 0:d531d84af4c9 103 volatile int IntrFired=0;
charlesmn 0:d531d84af4c9 104
charlesmn 0:d531d84af4c9 105 VL6180 *Sensor;
charlesmn 0:d531d84af4c9 106
charlesmn 0:d531d84af4c9 107 static XNucleo53L1A1 *board=NULL;
charlesmn 0:d531d84af4c9 108
charlesmn 1:860eb432852b 109 // MBed V6.4 has renamed wait_ms and UnbufferedSerial replaces Serial
charlesmn 1:860eb432852b 110 #if (MBED_VERSION > 60300)
charlesmn 1:860eb432852b 111 UnbufferedSerial pc(SERIAL_TX, SERIAL_RX);
charlesmn 1:860eb432852b 112 extern "C" void wait_ms(int ms);
charlesmn 1:860eb432852b 113 #else
charlesmn 0:d531d84af4c9 114 Serial pc(SERIAL_TX, SERIAL_RX);
charlesmn 1:860eb432852b 115 #endif
charlesmn 0:d531d84af4c9 116
charlesmn 0:d531d84af4c9 117 vl6180_DevI2C *dev_I2C = new vl6180_DevI2C(VL6180_I2C_SDA, VL6180_I2C_SCL);
charlesmn 0:d531d84af4c9 118
charlesmn 0:d531d84af4c9 119 #define theVL6180Dev 0x52 // what we use as "API device
charlesmn 0:d531d84af4c9 120
charlesmn 0:d531d84af4c9 121 #define i2c_bus (&hi2c1)
charlesmn 0:d531d84af4c9 122 #define def_i2c_time_out 100
charlesmn 0:d531d84af4c9 123
charlesmn 1:860eb432852b 124 // Define interrupt pins
charlesmn 1:860eb432852b 125 // The interrupt pins depend on solder blobs on the back of the shield.
charlesmn 1:860eb432852b 126 // Each interupt can have two possible pins, this allows all interrupts to be on the same gpio or different gpio
charlesmn 1:860eb432852b 127 // The first values are those an unmodified board has
charlesmn 1:860eb432852b 128 // see ST document UM2657 for more details
charlesmn 1:860eb432852b 129 PinName CentreIntPin = A3;
charlesmn 1:860eb432852b 130 PinName LeftIntPin = D13;
charlesmn 1:860eb432852b 131 PinName RightIntPin = D2;
charlesmn 1:860eb432852b 132 PinName BottomIntPin = A2;
charlesmn 1:860eb432852b 133 // alternate set
charlesmn 1:860eb432852b 134 //PinName CentreIntPin = A5;
charlesmn 1:860eb432852b 135 //PinName LeftIntPin = D8;
charlesmn 1:860eb432852b 136 //PinName RightIntPin = D4;
charlesmn 1:860eb432852b 137 //PinName BottomIntPin = A4;
charlesmn 0:d531d84af4c9 138
charlesmn 0:d531d84af4c9 139
charlesmn 0:d531d84af4c9 140
charlesmn 0:d531d84af4c9 141 static char DISP_CurString[10]; // the strin g to be displayed on the screen
charlesmn 0:d531d84af4c9 142
charlesmn 0:d531d84af4c9 143 VL6180_RangeData_t Range; /* Range measurmeent */
charlesmn 0:d531d84af4c9 144 uint16_t range; /* range average distance */
charlesmn 0:d531d84af4c9 145
charlesmn 0:d531d84af4c9 146 int main(void)
charlesmn 0:d531d84af4c9 147 {
charlesmn 1:860eb432852b 148 int status;
charlesmn 1:860eb432852b 149
charlesmn 0:d531d84af4c9 150 pc.baud(115200); // baud rate is important as printf statements take a lot of time
charlesmn 0:d531d84af4c9 151 devCentre.i2c_addr = theVL6180Dev; // set to default adress for now
charlesmn 1:860eb432852b 152 printf("vl6180_ss_and_poll_ranging mbed = %d \r\n",MBED_VERSION);
charlesmn 0:d531d84af4c9 153
charlesmn 0:d531d84af4c9 154 // create instances for the sensors
charlesmn 1:860eb432852b 155 board = XNucleo53L1A1::instance(dev_I2C, CentreIntPin, LeftIntPin, RightIntPin ,BottomIntPin);
charlesmn 0:d531d84af4c9 156
charlesmn 0:d531d84af4c9 157 // find the sensors we have and initialise
charlesmn 0:d531d84af4c9 158 status = board->init_board();
charlesmn 0:d531d84af4c9 159 if (status) {
charlesmn 0:d531d84af4c9 160 printf("Failed to init board!\r\n");
charlesmn 0:d531d84af4c9 161 return 0;
charlesmn 0:d531d84af4c9 162 }
charlesmn 0:d531d84af4c9 163
charlesmn 0:d531d84af4c9 164 //select centre sensor
charlesmn 0:d531d84af4c9 165 devCentre.i2c_addr = NEW_SENSOR_CENTRE_ADDRESS;
charlesmn 0:d531d84af4c9 166 Dev = &devCentre;
charlesmn 0:d531d84af4c9 167 Sensor=board->sensor_centre;
charlesmn 0:d531d84af4c9 168 if ( board->sensor_centre ==NULL)
charlesmn 0:d531d84af4c9 169 printf("board->sensor_centre = Null\n");
charlesmn 0:d531d84af4c9 170
charlesmn 0:d531d84af4c9 171 /* Note that as we waited 1msec we could bypass VL6180_WaitDeviceBooted(&Dev); */
charlesmn 0:d531d84af4c9 172 Sensor->vl6180_WaitDeviceBooted(Dev);
charlesmn 0:d531d84af4c9 173 Sensor->vl6180_InitData(Dev);
charlesmn 0:d531d84af4c9 174
charlesmn 0:d531d84af4c9 175 printf("started interrupt centre %d\n",status);
charlesmn 0:d531d84af4c9 176
charlesmn 0:d531d84af4c9 177 /* Enable Dmax calculation only if value is displayed (to save computation power) */
charlesmn 0:d531d84af4c9 178 Sensor->vl6180_DMaxSetState(Dev, DMaxDispTime>0);
charlesmn 0:d531d84af4c9 179 status = Sensor->vl6180_Prepare(Dev);
charlesmn 0:d531d84af4c9 180
charlesmn 0:d531d84af4c9 181 VL6180_ClearInterrupt(Dev, INTERRUPT_CLEAR_RANGING);
charlesmn 0:d531d84af4c9 182
charlesmn 0:d531d84af4c9 183 /* kick off the first measurement */
charlesmn 0:d531d84af4c9 184 status = Sensor->vl6180_RangeStartSingleShot(Dev);
charlesmn 0:d531d84af4c9 185
charlesmn 0:d531d84af4c9 186 printf("start loop \n");
charlesmn 0:d531d84af4c9 187 /* Infinite loop */
charlesmn 0:d531d84af4c9 188 while (1) {
charlesmn 0:d531d84af4c9 189 status = Sensor->vl6180_RangeGetMeasurementIfReady(Dev, &Range);
charlesmn 0:d531d84af4c9 190 if( status == 0 ){
charlesmn 0:d531d84af4c9 191 // Application must check Range.errorStatus before accessing the other data
charlesmn 0:d531d84af4c9 192 // If Range.errorStatus is DataNotReady, application knows that it has to wait a bit before getting a new data
charlesmn 0:d531d84af4c9 193 // If Range.errorStatus is 0, application knows it is a valid distance
charlesmn 0:d531d84af4c9 194 // If Range.errorStatus is not 0, application knows that reported distance is invalid so may take some decisions depending on the errorStatus
charlesmn 0:d531d84af4c9 195 if (Range.errorStatus == DataNotReady)
charlesmn 0:d531d84af4c9 196 continue;
charlesmn 0:d531d84af4c9 197
charlesmn 0:d531d84af4c9 198 if((Range.errorStatus == 0) && (status == 0))
charlesmn 0:d531d84af4c9 199 {
charlesmn 0:d531d84af4c9 200 // printf("range = %d\n",Range.range_mm); //output result to serial port
charlesmn 0:d531d84af4c9 201 sprintf(DISP_CurString, " %d", (int)Range.range_mm);
charlesmn 0:d531d84af4c9 202 }
charlesmn 0:d531d84af4c9 203 else
charlesmn 0:d531d84af4c9 204 {
charlesmn 0:d531d84af4c9 205 sprintf(DISP_CurString, " %d", 0);
charlesmn 0:d531d84af4c9 206 }
charlesmn 0:d531d84af4c9 207
charlesmn 0:d531d84af4c9 208 /* re-arm next measurement */
charlesmn 0:d531d84af4c9 209 status = Sensor->vl6180_RangeStartSingleShot(Dev);
charlesmn 0:d531d84af4c9 210 }
charlesmn 0:d531d84af4c9 211 else{
charlesmn 0:d531d84af4c9 212 // it is an critical error
charlesmn 0:d531d84af4c9 213 // HandleError("critical error on VL6180x_RangeCheckAndGetMeasurement");
charlesmn 0:d531d84af4c9 214 }
charlesmn 0:d531d84af4c9 215
charlesmn 0:d531d84af4c9 216
charlesmn 0:d531d84af4c9 217 // the display is very simple and requires written to frequently so
charlesmn 0:d531d84af4c9 218 // we are writing to the display when we would normally sleep.
charlesmn 0:d531d84af4c9 219 // when we are not writing to the display it is blank
charlesmn 0:d531d84af4c9 220 for (int i = 0 ;i < 20;i++)
charlesmn 0:d531d84af4c9 221 {
charlesmn 0:d531d84af4c9 222 XNUCLEO6180XA1_DisplayString(DISP_CurString, DigitDisplay_ms* 5);
charlesmn 0:d531d84af4c9 223 }
charlesmn 0:d531d84af4c9 224
charlesmn 0:d531d84af4c9 225 }
charlesmn 0:d531d84af4c9 226
charlesmn 0:d531d84af4c9 227 }
charlesmn 0:d531d84af4c9 228
charlesmn 1:860eb432852b 229 // wait_ms was removed in MBed V6.4
charlesmn 1:860eb432852b 230 #if (MBED_VERSION > 60300)
charlesmn 1:860eb432852b 231 void wait_ms(int ms)
charlesmn 1:860eb432852b 232 {
charlesmn 1:860eb432852b 233 thread_sleep_for(ms);
charlesmn 1:860eb432852b 234 }
charlesmn 1:860eb432852b 235 #endif
charlesmn 1:860eb432852b 236
charlesmn 1:860eb432852b 237
charlesmn 0:d531d84af4c9 238
charlesmn 0:d531d84af4c9 239 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/