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