ST Expansion SW Team / Mbed OS VL6180_MB63_1sensor_singleshot_poll

Dependencies:   X_NUCLEO_6180

Committer:
charlesmn
Date:
Mon May 03 10:59:47 2021 +0000
Revision:
1:43a9bc2f05b5
Parent:
0:d96995e87b29
Sample program for the VL6180 ToF sensor. Runs 1 sensor. Uses singleshot poll mode. MBed V6

Who changed what in which revision?

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