ST Expansion SW Team / Mbed OS VL6180_MB5_1sensor_singleshot_poll

Dependencies:   X_NUCLEO_6180

Committer:
charlesmn
Date:
Thu Oct 29 09:21:25 2020 +0000
Revision:
0:d531d84af4c9
Child:
1:860eb432852b
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 outputed to the Screen. MBed V5.15.

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 0:d531d84af4c9 109 Serial pc(SERIAL_TX, SERIAL_RX);
charlesmn 0:d531d84af4c9 110
charlesmn 0:d531d84af4c9 111 vl6180_DevI2C *dev_I2C = new vl6180_DevI2C(VL6180_I2C_SDA, VL6180_I2C_SCL);
charlesmn 0:d531d84af4c9 112
charlesmn 0:d531d84af4c9 113 #define theVL6180Dev 0x52 // what we use as "API device
charlesmn 0:d531d84af4c9 114
charlesmn 0:d531d84af4c9 115 #define i2c_bus (&hi2c1)
charlesmn 0:d531d84af4c9 116 #define def_i2c_time_out 100
charlesmn 0:d531d84af4c9 117
charlesmn 0:d531d84af4c9 118
charlesmn 0:d531d84af4c9 119 void XNUCLEO6180XA1_WaitMilliSec(int n){
charlesmn 0:d531d84af4c9 120 wait_ms(n);
charlesmn 0:d531d84af4c9 121 }
charlesmn 0:d531d84af4c9 122
charlesmn 0:d531d84af4c9 123
charlesmn 0:d531d84af4c9 124
charlesmn 0:d531d84af4c9 125
charlesmn 0:d531d84af4c9 126 /**
charlesmn 0:d531d84af4c9 127 * DISPLAY public
charlesmn 0:d531d84af4c9 128 */
charlesmn 0:d531d84af4c9 129 /*************** DISPLAY PUBLIC *********************/
charlesmn 0:d531d84af4c9 130 /*************** DISPLAY PRIVATE *********************/
charlesmn 0:d531d84af4c9 131 static char DISP_CurString[10]; // the strin g to be displayed on the screen
charlesmn 0:d531d84af4c9 132
charlesmn 0:d531d84af4c9 133 char buffer[10];
charlesmn 0:d531d84af4c9 134
charlesmn 0:d531d84af4c9 135
charlesmn 0:d531d84af4c9 136 uint32_t TimeStarted; /* various display and mode delay starting time */
charlesmn 0:d531d84af4c9 137 VL6180_RangeData_t Range; /* Range measurmeent */
charlesmn 0:d531d84af4c9 138 uint16_t range; /* range average distance */
charlesmn 0:d531d84af4c9 139
charlesmn 0:d531d84af4c9 140
charlesmn 0:d531d84af4c9 141 /* USER CODE END 0 */
charlesmn 0:d531d84af4c9 142
charlesmn 0:d531d84af4c9 143 /* Private function prototypes -----------------------------------------------*/
charlesmn 0:d531d84af4c9 144
charlesmn 0:d531d84af4c9 145 int main(void)
charlesmn 0:d531d84af4c9 146 {
charlesmn 0:d531d84af4c9 147 pc.baud(115200); // baud rate is important as printf statements take a lot of time
charlesmn 0:d531d84af4c9 148 devCentre.i2c_addr = theVL6180Dev; // set to default adress for now
charlesmn 0:d531d84af4c9 149 printf("vl6180_ss_and_poll_ranging \n");
charlesmn 0:d531d84af4c9 150
charlesmn 0:d531d84af4c9 151 int status;
charlesmn 0:d531d84af4c9 152
charlesmn 0:d531d84af4c9 153 // create instances for the sensors
charlesmn 0:d531d84af4c9 154 board = XNucleo53L1A1::instance(dev_I2C, A2, D8, D2 ,D2);
charlesmn 0:d531d84af4c9 155
charlesmn 0:d531d84af4c9 156 // find the sensors we have and initialise
charlesmn 0:d531d84af4c9 157 status = board->init_board();
charlesmn 0:d531d84af4c9 158 if (status) {
charlesmn 0:d531d84af4c9 159 printf("Failed to init board!\r\n");
charlesmn 0:d531d84af4c9 160 return 0;
charlesmn 0:d531d84af4c9 161 }
charlesmn 0:d531d84af4c9 162
charlesmn 0:d531d84af4c9 163 //select centre sensor
charlesmn 0:d531d84af4c9 164 devCentre.i2c_addr = NEW_SENSOR_CENTRE_ADDRESS;
charlesmn 0:d531d84af4c9 165 Dev = &devCentre;
charlesmn 0:d531d84af4c9 166 Sensor=board->sensor_centre;
charlesmn 0:d531d84af4c9 167 if ( board->sensor_centre ==NULL)
charlesmn 0:d531d84af4c9 168 printf("board->sensor_centre = Null\n");
charlesmn 0:d531d84af4c9 169
charlesmn 0:d531d84af4c9 170 /* Note that as we waited 1msec we could bypass VL6180_WaitDeviceBooted(&Dev); */
charlesmn 0:d531d84af4c9 171 Sensor->vl6180_WaitDeviceBooted(Dev);
charlesmn 0:d531d84af4c9 172 Sensor->vl6180_InitData(Dev);
charlesmn 0:d531d84af4c9 173
charlesmn 0:d531d84af4c9 174 printf("started interrupt centre %d\n",status);
charlesmn 0:d531d84af4c9 175
charlesmn 0:d531d84af4c9 176 /* Enable Dmax calculation only if value is displayed (to save computation power) */
charlesmn 0:d531d84af4c9 177 Sensor->vl6180_DMaxSetState(Dev, DMaxDispTime>0);
charlesmn 0:d531d84af4c9 178 status = Sensor->vl6180_Prepare(Dev);
charlesmn 0:d531d84af4c9 179
charlesmn 0:d531d84af4c9 180 VL6180_ClearInterrupt(Dev, INTERRUPT_CLEAR_RANGING);
charlesmn 0:d531d84af4c9 181
charlesmn 0:d531d84af4c9 182 /* kick off the first measurement */
charlesmn 0:d531d84af4c9 183 status = Sensor->vl6180_RangeStartSingleShot(Dev);
charlesmn 0:d531d84af4c9 184
charlesmn 0:d531d84af4c9 185 printf("start loop \n");
charlesmn 0:d531d84af4c9 186 /* Infinite loop */
charlesmn 0:d531d84af4c9 187 while (1) {
charlesmn 0:d531d84af4c9 188 status = Sensor->vl6180_RangeGetMeasurementIfReady(Dev, &Range);
charlesmn 0:d531d84af4c9 189 if( status == 0 ){
charlesmn 0:d531d84af4c9 190 // Application must check Range.errorStatus before accessing the other data
charlesmn 0:d531d84af4c9 191 // If Range.errorStatus is DataNotReady, application knows that it has to wait a bit before getting a new data
charlesmn 0:d531d84af4c9 192 // If Range.errorStatus is 0, application knows it is a valid distance
charlesmn 0:d531d84af4c9 193 // 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 194 if (Range.errorStatus == DataNotReady)
charlesmn 0:d531d84af4c9 195 continue;
charlesmn 0:d531d84af4c9 196
charlesmn 0:d531d84af4c9 197 if((Range.errorStatus == 0) && (status == 0))
charlesmn 0:d531d84af4c9 198 {
charlesmn 0:d531d84af4c9 199 // printf("range = %d\n",Range.range_mm); //output result to serial port
charlesmn 0:d531d84af4c9 200 sprintf(DISP_CurString, " %d", (int)Range.range_mm);
charlesmn 0:d531d84af4c9 201 }
charlesmn 0:d531d84af4c9 202 else
charlesmn 0:d531d84af4c9 203 {
charlesmn 0:d531d84af4c9 204 sprintf(DISP_CurString, " %d", 0);
charlesmn 0:d531d84af4c9 205 }
charlesmn 0:d531d84af4c9 206
charlesmn 0:d531d84af4c9 207 /* re-arm next measurement */
charlesmn 0:d531d84af4c9 208 status = Sensor->vl6180_RangeStartSingleShot(Dev);
charlesmn 0:d531d84af4c9 209 }
charlesmn 0:d531d84af4c9 210 else{
charlesmn 0:d531d84af4c9 211 // it is an critical error
charlesmn 0:d531d84af4c9 212 // HandleError("critical error on VL6180x_RangeCheckAndGetMeasurement");
charlesmn 0:d531d84af4c9 213 }
charlesmn 0:d531d84af4c9 214
charlesmn 0:d531d84af4c9 215
charlesmn 0:d531d84af4c9 216 // the display is very simple and requires written to frequently so
charlesmn 0:d531d84af4c9 217 // we are writing to the display when we would normally sleep.
charlesmn 0:d531d84af4c9 218 // when we are not writing to the display it is blank
charlesmn 0:d531d84af4c9 219 for (int i = 0 ;i < 20;i++)
charlesmn 0:d531d84af4c9 220 {
charlesmn 0:d531d84af4c9 221 XNUCLEO6180XA1_DisplayString(DISP_CurString, DigitDisplay_ms* 5);
charlesmn 0:d531d84af4c9 222 }
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 0:d531d84af4c9 229 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/