We are making a bluetooth application for a vehicle.

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_HeartRate_IDB0XA1 by ST

Committer:
Technicus
Date:
Wed Jul 19 05:03:35 2017 +0000
Revision:
29:e7d4922a4620
Parent:
28:a56710056f4d
Child:
30:243e095a69d9
Reduced polling time, and attempted to add interrupts for inputs.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:eb7f02ad28a7 1 /* mbed Microcontroller Library
screamer 0:eb7f02ad28a7 2 * Copyright (c) 2006-2015 ARM Limited
screamer 0:eb7f02ad28a7 3 *
screamer 0:eb7f02ad28a7 4 * Licensed under the Apache License, Version 2.0 (the "License");
screamer 0:eb7f02ad28a7 5 * you may not use this file except in compliance with the License.
screamer 0:eb7f02ad28a7 6 * You may obtain a copy of the License at
screamer 0:eb7f02ad28a7 7 *
screamer 0:eb7f02ad28a7 8 * http://www.apache.org/licenses/LICENSE-2.0
screamer 0:eb7f02ad28a7 9 *
screamer 0:eb7f02ad28a7 10 * Unless required by applicable law or agreed to in writing, software
screamer 0:eb7f02ad28a7 11 * distributed under the License is distributed on an "AS IS" BASIS,
screamer 0:eb7f02ad28a7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 0:eb7f02ad28a7 13 * See the License for the specific language governing permissions and
screamer 0:eb7f02ad28a7 14 * limitations under the License.
screamer 0:eb7f02ad28a7 15 */
screamer 0:eb7f02ad28a7 16
screamer 0:eb7f02ad28a7 17 #include "mbed.h"
screamer 0:eb7f02ad28a7 18 #include "ble/BLE.h"
bobbaddeley 23:a31b178e2263 19 #include "bike_service.h"
bobbaddeley 23:a31b178e2263 20 #include "ble/services/BatteryService.h"
screamer 0:eb7f02ad28a7 21
Technicus 28:a56710056f4d 22 int alarm_activated = 0;
Technicus 28:a56710056f4d 23 int alarm_on = 0;
Technicus 28:a56710056f4d 24 int alarm_counter = 0;
bobbaddeley 26:3a1d82a26a83 25
Technicus 28:a56710056f4d 26 DigitalOut led_0(PC_6);
Technicus 28:a56710056f4d 27 DigitalOut led_1(PC_7);
bobbaddeley 26:3a1d82a26a83 28 DigitalOut buzzer(PC_8);
Technicus 28:a56710056f4d 29 DigitalOut rumblr(PC_9);;
apalmieri 13:227a0149b677 30 DigitalOut led1(LED1, 1);
screamer 0:eb7f02ad28a7 31
Technicus 28:a56710056f4d 32 const static char DEVICE_NAME[] = "HeckBike!";
bobbaddeley 24:d352571b1c1f 33 static const uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE,
bobbaddeley 23:a31b178e2263 34 0x8EC5};//made up UUID for the Heck bike
apalmieri 13:227a0149b677 35
bobbaddeley 26:3a1d82a26a83 36 #define on 0xFFFF
bobbaddeley 26:3a1d82a26a83 37 #define off 0
bobbaddeley 26:3a1d82a26a83 38
Technicus 28:a56710056f4d 39 #define buttonMask 0x003F
bobbaddeley 26:3a1d82a26a83 40
bobbaddeley 26:3a1d82a26a83 41 PortIn sixButtons(PortC, buttonMask);
Technicus 29:e7d4922a4620 42
Technicus 29:e7d4922a4620 43 //InterruptIn event(sixButtons.read());
Technicus 29:e7d4922a4620 44 //InterruptIn interruptEventButton_0(PC_2);
Technicus 29:e7d4922a4620 45 //InterruptIn interruptEventButton_1(PC_3);
Technicus 29:e7d4922a4620 46 //InterruptIn interruptEventButton_2(PC_4);
Technicus 29:e7d4922a4620 47 //InterruptIn interruptEventButton_3(PC_5);
Technicus 29:e7d4922a4620 48 //InterruptIn interruptEventSensor_0(PC_0); // Vibration
Technicus 29:e7d4922a4620 49 //InterruptIn interruptEventSensor_1(PC_1); // Tilt
Technicus 29:e7d4922a4620 50
bobbaddeley 26:3a1d82a26a83 51 unsigned char byteOut = 0;
Technicus 28:a56710056f4d 52 unsigned char prevByteOut = 0;
bobbaddeley 26:3a1d82a26a83 53 unsigned char byteIn = 0x08;
bobbaddeley 26:3a1d82a26a83 54
Technicus 29:e7d4922a4620 55 uint8_t inputs = 0x00;
Technicus 29:e7d4922a4620 56 uint8_t outputs = 0x00;
Technicus 29:e7d4922a4620 57 uint8_t old_outputs = 0x00;
Technicus 29:e7d4922a4620 58 uint32_t timestamp = 0x00;
bobbaddeley 23:a31b178e2263 59
screamer 0:eb7f02ad28a7 60 static volatile bool triggerSensorPolling = false;
screamer 0:eb7f02ad28a7 61
apalmieri 2:bc0c0d442a24 62 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
screamer 0:eb7f02ad28a7 63 {
apalmieri 13:227a0149b677 64 (void)params;
apalmieri 13:227a0149b677 65 BLE::Instance().gap().startAdvertising(); // restart advertising
screamer 0:eb7f02ad28a7 66 }
screamer 0:eb7f02ad28a7 67
Technicus 29:e7d4922a4620 68 void toggleLED(void)
Technicus 29:e7d4922a4620 69 {
Technicus 29:e7d4922a4620 70 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
Technicus 29:e7d4922a4620 71 }
Technicus 29:e7d4922a4620 72
screamer 0:eb7f02ad28a7 73 void periodicCallback(void)
screamer 0:eb7f02ad28a7 74 {
screamer 0:eb7f02ad28a7 75 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
screamer 0:eb7f02ad28a7 76 * heavy-weight sensor polling from the main thread. */
screamer 0:eb7f02ad28a7 77 triggerSensorPolling = true;
screamer 0:eb7f02ad28a7 78 }
screamer 0:eb7f02ad28a7 79
apalmieri 13:227a0149b677 80 void onBleInitError(BLE &ble, ble_error_t error)
apalmieri 13:227a0149b677 81 {
apalmieri 13:227a0149b677 82 (void)ble;
apalmieri 13:227a0149b677 83 (void)error;
apalmieri 13:227a0149b677 84 /* Initialization error handling should go here */
apalmieri 13:227a0149b677 85 }
apalmieri 13:227a0149b677 86
Technicus 22:985657fc70c8 87 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
bobbaddeley 24:d352571b1c1f 88 //if (params->handle == BikeService.outputs.getValueAttribute().getHandle()) {
bobbaddeley 24:d352571b1c1f 89 //BOB Should update the outputs.
bobbaddeley 24:d352571b1c1f 90 outputs = *(params->data);
bobbaddeley 24:d352571b1c1f 91 //}
Technicus 22:985657fc70c8 92 }
Technicus 22:985657fc70c8 93
Technicus 29:e7d4922a4620 94 void alarm() {
Technicus 29:e7d4922a4620 95 if (alarm_activated && alarm_on) { //Flag set to sound the alarm?
Technicus 29:e7d4922a4620 96
Technicus 29:e7d4922a4620 97 if (alarm_counter++ < 500) { //Beep it on and off
Technicus 29:e7d4922a4620 98 buzzer = 1;
Technicus 29:e7d4922a4620 99 led_0 = 1;
Technicus 29:e7d4922a4620 100 led_1 = 1;
Technicus 29:e7d4922a4620 101 rumblr = 1;
Technicus 29:e7d4922a4620 102 }
Technicus 29:e7d4922a4620 103 else {
Technicus 29:e7d4922a4620 104 if (alarm_counter > 1000){alarm_counter = 0;}
Technicus 29:e7d4922a4620 105 buzzer = 0;
Technicus 29:e7d4922a4620 106 led_0 = 0;
Technicus 29:e7d4922a4620 107 led_1 = 0;
Technicus 29:e7d4922a4620 108 rumblr = 0;
Technicus 29:e7d4922a4620 109 }
Technicus 29:e7d4922a4620 110 }
Technicus 29:e7d4922a4620 111 }
bobbaddeley 26:3a1d82a26a83 112
Technicus 29:e7d4922a4620 113 //void interruptButton_0() {
Technicus 29:e7d4922a4620 114
Technicus 29:e7d4922a4620 115 //}
Technicus 29:e7d4922a4620 116 //void interruptButton_1() {
Technicus 29:e7d4922a4620 117
Technicus 29:e7d4922a4620 118 //}
Technicus 29:e7d4922a4620 119 //void interruptButton_2() {
Technicus 29:e7d4922a4620 120
Technicus 29:e7d4922a4620 121 //}
Technicus 29:e7d4922a4620 122 //void interruptButton_3() {
Technicus 29:e7d4922a4620 123
Technicus 29:e7d4922a4620 124 //}
Technicus 29:e7d4922a4620 125 //void interruptSensor_0() { // Vibration
Technicus 29:e7d4922a4620 126 // alarm_on = 1;
Technicus 29:e7d4922a4620 127 //}
Technicus 29:e7d4922a4620 128 //void interruptSensor_1() { // Tilt
Technicus 29:e7d4922a4620 129 //
Technicus 29:e7d4922a4620 130 //}
Technicus 29:e7d4922a4620 131
apalmieri 13:227a0149b677 132 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
screamer 0:eb7f02ad28a7 133 {
apalmieri 13:227a0149b677 134 BLE& ble = params->ble;
apalmieri 13:227a0149b677 135 ble_error_t error = params->error;
screamer 0:eb7f02ad28a7 136
apalmieri 13:227a0149b677 137 if (error != BLE_ERROR_NONE) {
apalmieri 13:227a0149b677 138 onBleInitError(ble, error);
apalmieri 13:227a0149b677 139 return;
apalmieri 13:227a0149b677 140 }
apalmieri 13:227a0149b677 141
apalmieri 13:227a0149b677 142 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
apalmieri 13:227a0149b677 143 return;
apalmieri 13:227a0149b677 144 }
apalmieri 13:227a0149b677 145
screamer 0:eb7f02ad28a7 146 ble.gap().onDisconnection(disconnectionCallback);
screamer 0:eb7f02ad28a7 147
Technicus 22:985657fc70c8 148 ble.gattServer().onDataWritten(onDataWrittenCallback);
screamer 0:eb7f02ad28a7 149 /* Setup primary service. */
bobbaddeley 24:d352571b1c1f 150 BikeService bikeService(ble);
bobbaddeley 23:a31b178e2263 151 /* Setup battery service. */
bobbaddeley 23:a31b178e2263 152 BatteryService btService(ble,100);
screamer 0:eb7f02ad28a7 153 /* Setup advertising. */
screamer 0:eb7f02ad28a7 154 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
screamer 0:eb7f02ad28a7 155 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
bobbaddeley 23:a31b178e2263 156 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_CYCLING);
screamer 0:eb7f02ad28a7 157 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
screamer 0:eb7f02ad28a7 158 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
screamer 0:eb7f02ad28a7 159 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
screamer 0:eb7f02ad28a7 160 ble.gap().startAdvertising();
screamer 0:eb7f02ad28a7 161
screamer 0:eb7f02ad28a7 162 // infinite loop
apalmieri 13:227a0149b677 163 while (true) {
screamer 0:eb7f02ad28a7 164 // check for trigger from periodicCallback()
screamer 0:eb7f02ad28a7 165 if (triggerSensorPolling && ble.getGapState().connected) {
Technicus 29:e7d4922a4620 166 //if (ble.getGapState().connected) {
Technicus 28:a56710056f4d 167 if (outputs & 0x01){
Technicus 28:a56710056f4d 168 led_0 = 1;
Technicus 29:e7d4922a4620 169 }
Technicus 28:a56710056f4d 170 if ((outputs & 0x01) == 0){
Technicus 28:a56710056f4d 171 led_0 = 0;
Technicus 29:e7d4922a4620 172 }
Technicus 29:e7d4922a4620 173
Technicus 28:a56710056f4d 174 if (outputs & 0x02){
Technicus 28:a56710056f4d 175 led_1 = 1;
Technicus 29:e7d4922a4620 176 }
Technicus 28:a56710056f4d 177 if ((outputs & 0x02) == 0){
Technicus 28:a56710056f4d 178 led_1 = 0;
Technicus 29:e7d4922a4620 179 }
Technicus 29:e7d4922a4620 180
Technicus 28:a56710056f4d 181 if (outputs & 0x04){
Technicus 28:a56710056f4d 182 buzzer = 1;
Technicus 28:a56710056f4d 183 }
Technicus 28:a56710056f4d 184 if ((outputs & 0x04) == 0){
Technicus 28:a56710056f4d 185 buzzer = 0;
Technicus 29:e7d4922a4620 186 }
Technicus 29:e7d4922a4620 187
Technicus 28:a56710056f4d 188 if (outputs & 0x08){
Technicus 28:a56710056f4d 189 rumblr = 1;
Technicus 29:e7d4922a4620 190 }
Technicus 28:a56710056f4d 191 if ((outputs & 0x08) == 0){
Technicus 28:a56710056f4d 192 rumblr = 0;
Technicus 29:e7d4922a4620 193 }
Technicus 29:e7d4922a4620 194
Technicus 28:a56710056f4d 195 if (outputs & 0x10){
Technicus 28:a56710056f4d 196 alarm_activated = 1;
bobbaddeley 26:3a1d82a26a83 197 }
Technicus 28:a56710056f4d 198 if ((outputs & 0x10) == 0){
Technicus 28:a56710056f4d 199 alarm_activated = 0;
Technicus 28:a56710056f4d 200 }
Technicus 29:e7d4922a4620 201
Technicus 28:a56710056f4d 202 if (outputs & 0x20){
Technicus 28:a56710056f4d 203 alarm_on = 1;
Technicus 28:a56710056f4d 204 }
Technicus 28:a56710056f4d 205 if ((outputs & 0x20) == 0){
Technicus 28:a56710056f4d 206 alarm_on = 0;
bobbaddeley 26:3a1d82a26a83 207 }
bobbaddeley 26:3a1d82a26a83 208
screamer 0:eb7f02ad28a7 209 triggerSensorPolling = false;
bobbaddeley 26:3a1d82a26a83 210 byteOut = sixButtons & buttonMask;
Technicus 29:e7d4922a4620 211 // update the ble with the inputs
Technicus 29:e7d4922a4620 212 bikeService.updateInputs(byteOut);
Technicus 29:e7d4922a4620 213 bikeService.updateTimestamp();
Technicus 29:e7d4922a4620 214 //if ((byteOut & 0x01) && alarm_activated==1) {
Technicus 29:e7d4922a4620 215 // alarm_on = 1;
Technicus 29:e7d4922a4620 216 // }
Technicus 28:a56710056f4d 217 if (byteOut != prevByteOut){
Technicus 28:a56710056f4d 218 // update the ble with the inputs
Technicus 28:a56710056f4d 219 bikeService.updateInputs(byteOut);
Technicus 28:a56710056f4d 220 bikeService.updateTimestamp();
Technicus 28:a56710056f4d 221 }
Technicus 28:a56710056f4d 222 prevByteOut = byteOut;
Technicus 29:e7d4922a4620 223
screamer 0:eb7f02ad28a7 224 } else {
screamer 0:eb7f02ad28a7 225 ble.waitForEvent(); // low power wait for event
screamer 0:eb7f02ad28a7 226 }
bobbaddeley 26:3a1d82a26a83 227
Technicus 29:e7d4922a4620 228 alarm();
screamer 0:eb7f02ad28a7 229 }
screamer 0:eb7f02ad28a7 230 }
apalmieri 13:227a0149b677 231
apalmieri 13:227a0149b677 232 int main(void)
apalmieri 13:227a0149b677 233 {
Technicus 29:e7d4922a4620 234
Technicus 29:e7d4922a4620 235 //interruptEventButton_0.fall(&interruptButton_0);
Technicus 29:e7d4922a4620 236 //interruptEventButton_1.fall(&interruptButton_1);
Technicus 29:e7d4922a4620 237 //interruptEventButton_2.fall(&interruptButton_2);
Technicus 29:e7d4922a4620 238 //interruptEventButton_3.fall(&interruptButton_3);
Technicus 29:e7d4922a4620 239 //interruptEventSensor_0.fall(&interruptSensor_0); // Vibration
Technicus 29:e7d4922a4620 240 //interruptEventSensor_1.fall(&interruptSensor_1); // Tilt
Technicus 29:e7d4922a4620 241
apalmieri 13:227a0149b677 242 Ticker ticker;
Technicus 29:e7d4922a4620 243 ticker.attach(toggleLED, 1);
Technicus 29:e7d4922a4620 244
Technicus 29:e7d4922a4620 245 Ticker ticker_CallBack;
Technicus 29:e7d4922a4620 246 //ticker.attach(periodicCallback, 1); // blink LED every second
Technicus 29:e7d4922a4620 247 ticker_CallBack.attach(periodicCallback, 0.01);
Technicus 29:e7d4922a4620 248
apalmieri 13:227a0149b677 249 BLE::Instance().init(bleInitComplete);
apalmieri 13:227a0149b677 250 }
apalmieri 14:f715c13eb84f 251
Technicus 29:e7d4922a4620 252 // Reference
Technicus 29:e7d4922a4620 253 // http://files.amperka.ru/datasheets/nucleo-usermanual.pdf
Technicus 29:e7d4922a4620 254 // http://www.st.com/content/ccc/resource/technical/document/user_manual/65/e0/44/72/9e/34/41/8d/DM00026748.pdf/files/DM00026748.pdf/jcr:content/translations/en.DM00026748.pdf
Technicus 29:e7d4922a4620 255 // https://developer.mbed.org/users/mbed_official/code/mbed-dev/file/default/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PinNames.h
Technicus 29:e7d4922a4620 256 // https://developer.mbed.org/users/mbed_official/code/mbed-dev/file/default/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralPins.c
Technicus 29:e7d4922a4620 257 // http://www.st.com/content/ccc/resource/technical/document/datasheet/c5/ed/2f/60/aa/79/42/0b/DM00108832.pdf/files/DM00108832.pdf/jcr:content/translations/en.DM00108832.pdf
Technicus 29:e7d4922a4620 258 // http://www.st.com/en/microcontrollers/stm32l476rg.html
Technicus 29:e7d4922a4620 259 // http://jeelabs.org/book/1547a/index.html
Technicus 29:e7d4922a4620 260 // http://www.st.com/content/ccc/resource/technical/document/datasheet/33/d4/6f/1d/df/0b/4c/6d/CD00161566.pdf/files/CD00161566.pdf/jcr:content/translations/en.CD00161566.pdf