MtM+ / Mbed OS MtConnect04S_MtSense06

Dependencies:   MtSense06

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* Copyright (c) 2016 MtM Technology Corporation, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction, 
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or 
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 #include <events/mbed_events.h>
00019 #include <mbed.h>
00020 #include "ble/BLE.h"
00021 #include "ble/Gap.h"
00022 #include "ble/services/BatteryService.h"
00023 #include "ble/services/DeviceInformationService.h"
00024 #include "PulseOximeterService.h"
00025 #include "M1.h"
00026 
00027 /* 
00028  * set 0 disable M1 data send to uart
00029  *     1 enable M1 data send to urat
00030  */
00031 #define M1_UART_RAW_DATA_ENABLE     0
00032 
00033 DigitalOut ledRed(p16, 1);
00034 Serial pc(p5, p4);
00035 I2C i2c(p3, p2);
00036 M1 m1(i2c);
00037 
00038 const static char     DEVICE_NAME[] = "MtM_PLX";
00039 static const uint16_t uuid16_list[] = { 0x1822, /* UUID_PULSE_OXIMETER_SERVICE */
00040                                         GattService::UUID_BATTERY_SERVICE,
00041                                         GattService::UUID_DEVICE_INFORMATION_SERVICE};
00042 
00043 static PulseOximeterService* plxServicePtr;
00044 static BatteryService* batteryServicePtr;
00045 
00046 static EventQueue eventQueue(
00047     /* event count */ 16 * /* event size */ 32
00048 );
00049 
00050 
00051 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
00052 {
00053     BLE::Instance().gap().startAdvertising();
00054 }
00055 
00056 void blinkCallback(void)
00057 {
00058     ledRed = !ledRed;
00059 }
00060 
00061 void plxCallback(void)
00062 {
00063     M1::Plx plx;
00064     
00065     BLE &ble = BLE::Instance();
00066     if (ble.gap().getState().connected && m1.IsSkinIn()) {
00067         m1.GetPlx(&plx);
00068         plxServicePtr->updatePlxMeas((float)plx.spo2, (float)plx.pulseRate);
00069     }
00070 }
00071 
00072 void rawCallback(void)
00073 {
00074     M1::Raw raw;
00075     static uint8_t cnt = 0;
00076     static uint8_t raw_x3[6*3];
00077 
00078     BLE &ble = BLE::Instance();
00079     if (ble.gap().getState().connected && m1.IsSkinIn()) {
00080         m1.GetRaw(&raw);
00081         
00082         raw_x3[6*cnt+0] = (uint8_t)(raw.red   >> 8);
00083         raw_x3[6*cnt+1] = (uint8_t)(raw.red   >> 0);
00084         raw_x3[6*cnt+2] = (uint8_t)(raw.ir    >> 8);
00085         raw_x3[6*cnt+3] = (uint8_t)(raw.ir    >> 0);
00086         raw_x3[6*cnt+4] = (uint8_t)(raw.green >> 8);
00087         raw_x3[6*cnt+5] = (uint8_t)(raw.green >> 0);
00088         
00089         if (++cnt >= 3) {
00090             plxServicePtr->updateRaw(raw_x3);
00091             cnt = 0;
00092         }
00093     } else {
00094         cnt = 0;
00095     }
00096 }
00097 
00098 void rawCallbackToUART() {
00099     M1::Raw raw;
00100     if(m1.IsSkinIn()) {
00101             m1.GetRaw(&raw);  
00102             pc.printf("%d,%d,%d\r\n",raw.red, raw.ir, raw.green);
00103         }   
00104 }
00105 
00106 void StatusCallback(void)
00107 {
00108     M1::Status sta;
00109     
00110     BLE &ble = BLE::Instance();
00111     if (ble.gap().getState().connected) {
00112         m1.GetStatus(&sta);
00113         plxServicePtr->updateStatusFlagAndSignalQuality(sta.flags, sta.signalQuality);
00114     }  
00115 }
00116 
00117 void batteryCallback(void )
00118 {
00119     uint8_t batteryLevel = 99;
00120 
00121     BLE &ble = BLE::Instance();
00122     if (ble.gap().getState().connected) {
00123         batteryServicePtr->updateBatteryLevel(batteryLevel);
00124     }
00125 }
00126 
00127 /**
00128  * This function is called when the ble initialization process has failled
00129  */
00130 void onBleInitError(BLE &ble, ble_error_t error)
00131 {
00132     /* Initialization error handling should go here */
00133 }
00134 
00135 /**
00136  * Callback triggered when the ble initialization process has finished
00137  */
00138 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00139 {
00140     BLE&        ble   = params->ble;
00141     ble_error_t error = params->error;
00142 
00143     if (error != BLE_ERROR_NONE) {
00144         /* In case of error, forward the error handling to onBleInitError */
00145         onBleInitError(ble, error);
00146         return;
00147     }
00148 
00149     /* Ensure that it is the default instance of BLE */
00150     if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00151         return;
00152     }
00153 
00154     ble.gap().onDisconnection(disconnectionCallback);
00155 
00156     /* Setup primary service */
00157     plxServicePtr     = new PulseOximeterService(ble, 0, 0);
00158     batteryServicePtr = new BatteryService(ble, 100);
00159     DeviceInformationService deviceInfo(ble, "MtM");
00160 
00161     /* Setup advertising */
00162     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00163     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list));
00164     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
00165     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::PULSE_OXIMETER_GENERIC);
00166     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00167     ble.gap().setAdvertisingInterval(1000); /* 1000ms */
00168     ble.gap().startAdvertising();
00169 }
00170 
00171 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00172     BLE &ble = BLE::Instance();
00173     eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
00174 }
00175 
00176 int main()
00177 {
00178     /* Disable the hardware flow control of Serial, then show the mbed version */
00179     pc.set_flow_control(SerialBase::Disabled);
00180     pc.baud(115200);
00181     pc.printf("\r\n");
00182     pc.printf("mbed version(%d.%d.%d)\r\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
00183     pc.printf("\r\n");
00184 
00185     /* Config device */
00186     m1.ConfigDevice();
00187 
00188 #if M1_UART_RAW_DATA_ENABLE
00189     /* 35ms getter raw data to uart */
00190     eventQueue.call_every(35,   rawCallbackToUART);
00191     eventQueue.call_every(500,  blinkCallback);
00192 #else
00193     /* Update each data every N ms */
00194     eventQueue.call_every(1000, plxCallback);
00195     eventQueue.call_every(35,   rawCallback);
00196     eventQueue.call_every(1000, StatusCallback);
00197     eventQueue.call_every(500,  batteryCallback);
00198     eventQueue.call_every(500,  blinkCallback);
00199 
00200     BLE &ble = BLE::Instance();
00201     ble.onEventsToProcess(scheduleBleEventsProcessing);
00202     ble.init(bleInitComplete);
00203 #endif    
00204 
00205     eventQueue.dispatch_forever();
00206 
00207     return 0;
00208 }