We are making a bluetooth application for a vehicle.

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_HeartRate_IDB0XA1 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "ble/BLE.h"
00019 #include "bike_service.h"
00020 #include "ble/services/BatteryService.h"
00021 
00022 int alarm_activated = 0;
00023 int alarm_on = 0;
00024 int alarm_counter = 0;
00025 
00026 DigitalOut led_0(PC_6);
00027 DigitalOut led_1(PC_7);
00028 DigitalOut buzzer(PC_8);
00029 DigitalOut rumblr(PC_9);;
00030 DigitalOut led1(LED1, 1);
00031 
00032 const static char     DEVICE_NAME[]        = "HeckBike!";
00033 static const uint16_t uuid16_list[]        = {GattService::UUID_BATTERY_SERVICE,
00034                                               0x8EC5};//made up UUID for the Heck bike
00035 
00036 #define on  0xFFFF
00037 #define off 0
00038  
00039 #define buttonMask 0x003F
00040  
00041 PortIn sixButtons(PortC, buttonMask);
00042 
00043 //InterruptIn event(sixButtons.read());
00044 //InterruptIn interruptEventButton_0(PC_2);
00045 //InterruptIn interruptEventButton_1(PC_3);
00046 //InterruptIn interruptEventButton_2(PC_4);
00047 //InterruptIn interruptEventButton_3(PC_5);
00048 //InterruptIn interruptEventSensor_0(PC_0); // Vibration
00049 //InterruptIn interruptEventSensor_1(PC_1); // Tilt
00050 
00051 unsigned char byteIn = 0; 
00052 unsigned char prevByteIn = 0;
00053 
00054 uint8_t inputs = 0x00;
00055 uint8_t outputs = 0x00;
00056 uint8_t old_outputs = 0x00;
00057 uint32_t timestamp = 0x00;
00058     
00059 static volatile bool  triggerSensorPolling = false;
00060 
00061 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
00062 {
00063     (void)params;
00064     BLE::Instance().gap().startAdvertising(); // restart advertising
00065 }
00066 
00067 void toggleLED(void)
00068 {
00069     led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
00070 }
00071 
00072 void periodicCallback(void)
00073 {
00074     /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
00075      * heavy-weight sensor polling from the main thread. */
00076     triggerSensorPolling = true;
00077 }
00078 
00079 void onBleInitError(BLE &ble, ble_error_t error)
00080 {
00081     (void)ble;
00082     (void)error;
00083    /* Initialization error handling should go here */
00084 }
00085 
00086 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
00087     //if (params->handle == BikeService.output_characteristic.getValueAttribute().getHandle()) {
00088         outputs = *(params->data);
00089         if (outputs & 0x01){
00090             led_0 = 1;
00091         }
00092         if ((outputs & 0x01) == 0){
00093             led_0 = 0;
00094         }
00095             
00096         if (outputs & 0x02){
00097             led_1 = 1;
00098         }
00099         if ((outputs & 0x02) == 0){
00100             led_1 = 0;
00101         }
00102             
00103         if (outputs & 0x04){
00104             buzzer = 1;
00105             }
00106         if ((outputs & 0x04) == 0){
00107             buzzer = 0;
00108         }
00109             
00110         if (outputs & 0x08){
00111             rumblr = 1;
00112         }
00113         if ((outputs & 0x08) == 0){
00114             rumblr = 0;
00115         }
00116             
00117         if (outputs & 0x10){
00118             alarm_activated = 1;
00119         }
00120         if ((outputs & 0x10) == 0){
00121             alarm_activated = 0;
00122             alarm_on = 0;
00123         }
00124         
00125         if (outputs & 0x20){
00126             alarm_on = 1;
00127         }
00128         if ((outputs & 0x20) == 0){
00129             alarm_on = 0;
00130         }
00131     //}
00132 }
00133 
00134 void alarm() {
00135      if (alarm_activated && alarm_on) {                                        //Flag set to sound the alarm?
00136             
00137             if (alarm_counter++ < 500) {                            //Beep it on and off
00138                 buzzer = 1;
00139                 led_0 = 1;
00140                 led_1 = 1;
00141                 rumblr = 1;
00142             }
00143             else {
00144                 if (alarm_counter > 1000){alarm_counter = 0;}
00145                 buzzer = 0;
00146                 led_0 = 0;
00147                 led_1 = 0;
00148                 rumblr = 0;
00149             }
00150         }
00151 }
00152 
00153 //void interruptButton_0() {
00154 
00155 //} 
00156 //void interruptButton_1() {
00157     
00158 //}
00159 //void interruptButton_2() {
00160 
00161 //} 
00162 //void interruptButton_3() {
00163     
00164 //}  
00165 //void interruptSensor_0() { // Vibration
00166 //    alarm_on = 1;
00167 //} 
00168 //void interruptSensor_1() { // Tilt
00169 //    
00170 //}
00171  
00172 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00173 {
00174     BLE&        ble   = params->ble;
00175     ble_error_t error = params->error;
00176 
00177     if (error != BLE_ERROR_NONE) {
00178         onBleInitError(ble, error);
00179         return;
00180     }
00181 
00182     if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00183         return;
00184     }
00185 
00186     ble.gap().onDisconnection(disconnectionCallback);
00187 
00188     ble.gattServer().onDataWritten(onDataWrittenCallback);
00189     /* Setup primary service. */
00190     BikeService bikeService(ble);
00191     /* Setup battery service. */
00192     BatteryService btService(ble,100);
00193     /* Setup advertising. */
00194     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00195     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00196     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_CYCLING);
00197     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00198     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00199     ble.gap().setAdvertisingInterval(1000); /* 1000ms */
00200     ble.gap().startAdvertising();
00201 
00202     // infinite loop
00203     while (true) {
00204         // check for trigger from periodicCallback()
00205         if (triggerSensorPolling && ble.getGapState().connected) {
00206         //if (ble.getGapState().connected) {
00207             
00208             
00209             triggerSensorPolling = false;
00210             byteIn = sixButtons & buttonMask;
00211             // update the ble with the inputs
00212             //bikeService.updateInputs(byteOut);
00213             //bikeService.updateTimestamp();
00214             if (((byteIn & 0x01)==0) && alarm_activated==1 && alarm_on==0) {
00215                 alarm_on = 1;
00216                 outputs = outputs | 0x20;
00217                 bikeService.updateOutputs(outputs);
00218              }
00219             if (byteIn != prevByteIn){
00220                 // update the ble with the inputs
00221                 bikeService.updateInputs(byteIn);
00222                 bikeService.updateTimestamp();
00223             }
00224             prevByteIn = byteIn;
00225              
00226         } else {
00227             ble.waitForEvent(); // low power wait for event
00228         }
00229         
00230         alarm();     
00231     }
00232 }
00233 
00234 int main(void)
00235 {
00236     
00237     //interruptEventButton_0.fall(&interruptButton_0);
00238     //interruptEventButton_1.fall(&interruptButton_1);
00239     //interruptEventButton_2.fall(&interruptButton_2);
00240     //interruptEventButton_3.fall(&interruptButton_3);
00241     //interruptEventSensor_0.fall(&interruptSensor_0); // Vibration
00242     //interruptEventSensor_1.fall(&interruptSensor_1); // Tilt
00243     
00244     Ticker ticker;
00245     ticker.attach(toggleLED, 1);
00246     
00247     Ticker ticker_CallBack;
00248     //ticker.attach(periodicCallback, 1); // blink LED every second
00249     ticker_CallBack.attach(periodicCallback, 0.1);
00250     
00251     BLE::Instance().init(bleInitComplete);
00252 }
00253 
00254 // Reference
00255 // http://files.amperka.ru/datasheets/nucleo-usermanual.pdf
00256 // 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
00257 // https://developer.mbed.org/users/mbed_official/code/mbed-dev/file/default/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PinNames.h
00258 // https://developer.mbed.org/users/mbed_official/code/mbed-dev/file/default/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralPins.c
00259 // 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
00260 // http://www.st.com/en/microcontrollers/stm32l476rg.html
00261 // http://jeelabs.org/book/1547a/index.html
00262 // 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