We are making a bluetooth application for a vehicle.

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_HeartRate_IDB0XA1 by ST

Committer:
bobbaddeley
Date:
Wed Jul 19 14:38:04 2017 +0000
Revision:
30:243e095a69d9
Parent:
29:e7d4922a4620
Getting alarms to work

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 30:243e095a69d9 51 unsigned char byteIn = 0;
bobbaddeley 30:243e095a69d9 52 unsigned char prevByteIn = 0;
bobbaddeley 26:3a1d82a26a83 53
Technicus 29:e7d4922a4620 54 uint8_t inputs = 0x00;
Technicus 29:e7d4922a4620 55 uint8_t outputs = 0x00;
Technicus 29:e7d4922a4620 56 uint8_t old_outputs = 0x00;
Technicus 29:e7d4922a4620 57 uint32_t timestamp = 0x00;
bobbaddeley 23:a31b178e2263 58
screamer 0:eb7f02ad28a7 59 static volatile bool triggerSensorPolling = false;
screamer 0:eb7f02ad28a7 60
apalmieri 2:bc0c0d442a24 61 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
screamer 0:eb7f02ad28a7 62 {
apalmieri 13:227a0149b677 63 (void)params;
apalmieri 13:227a0149b677 64 BLE::Instance().gap().startAdvertising(); // restart advertising
screamer 0:eb7f02ad28a7 65 }
screamer 0:eb7f02ad28a7 66
Technicus 29:e7d4922a4620 67 void toggleLED(void)
Technicus 29:e7d4922a4620 68 {
Technicus 29:e7d4922a4620 69 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
Technicus 29:e7d4922a4620 70 }
Technicus 29:e7d4922a4620 71
screamer 0:eb7f02ad28a7 72 void periodicCallback(void)
screamer 0:eb7f02ad28a7 73 {
screamer 0:eb7f02ad28a7 74 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
screamer 0:eb7f02ad28a7 75 * heavy-weight sensor polling from the main thread. */
screamer 0:eb7f02ad28a7 76 triggerSensorPolling = true;
screamer 0:eb7f02ad28a7 77 }
screamer 0:eb7f02ad28a7 78
apalmieri 13:227a0149b677 79 void onBleInitError(BLE &ble, ble_error_t error)
apalmieri 13:227a0149b677 80 {
apalmieri 13:227a0149b677 81 (void)ble;
apalmieri 13:227a0149b677 82 (void)error;
apalmieri 13:227a0149b677 83 /* Initialization error handling should go here */
apalmieri 13:227a0149b677 84 }
apalmieri 13:227a0149b677 85
Technicus 22:985657fc70c8 86 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
bobbaddeley 30:243e095a69d9 87 //if (params->handle == BikeService.output_characteristic.getValueAttribute().getHandle()) {
bobbaddeley 30:243e095a69d9 88 outputs = *(params->data);
bobbaddeley 30:243e095a69d9 89 if (outputs & 0x01){
bobbaddeley 30:243e095a69d9 90 led_0 = 1;
bobbaddeley 30:243e095a69d9 91 }
bobbaddeley 30:243e095a69d9 92 if ((outputs & 0x01) == 0){
bobbaddeley 30:243e095a69d9 93 led_0 = 0;
bobbaddeley 30:243e095a69d9 94 }
bobbaddeley 30:243e095a69d9 95
bobbaddeley 30:243e095a69d9 96 if (outputs & 0x02){
bobbaddeley 30:243e095a69d9 97 led_1 = 1;
bobbaddeley 30:243e095a69d9 98 }
bobbaddeley 30:243e095a69d9 99 if ((outputs & 0x02) == 0){
bobbaddeley 30:243e095a69d9 100 led_1 = 0;
bobbaddeley 30:243e095a69d9 101 }
bobbaddeley 30:243e095a69d9 102
bobbaddeley 30:243e095a69d9 103 if (outputs & 0x04){
bobbaddeley 30:243e095a69d9 104 buzzer = 1;
bobbaddeley 30:243e095a69d9 105 }
bobbaddeley 30:243e095a69d9 106 if ((outputs & 0x04) == 0){
bobbaddeley 30:243e095a69d9 107 buzzer = 0;
bobbaddeley 30:243e095a69d9 108 }
bobbaddeley 30:243e095a69d9 109
bobbaddeley 30:243e095a69d9 110 if (outputs & 0x08){
bobbaddeley 30:243e095a69d9 111 rumblr = 1;
bobbaddeley 30:243e095a69d9 112 }
bobbaddeley 30:243e095a69d9 113 if ((outputs & 0x08) == 0){
bobbaddeley 30:243e095a69d9 114 rumblr = 0;
bobbaddeley 30:243e095a69d9 115 }
bobbaddeley 30:243e095a69d9 116
bobbaddeley 30:243e095a69d9 117 if (outputs & 0x10){
bobbaddeley 30:243e095a69d9 118 alarm_activated = 1;
bobbaddeley 30:243e095a69d9 119 }
bobbaddeley 30:243e095a69d9 120 if ((outputs & 0x10) == 0){
bobbaddeley 30:243e095a69d9 121 alarm_activated = 0;
bobbaddeley 30:243e095a69d9 122 alarm_on = 0;
bobbaddeley 30:243e095a69d9 123 }
bobbaddeley 30:243e095a69d9 124
bobbaddeley 30:243e095a69d9 125 if (outputs & 0x20){
bobbaddeley 30:243e095a69d9 126 alarm_on = 1;
bobbaddeley 30:243e095a69d9 127 }
bobbaddeley 30:243e095a69d9 128 if ((outputs & 0x20) == 0){
bobbaddeley 30:243e095a69d9 129 alarm_on = 0;
bobbaddeley 30:243e095a69d9 130 }
bobbaddeley 30:243e095a69d9 131 //}
Technicus 22:985657fc70c8 132 }
Technicus 22:985657fc70c8 133
Technicus 29:e7d4922a4620 134 void alarm() {
Technicus 29:e7d4922a4620 135 if (alarm_activated && alarm_on) { //Flag set to sound the alarm?
Technicus 29:e7d4922a4620 136
Technicus 29:e7d4922a4620 137 if (alarm_counter++ < 500) { //Beep it on and off
Technicus 29:e7d4922a4620 138 buzzer = 1;
Technicus 29:e7d4922a4620 139 led_0 = 1;
Technicus 29:e7d4922a4620 140 led_1 = 1;
Technicus 29:e7d4922a4620 141 rumblr = 1;
Technicus 29:e7d4922a4620 142 }
Technicus 29:e7d4922a4620 143 else {
Technicus 29:e7d4922a4620 144 if (alarm_counter > 1000){alarm_counter = 0;}
Technicus 29:e7d4922a4620 145 buzzer = 0;
Technicus 29:e7d4922a4620 146 led_0 = 0;
Technicus 29:e7d4922a4620 147 led_1 = 0;
Technicus 29:e7d4922a4620 148 rumblr = 0;
Technicus 29:e7d4922a4620 149 }
Technicus 29:e7d4922a4620 150 }
Technicus 29:e7d4922a4620 151 }
bobbaddeley 26:3a1d82a26a83 152
Technicus 29:e7d4922a4620 153 //void interruptButton_0() {
Technicus 29:e7d4922a4620 154
Technicus 29:e7d4922a4620 155 //}
Technicus 29:e7d4922a4620 156 //void interruptButton_1() {
Technicus 29:e7d4922a4620 157
Technicus 29:e7d4922a4620 158 //}
Technicus 29:e7d4922a4620 159 //void interruptButton_2() {
Technicus 29:e7d4922a4620 160
Technicus 29:e7d4922a4620 161 //}
Technicus 29:e7d4922a4620 162 //void interruptButton_3() {
Technicus 29:e7d4922a4620 163
Technicus 29:e7d4922a4620 164 //}
Technicus 29:e7d4922a4620 165 //void interruptSensor_0() { // Vibration
Technicus 29:e7d4922a4620 166 // alarm_on = 1;
Technicus 29:e7d4922a4620 167 //}
Technicus 29:e7d4922a4620 168 //void interruptSensor_1() { // Tilt
Technicus 29:e7d4922a4620 169 //
Technicus 29:e7d4922a4620 170 //}
Technicus 29:e7d4922a4620 171
apalmieri 13:227a0149b677 172 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
screamer 0:eb7f02ad28a7 173 {
apalmieri 13:227a0149b677 174 BLE& ble = params->ble;
apalmieri 13:227a0149b677 175 ble_error_t error = params->error;
screamer 0:eb7f02ad28a7 176
apalmieri 13:227a0149b677 177 if (error != BLE_ERROR_NONE) {
apalmieri 13:227a0149b677 178 onBleInitError(ble, error);
apalmieri 13:227a0149b677 179 return;
apalmieri 13:227a0149b677 180 }
apalmieri 13:227a0149b677 181
apalmieri 13:227a0149b677 182 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
apalmieri 13:227a0149b677 183 return;
apalmieri 13:227a0149b677 184 }
apalmieri 13:227a0149b677 185
screamer 0:eb7f02ad28a7 186 ble.gap().onDisconnection(disconnectionCallback);
screamer 0:eb7f02ad28a7 187
Technicus 22:985657fc70c8 188 ble.gattServer().onDataWritten(onDataWrittenCallback);
screamer 0:eb7f02ad28a7 189 /* Setup primary service. */
bobbaddeley 24:d352571b1c1f 190 BikeService bikeService(ble);
bobbaddeley 23:a31b178e2263 191 /* Setup battery service. */
bobbaddeley 23:a31b178e2263 192 BatteryService btService(ble,100);
screamer 0:eb7f02ad28a7 193 /* Setup advertising. */
screamer 0:eb7f02ad28a7 194 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
screamer 0:eb7f02ad28a7 195 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
bobbaddeley 23:a31b178e2263 196 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_CYCLING);
screamer 0:eb7f02ad28a7 197 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
screamer 0:eb7f02ad28a7 198 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
screamer 0:eb7f02ad28a7 199 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
screamer 0:eb7f02ad28a7 200 ble.gap().startAdvertising();
screamer 0:eb7f02ad28a7 201
screamer 0:eb7f02ad28a7 202 // infinite loop
apalmieri 13:227a0149b677 203 while (true) {
screamer 0:eb7f02ad28a7 204 // check for trigger from periodicCallback()
screamer 0:eb7f02ad28a7 205 if (triggerSensorPolling && ble.getGapState().connected) {
Technicus 29:e7d4922a4620 206 //if (ble.getGapState().connected) {
Technicus 29:e7d4922a4620 207
bobbaddeley 26:3a1d82a26a83 208
screamer 0:eb7f02ad28a7 209 triggerSensorPolling = false;
bobbaddeley 30:243e095a69d9 210 byteIn = sixButtons & buttonMask;
Technicus 29:e7d4922a4620 211 // update the ble with the inputs
bobbaddeley 30:243e095a69d9 212 //bikeService.updateInputs(byteOut);
bobbaddeley 30:243e095a69d9 213 //bikeService.updateTimestamp();
bobbaddeley 30:243e095a69d9 214 if (((byteIn & 0x01)==0) && alarm_activated==1 && alarm_on==0) {
bobbaddeley 30:243e095a69d9 215 alarm_on = 1;
bobbaddeley 30:243e095a69d9 216 outputs = outputs | 0x20;
bobbaddeley 30:243e095a69d9 217 bikeService.updateOutputs(outputs);
bobbaddeley 30:243e095a69d9 218 }
bobbaddeley 30:243e095a69d9 219 if (byteIn != prevByteIn){
Technicus 28:a56710056f4d 220 // update the ble with the inputs
bobbaddeley 30:243e095a69d9 221 bikeService.updateInputs(byteIn);
Technicus 28:a56710056f4d 222 bikeService.updateTimestamp();
Technicus 28:a56710056f4d 223 }
bobbaddeley 30:243e095a69d9 224 prevByteIn = byteIn;
Technicus 29:e7d4922a4620 225
screamer 0:eb7f02ad28a7 226 } else {
screamer 0:eb7f02ad28a7 227 ble.waitForEvent(); // low power wait for event
screamer 0:eb7f02ad28a7 228 }
bobbaddeley 26:3a1d82a26a83 229
Technicus 29:e7d4922a4620 230 alarm();
screamer 0:eb7f02ad28a7 231 }
screamer 0:eb7f02ad28a7 232 }
apalmieri 13:227a0149b677 233
apalmieri 13:227a0149b677 234 int main(void)
apalmieri 13:227a0149b677 235 {
Technicus 29:e7d4922a4620 236
Technicus 29:e7d4922a4620 237 //interruptEventButton_0.fall(&interruptButton_0);
Technicus 29:e7d4922a4620 238 //interruptEventButton_1.fall(&interruptButton_1);
Technicus 29:e7d4922a4620 239 //interruptEventButton_2.fall(&interruptButton_2);
Technicus 29:e7d4922a4620 240 //interruptEventButton_3.fall(&interruptButton_3);
Technicus 29:e7d4922a4620 241 //interruptEventSensor_0.fall(&interruptSensor_0); // Vibration
Technicus 29:e7d4922a4620 242 //interruptEventSensor_1.fall(&interruptSensor_1); // Tilt
Technicus 29:e7d4922a4620 243
apalmieri 13:227a0149b677 244 Ticker ticker;
Technicus 29:e7d4922a4620 245 ticker.attach(toggleLED, 1);
Technicus 29:e7d4922a4620 246
Technicus 29:e7d4922a4620 247 Ticker ticker_CallBack;
Technicus 29:e7d4922a4620 248 //ticker.attach(periodicCallback, 1); // blink LED every second
bobbaddeley 30:243e095a69d9 249 ticker_CallBack.attach(periodicCallback, 0.1);
Technicus 29:e7d4922a4620 250
apalmieri 13:227a0149b677 251 BLE::Instance().init(bleInitComplete);
apalmieri 13:227a0149b677 252 }
apalmieri 14:f715c13eb84f 253
Technicus 29:e7d4922a4620 254 // Reference
Technicus 29:e7d4922a4620 255 // http://files.amperka.ru/datasheets/nucleo-usermanual.pdf
Technicus 29:e7d4922a4620 256 // 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 257 // 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 258 // 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 259 // 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 260 // http://www.st.com/en/microcontrollers/stm32l476rg.html
Technicus 29:e7d4922a4620 261 // http://jeelabs.org/book/1547a/index.html
Technicus 29:e7d4922a4620 262 // 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