Roy Sandberg / Mbed 2 deprecated BLE_ECG

Dependencies:   BLE_API Queue mbed nRF51822

Fork of BLE_HeartRate by Bluetooth Low Energy

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-2013 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 <qrsdet.h>
00019 #include "queue.h"
00020  
00021 #include "BLEDevice.h"
00022 #include "HeartRateService.h"
00023 #include "DeviceInformationService.h"
00024 
00025 /* Enable the following if you need to throttle the connection interval. This has
00026  * the effect of reducing energy consumption after a connection is made;
00027  * particularly for applications where the central may want a fast connection
00028  * interval.*/
00029 #define UPDATE_PARAMS_FOR_LONGER_CONNECTION_INTERVAL 0
00030 
00031 // SAMPLE_RATE is defined in qrsdet.h
00032 #define MS_PER_SAMPLE (1000/SAMPLE_RATE)
00033 
00034 extern void setup_sampler(void (*function)(uint32_t));
00035 extern int BeatDetectAndClassify(int ecgSample, int *beatType, int *beatMatch); // defined in bdac.cpp
00036 extern void ResetBDAC(void);
00037     
00038 BLEDevice  ble;
00039 DigitalOut led1(LED1);
00040 PwmOut LRA(P0_15);
00041 InterruptIn button1(P0_17); // button 1
00042 InterruptIn button2(P0_18); // button 2
00043 InterruptIn button3(P0_19); // button 3
00044 InterruptIn button4(P0_20); // button 4
00045 
00046  
00047 //Serial pc (P0_9, P0_11);  // TX, RX
00048 
00049 volatile uint8_t hrmCounter = 128; 
00050 volatile uint16_t ecgSample = 0;
00051 volatile int sampleCounter=0;
00052 
00053 #define ITEMS_IN_QUEUE 50
00054 Queue ecgQueue ( sizeof(int), ITEMS_IN_QUEUE ); // queue of hrmCounter values
00055 bool itemAddedToQueue = true;
00056 
00057 
00058 const static char     DEVICE_NAME[]        = "HRM1";
00059 static const uint16_t uuid16_list[]        = {GattService::UUID_HEART_RATE_SERVICE,
00060         GattService::UUID_DEVICE_INFORMATION_SERVICE
00061                                              };
00062 
00063 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00064 {
00065     ble.startAdvertising(); // restart advertising
00066 }
00067 
00068 
00069 void power0() {
00070     LRA.write(0.0);
00071 }
00072 void power1() {
00073     LRA.write(0.55);
00074 }
00075 void power2() {
00076     LRA.write(0.85);
00077 }
00078 void power3() {
00079     LRA.write(1.0);
00080 }
00081 
00082 void sampler_callback(uint32_t value)
00083 {
00084     //hrmCounter = (uint8_t) ((value+127) % 255);
00085     ecgSample = (uint16_t) value;
00086     itemAddedToQueue = ecgQueue.PutIrq((void*)&ecgSample);
00087 }
00088 
00089 
00090 int main(void)
00091 {
00092     uint16_t value;
00093     int beatType;
00094     int beatMatch;
00095     int samplesSinceLastR;
00096     int lastSamplesSinceLastR=0;
00097     int sampleOffset=0;
00098     char* beatName;
00099     
00100     led1 = 1;
00101     
00102     // Ticker ticker;
00103     //ticker.attach(periodicCallback, 0.1); // blink LED every second
00104 
00105     button1.rise(&power0);
00106     button2.rise(&power1);
00107     button3.rise(&power2);
00108     button4.rise(&power3);
00109 
00110     LRA.period_us(50); // 50 uS -> 20 Khz (needs to be between 10Khz and 250Khz)
00111     LRA.write(0.0); // Off. < 50% = 0ff
00112     
00113     printf("Initializing BLE...\r\n");
00114              
00115     ble.init();
00116     ble.onDisconnection(disconnectionCallback);
00117 
00118     /* Setup primary service. */
00119     //uint8_t hrmCounter = 100; // init HRM to 100bps
00120     HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
00121 
00122     /* Setup auxiliary service. */
00123     DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
00124 
00125     /* Setup advertising. */
00126     printf("Setting up advertising...\r\n");
00127     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00128     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00129     ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
00130     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00131     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00132     ble.setAdvertisingInterval(1000);
00133     ble.startAdvertising();
00134 
00135     setup_sampler(&sampler_callback);    
00136     
00137     ResetBDAC(); // reset the beat detector and classifier
00138     
00139     printf("Starting...\r\n");
00140      
00141     // infinite loop
00142     while (1) {
00143         // check for trigger from periodicCallback()
00144         if (ble.getGapState().connected) {
00145             while (ecgQueue.GetNumberOfItems()>0) {
00146                 ecgQueue.Get(&value);
00147                 samplesSinceLastR = BeatDetectAndClassify(value, &beatType, &beatMatch);
00148                 if (samplesSinceLastR != 0) {
00149                     printf("[C] samplesSinceLastR=%d, type=%d\r\n", value, beatType);
00150                 }
00151                 //hrService.updateHeartRate(value);
00152                 led1 = !led1;
00153             }
00154         } else {
00155             if (!itemAddedToQueue) {
00156                 printf("Queue overflow.\n\r");
00157                 itemAddedToQueue = true;
00158             }
00159             while (ecgQueue.GetNumberOfItems()>0) {
00160                 sampleCounter++;
00161                 ecgQueue.Get(&value);
00162                 samplesSinceLastR = BeatDetectAndClassify(value, &beatType, &beatMatch);
00163                 if (samplesSinceLastR != 0) {                    
00164                     sampleOffset = lastSamplesSinceLastR - samplesSinceLastR;
00165                     
00166                     if (beatType == 1) {
00167                         beatName = "Normal";
00168                     } else if (beatType == 5) {
00169                         beatName = "Ectopic";
00170                     } else {
00171                         beatName = "Unknown";
00172                     }
00173                     printf("[NC] interval_ms=%d, bpm=%d, samplesSinceLastR=%d  (%s)\r\n", ((sampleCounter-sampleOffset)*MS_PER_SAMPLE), (60000/((sampleCounter-sampleOffset)*MS_PER_SAMPLE)), value, beatName);
00174                     sampleCounter=0;
00175                     lastSamplesSinceLastR = samplesSinceLastR;
00176                 }
00177             }
00178             ble.waitForEvent(); // low power wait for event
00179         }
00180     }
00181 }