Bluetooth Connected TOF Sensor
Dependencies: BLE_API X_NUCLEO_6180XA1 X_NUCLEO_IDB0XA1 mbed
Fork of BLE_HeartRate_IDB0XA1 by
shields/xn6180.cpp@30:e324e95c68a9, 2017-02-02 (annotated)
- Committer:
- hux
- Date:
- Thu Feb 02 17:35:34 2017 +0000
- Revision:
- 30:e324e95c68a9
- Parent:
- 28:def5e0f0fb06
Final Version 2.0 of S16_Blue_ToF
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hux | 28:def5e0f0fb06 | 1 | // xn6180.cpp - X-NUCLEO 6180XA1 expansion board functionality |
hux | 28:def5e0f0fb06 | 2 | // |
hux | 28:def5e0f0fb06 | 3 | // This VL6180X Expansion board test application performs a range measurement and an als measurement in interrupt mode |
hux | 28:def5e0f0fb06 | 4 | // on the onboard embedded top sensor. |
hux | 28:def5e0f0fb06 | 5 | // The board red slider select on the flight the measurement type as ALS or RANGE; the measured data is diplayed on the |
hux | 28:def5e0f0fb06 | 6 | // on board 4digits display. |
hux | 28:def5e0f0fb06 | 7 | // |
hux | 28:def5e0f0fb06 | 8 | // User Blue button allows to stop current measurement and the entire program releasing all the resources. |
hux | 28:def5e0f0fb06 | 9 | // Reset button is used to restart the program. |
hux | 28:def5e0f0fb06 | 10 | // |
hux | 28:def5e0f0fb06 | 11 | // Polling operating modes don`t require callback function that handles IRQ |
hux | 28:def5e0f0fb06 | 12 | // Callback IRQ functions are used only for measure that require interrupt |
hux | 28:def5e0f0fb06 | 13 | // |
hux | 28:def5e0f0fb06 | 14 | // GetMeasurement is asynchronous! It returns NOT_READY if the measurement value |
hux | 28:def5e0f0fb06 | 15 | // is not ready to be read from the corresponding register. So you need to wait |
hux | 28:def5e0f0fb06 | 16 | // for the result to be ready |
hux | 28:def5e0f0fb06 | 17 | // |
hux | 28:def5e0f0fb06 | 18 | |
hux | 28:def5e0f0fb06 | 19 | #include "mbed.h" |
hux | 28:def5e0f0fb06 | 20 | #include "shields/xn6180.h" |
hux | 28:def5e0f0fb06 | 21 | |
hux | 28:def5e0f0fb06 | 22 | #define VL6180X_I2C_SDA D14 |
hux | 28:def5e0f0fb06 | 23 | #define VL6180X_I2C_SCL D15 |
hux | 28:def5e0f0fb06 | 24 | |
hux | 28:def5e0f0fb06 | 25 | #define RANGE 0 |
hux | 28:def5e0f0fb06 | 26 | #define ALS 1 |
hux | 28:def5e0f0fb06 | 27 | |
hux | 28:def5e0f0fb06 | 28 | #define DELAY 2000 // 2Sec |
hux | 28:def5e0f0fb06 | 29 | |
hux | 28:def5e0f0fb06 | 30 | // static DisplayShield *pShield = 0; // used by IRQ callback to access data |
hux | 28:def5e0f0fb06 | 31 | |
hux | 28:def5e0f0fb06 | 32 | void DisplayShield::init(const char *msg, int msec) |
hux | 28:def5e0f0fb06 | 33 | { |
hux | 28:def5e0f0fb06 | 34 | if (msg) |
hux | 28:def5e0f0fb06 | 35 | display(msg,msec); // display "INI" for 1 second |
hux | 28:def5e0f0fb06 | 36 | |
hux | 28:def5e0f0fb06 | 37 | // now init the 6180XA1 expansion board with default values |
hux | 28:def5e0f0fb06 | 38 | |
hux | 28:def5e0f0fb06 | 39 | int err = pBoard->InitBoard(); |
hux | 28:def5e0f0fb06 | 40 | if (err) |
hux | 28:def5e0f0fb06 | 41 | printf("Failed to init board!\n\r"); |
hux | 28:def5e0f0fb06 | 42 | |
hux | 28:def5e0f0fb06 | 43 | // read the red slider position for ALS/Range measure |
hux | 28:def5e0f0fb06 | 44 | |
hux | 28:def5e0f0fb06 | 45 | slider(IntMeasure); // update curMode due to slider position |
hux | 28:def5e0f0fb06 | 46 | clear(); // clear service handling request flag |
hux | 28:def5e0f0fb06 | 47 | } |
hux | 28:def5e0f0fb06 | 48 | |
hux | 28:def5e0f0fb06 | 49 | |
hux | 28:def5e0f0fb06 | 50 | DisplayShield::DisplayShield(const char *msg, int msec) |
hux | 28:def5e0f0fb06 | 51 | { |
hux | 28:def5e0f0fb06 | 52 | // first we need an I2C device |
hux | 28:def5e0f0fb06 | 53 | |
hux | 28:def5e0f0fb06 | 54 | pDevice = new DevI2C(VL6180X_I2C_SDA, VL6180X_I2C_SCL); |
hux | 28:def5e0f0fb06 | 55 | |
hux | 28:def5e0f0fb06 | 56 | // next we create the 6180XA1 expansion board singleton obj |
hux | 28:def5e0f0fb06 | 57 | // after that we are already able to display the init message |
hux | 28:def5e0f0fb06 | 58 | |
hux | 28:def5e0f0fb06 | 59 | // pBoard = X_NUCLEO_6180XA1::Instance(pDevice, A3, A2, D13, D2); |
hux | 28:def5e0f0fb06 | 60 | pBoard = X_NUCLEO_6180XA1::Instance(pDevice, NC, NC, NC, NC); |
hux | 28:def5e0f0fb06 | 61 | |
hux | 28:def5e0f0fb06 | 62 | init(msg,msec); // initialize shield |
hux | 28:def5e0f0fb06 | 63 | } |
hux | 28:def5e0f0fb06 | 64 | |
hux | 28:def5e0f0fb06 | 65 | //============================================================================== |
hux | 28:def5e0f0fb06 | 66 | // Displaying Messages or Values |
hux | 28:def5e0f0fb06 | 67 | //============================================================================== |
hux | 28:def5e0f0fb06 | 68 | |
hux | 28:def5e0f0fb06 | 69 | |
hux | 28:def5e0f0fb06 | 70 | void DisplayShield::display(const char * msg) // display max 4 digits |
hux | 28:def5e0f0fb06 | 71 | { |
hux | 28:def5e0f0fb06 | 72 | char buf[5]; |
hux | 28:def5e0f0fb06 | 73 | int nmax = sizeof(buf) - 1; |
hux | 28:def5e0f0fb06 | 74 | int len = strlen(msg); |
hux | 28:def5e0f0fb06 | 75 | |
hux | 28:def5e0f0fb06 | 76 | memset(buf,0,sizeof(buf)); // clear buffer, provide terminator |
hux | 28:def5e0f0fb06 | 77 | for (int j=0; j < nmax; j++) |
hux | 28:def5e0f0fb06 | 78 | { if (msg[j] == 0) |
hux | 28:def5e0f0fb06 | 79 | break; |
hux | 28:def5e0f0fb06 | 80 | buf[j] = msg[j]; |
hux | 28:def5e0f0fb06 | 81 | } |
hux | 28:def5e0f0fb06 | 82 | |
hux | 28:def5e0f0fb06 | 83 | pBoard->display->DisplayString(buf, strlen(buf)); |
hux | 28:def5e0f0fb06 | 84 | } |
hux | 28:def5e0f0fb06 | 85 | |
hux | 28:def5e0f0fb06 | 86 | |
hux | 28:def5e0f0fb06 | 87 | void DisplayShield::display(const char * msg, int msec) // display & wait |
hux | 28:def5e0f0fb06 | 88 | { |
hux | 28:def5e0f0fb06 | 89 | Timer timer; |
hux | 28:def5e0f0fb06 | 90 | |
hux | 28:def5e0f0fb06 | 91 | timer.start(); |
hux | 28:def5e0f0fb06 | 92 | for(int i=0; i < msec; i = timer.read_ms()) |
hux | 28:def5e0f0fb06 | 93 | display(msg); |
hux | 28:def5e0f0fb06 | 94 | timer.stop(); |
hux | 28:def5e0f0fb06 | 95 | } |
hux | 28:def5e0f0fb06 | 96 | |
hux | 28:def5e0f0fb06 | 97 | |
hux | 28:def5e0f0fb06 | 98 | // On board 4 digit local display refresh |
hux | 28:def5e0f0fb06 | 99 | |
hux | 28:def5e0f0fb06 | 100 | void DisplayShield::refresh(OpMode mode) |
hux | 28:def5e0f0fb06 | 101 | { |
hux | 28:def5e0f0fb06 | 102 | char str[5]; |
hux | 28:def5e0f0fb06 | 103 | |
hux | 28:def5e0f0fb06 | 104 | if(mode == range_continuous_interrupt || mode == range_continuous_polling) |
hux | 28:def5e0f0fb06 | 105 | { |
hux | 28:def5e0f0fb06 | 106 | if (data.range_mm != 0xFFFFFFFF) |
hux | 28:def5e0f0fb06 | 107 | { |
hux | 28:def5e0f0fb06 | 108 | sprintf(str,"%d",data.range_mm); |
hux | 28:def5e0f0fb06 | 109 | } |
hux | 28:def5e0f0fb06 | 110 | else |
hux | 28:def5e0f0fb06 | 111 | { |
hux | 28:def5e0f0fb06 | 112 | sprintf(str,"%s","----"); |
hux | 28:def5e0f0fb06 | 113 | } |
hux | 28:def5e0f0fb06 | 114 | } |
hux | 28:def5e0f0fb06 | 115 | else if(mode == als_continuous_interrupt || mode == als_continuous_polling) |
hux | 28:def5e0f0fb06 | 116 | { |
hux | 28:def5e0f0fb06 | 117 | if(data.lux != 0xFFFFFFFF) |
hux | 28:def5e0f0fb06 | 118 | { |
hux | 28:def5e0f0fb06 | 119 | sprintf(str,"%d",data.lux); |
hux | 28:def5e0f0fb06 | 120 | } |
hux | 28:def5e0f0fb06 | 121 | else |
hux | 28:def5e0f0fb06 | 122 | { |
hux | 28:def5e0f0fb06 | 123 | sprintf(str,"%s","----"); |
hux | 28:def5e0f0fb06 | 124 | } |
hux | 28:def5e0f0fb06 | 125 | } |
hux | 28:def5e0f0fb06 | 126 | pBoard->display->DisplayString(str, strlen(str)); |
hux | 28:def5e0f0fb06 | 127 | } |
hux | 28:def5e0f0fb06 | 128 | |
hux | 28:def5e0f0fb06 | 129 | void DisplayShield::refresh() // refresh display in current mode |
hux | 28:def5e0f0fb06 | 130 | { |
hux | 28:def5e0f0fb06 | 131 | refresh(curMode); |
hux | 28:def5e0f0fb06 | 132 | } |
hux | 28:def5e0f0fb06 | 133 | |
hux | 28:def5e0f0fb06 | 134 | |
hux | 28:def5e0f0fb06 | 135 | //============================================================================== |
hux | 28:def5e0f0fb06 | 136 | // IRQ Functionality |
hux | 28:def5e0f0fb06 | 137 | //============================================================================== |
hux | 28:def5e0f0fb06 | 138 | |
hux | 28:def5e0f0fb06 | 139 | |
hux | 28:def5e0f0fb06 | 140 | void DisplayShield::set() // set data read service request |
hux | 28:def5e0f0fb06 | 141 | { |
hux | 28:def5e0f0fb06 | 142 | flagService = true; |
hux | 28:def5e0f0fb06 | 143 | } |
hux | 28:def5e0f0fb06 | 144 | |
hux | 28:def5e0f0fb06 | 145 | void DisplayShield::clear() // clear data read service request |
hux | 28:def5e0f0fb06 | 146 | { |
hux | 28:def5e0f0fb06 | 147 | flagService = false; |
hux | 28:def5e0f0fb06 | 148 | } |
hux | 28:def5e0f0fb06 | 149 | |
hux | 28:def5e0f0fb06 | 150 | bool DisplayShield::request() // return data read service request |
hux | 28:def5e0f0fb06 | 151 | { |
hux | 28:def5e0f0fb06 | 152 | return flagService; |
hux | 28:def5e0f0fb06 | 153 | } |
hux | 28:def5e0f0fb06 | 154 | /* |
hux | 28:def5e0f0fb06 | 155 | static void cbDone(void) // measurement done callback |
hux | 28:def5e0f0fb06 | 156 | { |
hux | 28:def5e0f0fb06 | 157 | if (pShield) |
hux | 28:def5e0f0fb06 | 158 | { |
hux | 28:def5e0f0fb06 | 159 | pShield->set(); // set service request |
hux | 28:def5e0f0fb06 | 160 | pShield->disable(); // disable further interrupts |
hux | 28:def5e0f0fb06 | 161 | pShield = 0; // free-up shield pointer, no more in use |
hux | 28:def5e0f0fb06 | 162 | } |
hux | 28:def5e0f0fb06 | 163 | } |
hux | 28:def5e0f0fb06 | 164 | */ |
hux | 28:def5e0f0fb06 | 165 | |
hux | 28:def5e0f0fb06 | 166 | int DisplayShield::handle() // handle ISR and read the measurement |
hux | 28:def5e0f0fb06 | 167 | { |
hux | 28:def5e0f0fb06 | 168 | clear(); // clear data read service request |
hux | 28:def5e0f0fb06 | 169 | return pBoard->sensor_top->HandleIRQ(curMode, &data); |
hux | 28:def5e0f0fb06 | 170 | } |
hux | 28:def5e0f0fb06 | 171 | |
hux | 28:def5e0f0fb06 | 172 | |
hux | 28:def5e0f0fb06 | 173 | void DisplayShield::disable() // disable interrupt measure detection |
hux | 28:def5e0f0fb06 | 174 | { |
hux | 28:def5e0f0fb06 | 175 | pBoard->sensor_top->DisableInterruptMeasureDetectionIRQ(); |
hux | 28:def5e0f0fb06 | 176 | } |
hux | 28:def5e0f0fb06 | 177 | |
hux | 28:def5e0f0fb06 | 178 | |
hux | 28:def5e0f0fb06 | 179 | void DisplayShield::ready() // set data ready status |
hux | 28:def5e0f0fb06 | 180 | { |
hux | 28:def5e0f0fb06 | 181 | disable(); // disable interrupts |
hux | 28:def5e0f0fb06 | 182 | set(); // set data service request flag |
hux | 28:def5e0f0fb06 | 183 | } |
hux | 28:def5e0f0fb06 | 184 | |
hux | 28:def5e0f0fb06 | 185 | |
hux | 28:def5e0f0fb06 | 186 | int DisplayShield::start(void (*callback)(void)) |
hux | 28:def5e0f0fb06 | 187 | { |
hux | 28:def5e0f0fb06 | 188 | int err; // error code |
hux | 28:def5e0f0fb06 | 189 | |
hux | 28:def5e0f0fb06 | 190 | // if (pShield != 0) |
hux | 28:def5e0f0fb06 | 191 | // return 0x99; // pShield is already booked! |
hux | 28:def5e0f0fb06 | 192 | // |
hux | 28:def5e0f0fb06 | 193 | // pShield = this; // make access available to cbDone() |
hux | 28:def5e0f0fb06 | 194 | err = pBoard->sensor_top->StartMeasurement(curMode, callback, NULL, NULL); |
hux | 28:def5e0f0fb06 | 195 | |
hux | 28:def5e0f0fb06 | 196 | if (err == 0) // if no errors occured |
hux | 28:def5e0f0fb06 | 197 | { |
hux | 28:def5e0f0fb06 | 198 | prvMode = curMode; |
hux | 28:def5e0f0fb06 | 199 | startMessage(); // then report about successful start |
hux | 28:def5e0f0fb06 | 200 | } |
hux | 28:def5e0f0fb06 | 201 | |
hux | 28:def5e0f0fb06 | 202 | return err; |
hux | 28:def5e0f0fb06 | 203 | } |
hux | 28:def5e0f0fb06 | 204 | |
hux | 28:def5e0f0fb06 | 205 | |
hux | 28:def5e0f0fb06 | 206 | int DisplayShield::stop() |
hux | 28:def5e0f0fb06 | 207 | { |
hux | 28:def5e0f0fb06 | 208 | int err; // error code |
hux | 28:def5e0f0fb06 | 209 | |
hux | 28:def5e0f0fb06 | 210 | // pShield = 0; // free-up pShield pointer |
hux | 28:def5e0f0fb06 | 211 | err = pBoard->sensor_top->StopMeasurement(prvMode); // stop measurement |
hux | 28:def5e0f0fb06 | 212 | |
hux | 28:def5e0f0fb06 | 213 | if (err == 0) // if no errors occured |
hux | 28:def5e0f0fb06 | 214 | stopMessage(); // then report about successful stop |
hux | 28:def5e0f0fb06 | 215 | |
hux | 28:def5e0f0fb06 | 216 | return err; // return error code |
hux | 28:def5e0f0fb06 | 217 | } |
hux | 28:def5e0f0fb06 | 218 | |
hux | 28:def5e0f0fb06 | 219 | |
hux | 28:def5e0f0fb06 | 220 | //============================================================================== |
hux | 28:def5e0f0fb06 | 221 | // Examine Red Slider Position |
hux | 28:def5e0f0fb06 | 222 | //============================================================================== |
hux | 28:def5e0f0fb06 | 223 | |
hux | 28:def5e0f0fb06 | 224 | bool DisplayShield::red() |
hux | 28:def5e0f0fb06 | 225 | { |
hux | 28:def5e0f0fb06 | 226 | return (pBoard->RdSwitch() == RANGE); |
hux | 28:def5e0f0fb06 | 227 | } |
hux | 28:def5e0f0fb06 | 228 | |
hux | 28:def5e0f0fb06 | 229 | bool DisplayShield::slider(enum OpModeIntPoll_t mode) |
hux | 28:def5e0f0fb06 | 230 | { |
hux | 28:def5e0f0fb06 | 231 | int measure = pBoard->RdSwitch(); |
hux | 28:def5e0f0fb06 | 232 | |
hux | 28:def5e0f0fb06 | 233 | switch (mode) |
hux | 28:def5e0f0fb06 | 234 | { |
hux | 28:def5e0f0fb06 | 235 | case PollMeasure: |
hux | 28:def5e0f0fb06 | 236 | if (measure == RANGE) |
hux | 28:def5e0f0fb06 | 237 | curMode = range_continuous_polling; |
hux | 28:def5e0f0fb06 | 238 | else if(measure==ALS) |
hux | 28:def5e0f0fb06 | 239 | curMode = als_continuous_polling; |
hux | 28:def5e0f0fb06 | 240 | break; |
hux | 28:def5e0f0fb06 | 241 | |
hux | 28:def5e0f0fb06 | 242 | case IntMeasure: |
hux | 28:def5e0f0fb06 | 243 | if(measure == RANGE) |
hux | 28:def5e0f0fb06 | 244 | curMode = range_continuous_interrupt; |
hux | 28:def5e0f0fb06 | 245 | else if(measure == ALS) |
hux | 28:def5e0f0fb06 | 246 | curMode = als_continuous_interrupt; |
hux | 28:def5e0f0fb06 | 247 | break; |
hux | 28:def5e0f0fb06 | 248 | } |
hux | 28:def5e0f0fb06 | 249 | |
hux | 28:def5e0f0fb06 | 250 | return (curMode != prvMode); // slider position changed? |
hux | 28:def5e0f0fb06 | 251 | } |
hux | 28:def5e0f0fb06 | 252 | |
hux | 28:def5e0f0fb06 | 253 | bool DisplayShield::setup(OpMode mode) |
hux | 28:def5e0f0fb06 | 254 | { |
hux | 28:def5e0f0fb06 | 255 | switch (mode) |
hux | 28:def5e0f0fb06 | 256 | { |
hux | 28:def5e0f0fb06 | 257 | case range_continuous_polling: |
hux | 28:def5e0f0fb06 | 258 | case als_continuous_polling: |
hux | 28:def5e0f0fb06 | 259 | case range_continuous_interrupt: |
hux | 28:def5e0f0fb06 | 260 | case als_continuous_interrupt: |
hux | 28:def5e0f0fb06 | 261 | curMode = mode; |
hux | 28:def5e0f0fb06 | 262 | prvMode = mode; |
hux | 28:def5e0f0fb06 | 263 | return 0; // no errors |
hux | 28:def5e0f0fb06 | 264 | } |
hux | 28:def5e0f0fb06 | 265 | return 1; // return with error code 1 |
hux | 28:def5e0f0fb06 | 266 | } |
hux | 28:def5e0f0fb06 | 267 | |
hux | 28:def5e0f0fb06 | 268 | |
hux | 28:def5e0f0fb06 | 269 | //============================================================================== |
hux | 28:def5e0f0fb06 | 270 | // Trace Message Printing |
hux | 28:def5e0f0fb06 | 271 | //============================================================================== |
hux | 28:def5e0f0fb06 | 272 | |
hux | 28:def5e0f0fb06 | 273 | void DisplayShield::startMessage(OpMode mode) |
hux | 28:def5e0f0fb06 | 274 | { |
hux | 28:def5e0f0fb06 | 275 | if (mode == range_continuous_interrupt) |
hux | 28:def5e0f0fb06 | 276 | printf("\nStarted range continuous interrupt measure\n\r"); |
hux | 28:def5e0f0fb06 | 277 | else if(prvMode == als_continuous_interrupt) |
hux | 28:def5e0f0fb06 | 278 | printf("\nStarted als continuous interrupt measure\n\r"); |
hux | 28:def5e0f0fb06 | 279 | } |
hux | 28:def5e0f0fb06 | 280 | |
hux | 28:def5e0f0fb06 | 281 | void DisplayShield::startMessage() |
hux | 28:def5e0f0fb06 | 282 | { |
hux | 28:def5e0f0fb06 | 283 | startMessage(curMode); |
hux | 28:def5e0f0fb06 | 284 | } |
hux | 28:def5e0f0fb06 | 285 | |
hux | 28:def5e0f0fb06 | 286 | void DisplayShield::stopMessage(OpMode mode) |
hux | 28:def5e0f0fb06 | 287 | { |
hux | 28:def5e0f0fb06 | 288 | if (mode == range_continuous_interrupt) |
hux | 28:def5e0f0fb06 | 289 | printf("Stopped range continuous interrupt measure\n\r"); |
hux | 28:def5e0f0fb06 | 290 | else if(prvMode == als_continuous_interrupt) |
hux | 28:def5e0f0fb06 | 291 | printf("Stopped als continuous interrupt measure\n\r"); |
hux | 28:def5e0f0fb06 | 292 | } |
hux | 28:def5e0f0fb06 | 293 | |
hux | 28:def5e0f0fb06 | 294 | void DisplayShield::stopMessage() |
hux | 28:def5e0f0fb06 | 295 | { |
hux | 28:def5e0f0fb06 | 296 | stopMessage(prvMode); |
hux | 28:def5e0f0fb06 | 297 | } |
hux | 28:def5e0f0fb06 | 298 | |
hux | 28:def5e0f0fb06 | 299 | // eof |