士鈞 林 / Mbed OS 12_1

Dependencies:   X_NUCLEO_IKS01A2

Committer:
jim_lsj
Date:
Wed Apr 29 10:42:44 2020 +0000
Revision:
0:9c0e0ac79e75
Child:
1:b12ac7b02a21
12_1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jim_lsj 0:9c0e0ac79e75 1 /* mbed Microcontroller Library
jim_lsj 0:9c0e0ac79e75 2 * Copyright (c) 2006-2015 ARM Limited
jim_lsj 0:9c0e0ac79e75 3 *
jim_lsj 0:9c0e0ac79e75 4 * Licensed under the Apache License, Version 2.0 (the "License");
jim_lsj 0:9c0e0ac79e75 5 * you may not use this file except in compliance with the License.
jim_lsj 0:9c0e0ac79e75 6 * You may obtain a copy of the License at
jim_lsj 0:9c0e0ac79e75 7 *
jim_lsj 0:9c0e0ac79e75 8 * http://www.apache.org/licenses/LICENSE-2.0
jim_lsj 0:9c0e0ac79e75 9 *
jim_lsj 0:9c0e0ac79e75 10 * Unless required by applicable law or agreed to in writing, software
jim_lsj 0:9c0e0ac79e75 11 * distributed under the License is distributed on an "AS IS" BASIS,
jim_lsj 0:9c0e0ac79e75 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
jim_lsj 0:9c0e0ac79e75 13 * See the License for the specific language governing permissions and
jim_lsj 0:9c0e0ac79e75 14 * limitations under the License.
jim_lsj 0:9c0e0ac79e75 15 */
jim_lsj 0:9c0e0ac79e75 16
jim_lsj 0:9c0e0ac79e75 17 #include <events/mbed_events.h>
jim_lsj 0:9c0e0ac79e75 18 #include <mbed.h>
jim_lsj 0:9c0e0ac79e75 19 #include "ble/BLE.h"
jim_lsj 0:9c0e0ac79e75 20 #include "ble/gap/Gap.h"
jim_lsj 0:9c0e0ac79e75 21 //#include "ble/services/EnvironmentalSensingService2.h"
jim_lsj 0:9c0e0ac79e75 22 #include "ble/services/BatteryService.h"
jim_lsj 0:9c0e0ac79e75 23 #include "ble/services/HeartRateService.h"
jim_lsj 0:9c0e0ac79e75 24 #include "ble/services/DeviceInformationService.h"
jim_lsj 0:9c0e0ac79e75 25 #include "pretty_printer.h"
jim_lsj 0:9c0e0ac79e75 26
jim_lsj 0:9c0e0ac79e75 27 //#include "BLEDevice.h"
jim_lsj 0:9c0e0ac79e75 28 #include "blecommon.h"
jim_lsj 0:9c0e0ac79e75 29 #include "Gap.h"
jim_lsj 0:9c0e0ac79e75 30 #include "GattServer.h"
jim_lsj 0:9c0e0ac79e75 31 //#include "BLEDeviceInstanceBase.h"
jim_lsj 0:9c0e0ac79e75 32
jim_lsj 0:9c0e0ac79e75 33 #include "XNucleoIKS01A2.h"
jim_lsj 0:9c0e0ac79e75 34 #include "ESS.h"
jim_lsj 0:9c0e0ac79e75 35 #include "ESS2.h"
jim_lsj 0:9c0e0ac79e75 36
jim_lsj 0:9c0e0ac79e75 37 const static char DEVICE_NAME[] = "Heartrate";
jim_lsj 0:9c0e0ac79e75 38
jim_lsj 0:9c0e0ac79e75 39
jim_lsj 0:9c0e0ac79e75 40
jim_lsj 0:9c0e0ac79e75 41 // new code
jim_lsj 0:9c0e0ac79e75 42 static XNucleoIKS01A2 *Sensors = XNucleoIKS01A2::instance(D14, D15, D4, D5);
jim_lsj 0:9c0e0ac79e75 43 float TEMPERATURE_C = 20;
jim_lsj 0:9c0e0ac79e75 44 float HUMIDITY = 50;
jim_lsj 0:9c0e0ac79e75 45 float PRESSURE = 1000;
jim_lsj 0:9c0e0ac79e75 46 float WIND_DIRECTION = 0;
jim_lsj 0:9c0e0ac79e75 47 int16_t MagRaw[3];
jim_lsj 0:9c0e0ac79e75 48 AxesRaw_TypeDef MAGNETIC;
jim_lsj 0:9c0e0ac79e75 49 const static char DEVICE_NAME[] = "WEATHER";
jim_lsj 0:9c0e0ac79e75 50 static const uint16_t uuid16_list[] = {0x181A};
jim_lsj 0:9c0e0ac79e75 51
jim_lsj 0:9c0e0ac79e75 52 static volatile bool triggerSensorPolling = false;
jim_lsj 0:9c0e0ac79e75 53 //end
jim_lsj 0:9c0e0ac79e75 54
jim_lsj 0:9c0e0ac79e75 55 static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE);
jim_lsj 0:9c0e0ac79e75 56
jim_lsj 0:9c0e0ac79e75 57 class HeartrateDemo : ble::Gap::EventHandler {
jim_lsj 0:9c0e0ac79e75 58 public:
jim_lsj 0:9c0e0ac79e75 59 HeartrateDemo(BLE &ble, events::EventQueue &event_queue) :
jim_lsj 0:9c0e0ac79e75 60 _ble(ble),
jim_lsj 0:9c0e0ac79e75 61 _event_queue(event_queue),
jim_lsj 0:9c0e0ac79e75 62 _led1(LED1, 1),
jim_lsj 0:9c0e0ac79e75 63 _connected(false),
jim_lsj 0:9c0e0ac79e75 64 _hr_counter(100),
jim_lsj 0:9c0e0ac79e75 65 _bt_service(ble, 25),
jim_lsj 0:9c0e0ac79e75 66 _hr_service(ble, _hr_counter, HeartRateService::LOCATION_FINGER),
jim_lsj 0:9c0e0ac79e75 67 _deviceInfo(ble, "ST", "Nucleo", "SN1" ),
jim_lsj 0:9c0e0ac79e75 68 _adv_data_builder(_adv_buffer),
jim_lsj 0:9c0e0ac79e75 69
jim_lsj 0:9c0e0ac79e75 70 _air (ble, (uint16_t) HUMIDITY, (int16_t) TEMPERATURE_C ),
jim_lsj 0:9c0e0ac79e75 71 _wind (ble, (uint16_t) WIND_DIRECTION, (uint32_t) PRESSURE)
jim_lsj 0:9c0e0ac79e75 72 {
jim_lsj 0:9c0e0ac79e75 73 //_uuid_list = new UUID(3);
jim_lsj 0:9c0e0ac79e75 74 // _uuid_list[0] = GattService::UUID_HEART_RATE_SERVICE;
jim_lsj 0:9c0e0ac79e75 75 // _uuid_list[1] = GattService::UUID_BATTERY_SERVICE;
jim_lsj 0:9c0e0ac79e75 76 // _uuid_list[2] = GattService::UUID_DEVICE_INFORMATION_SERVICE;
jim_lsj 0:9c0e0ac79e75 77 }
jim_lsj 0:9c0e0ac79e75 78 ~HeartrateDemo(){
jim_lsj 0:9c0e0ac79e75 79 delete [] _uuid_list;
jim_lsj 0:9c0e0ac79e75 80 }
jim_lsj 0:9c0e0ac79e75 81
jim_lsj 0:9c0e0ac79e75 82 void start() {
jim_lsj 0:9c0e0ac79e75 83 _ble.gap().setEventHandler(this);
jim_lsj 0:9c0e0ac79e75 84
jim_lsj 0:9c0e0ac79e75 85 _ble.init(this, &HeartrateDemo::on_init_complete);
jim_lsj 0:9c0e0ac79e75 86
jim_lsj 0:9c0e0ac79e75 87 _event_queue.call_every(500, this, &HeartrateDemo::blink);
jim_lsj 0:9c0e0ac79e75 88 _event_queue.call_every(1000, this, &HeartrateDemo::update_sensor_value);
jim_lsj 0:9c0e0ac79e75 89
jim_lsj 0:9c0e0ac79e75 90 _event_queue.dispatch_forever();
jim_lsj 0:9c0e0ac79e75 91 }
jim_lsj 0:9c0e0ac79e75 92
jim_lsj 0:9c0e0ac79e75 93 private:
jim_lsj 0:9c0e0ac79e75 94 /** Callback triggered when the ble initialization process has finished */
jim_lsj 0:9c0e0ac79e75 95 void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
jim_lsj 0:9c0e0ac79e75 96 if (params->error != BLE_ERROR_NONE) {
jim_lsj 0:9c0e0ac79e75 97 printf("Ble initialization failed.");
jim_lsj 0:9c0e0ac79e75 98 return;
jim_lsj 0:9c0e0ac79e75 99 }
jim_lsj 0:9c0e0ac79e75 100
jim_lsj 0:9c0e0ac79e75 101 print_mac_address();
jim_lsj 0:9c0e0ac79e75 102
jim_lsj 0:9c0e0ac79e75 103 start_advertising();
jim_lsj 0:9c0e0ac79e75 104 }
jim_lsj 0:9c0e0ac79e75 105
jim_lsj 0:9c0e0ac79e75 106 void start_advertising() {
jim_lsj 0:9c0e0ac79e75 107 /* Create advertising parameters and payload */
jim_lsj 0:9c0e0ac79e75 108
jim_lsj 0:9c0e0ac79e75 109 ble::AdvertisingParameters adv_parameters(
jim_lsj 0:9c0e0ac79e75 110 ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
jim_lsj 0:9c0e0ac79e75 111 ble::adv_interval_t(ble::millisecond_t(1000))
jim_lsj 0:9c0e0ac79e75 112 );
jim_lsj 0:9c0e0ac79e75 113
jim_lsj 0:9c0e0ac79e75 114 _adv_data_builder.setFlags();
jim_lsj 0:9c0e0ac79e75 115 _adv_data_builder.setAppearance(ble::adv_data_appearance_t::GENERIC_THERMOMETER);
jim_lsj 0:9c0e0ac79e75 116 _adv_data_builder.setLocalServiceList(mbed::make_Span(&uuid16_list, 1));
jim_lsj 0:9c0e0ac79e75 117 _adv_data_builder.setName(DEVICE_NAME);
jim_lsj 0:9c0e0ac79e75 118
jim_lsj 0:9c0e0ac79e75 119 /* Setup advertising */
jim_lsj 0:9c0e0ac79e75 120
jim_lsj 0:9c0e0ac79e75 121 ble_error_t error = _ble.gap().setAdvertisingParameters(
jim_lsj 0:9c0e0ac79e75 122 ble::LEGACY_ADVERTISING_HANDLE,
jim_lsj 0:9c0e0ac79e75 123 adv_parameters
jim_lsj 0:9c0e0ac79e75 124 );
jim_lsj 0:9c0e0ac79e75 125
jim_lsj 0:9c0e0ac79e75 126 if (error) {
jim_lsj 0:9c0e0ac79e75 127 printf("_ble.gap().setAdvertisingParameters() failed\r\n");
jim_lsj 0:9c0e0ac79e75 128 return;
jim_lsj 0:9c0e0ac79e75 129 }
jim_lsj 0:9c0e0ac79e75 130
jim_lsj 0:9c0e0ac79e75 131 error = _ble.gap().setAdvertisingPayload(
jim_lsj 0:9c0e0ac79e75 132 ble::LEGACY_ADVERTISING_HANDLE,
jim_lsj 0:9c0e0ac79e75 133 _adv_data_builder.getAdvertisingData()
jim_lsj 0:9c0e0ac79e75 134 );
jim_lsj 0:9c0e0ac79e75 135
jim_lsj 0:9c0e0ac79e75 136 if (error) {
jim_lsj 0:9c0e0ac79e75 137 printf("_ble.gap().setAdvertisingPayload() failed\r\n");
jim_lsj 0:9c0e0ac79e75 138 return;
jim_lsj 0:9c0e0ac79e75 139 }
jim_lsj 0:9c0e0ac79e75 140
jim_lsj 0:9c0e0ac79e75 141 /* Start advertising */
jim_lsj 0:9c0e0ac79e75 142
jim_lsj 0:9c0e0ac79e75 143 error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
jim_lsj 0:9c0e0ac79e75 144
jim_lsj 0:9c0e0ac79e75 145 if (error) {
jim_lsj 0:9c0e0ac79e75 146 printf("_ble.gap().startAdvertising() failed\r\n");
jim_lsj 0:9c0e0ac79e75 147 return;
jim_lsj 0:9c0e0ac79e75 148 }
jim_lsj 0:9c0e0ac79e75 149 }
jim_lsj 0:9c0e0ac79e75 150
jim_lsj 0:9c0e0ac79e75 151 void update_sensor_value() {
jim_lsj 0:9c0e0ac79e75 152 if (_connected) {
jim_lsj 0:9c0e0ac79e75 153 // Do blocking calls or whatever is necessary for sensor polling.
jim_lsj 0:9c0e0ac79e75 154 // In our case, we simply update the HRM measurement.
jim_lsj 0:9c0e0ac79e75 155 Sensors->hts221.GetTemperature((float *)&TEMPERATURE_C);
jim_lsj 0:9c0e0ac79e75 156 Sensors->hts221.GetHumidity((float *)&HUMIDITY);
jim_lsj 0:9c0e0ac79e75 157 Sensors->lps25h.GetPressure((float *)&PRESSURE);
jim_lsj 0:9c0e0ac79e75 158 Sensors->lis3mdl.GetAxes((AxesRaw_TypeDef *)&MAGNETIC);
jim_lsj 0:9c0e0ac79e75 159
jim_lsj 0:9c0e0ac79e75 160 _hr_service.updateHeartRate(_hr_counter);
jim_lsj 0:9c0e0ac79e75 161 }
jim_lsj 0:9c0e0ac79e75 162 }
jim_lsj 0:9c0e0ac79e75 163
jim_lsj 0:9c0e0ac79e75 164 void blink(void) {
jim_lsj 0:9c0e0ac79e75 165 _led1 = !_led1;
jim_lsj 0:9c0e0ac79e75 166 }
jim_lsj 0:9c0e0ac79e75 167
jim_lsj 0:9c0e0ac79e75 168 private:
jim_lsj 0:9c0e0ac79e75 169 /* Event handler */
jim_lsj 0:9c0e0ac79e75 170
jim_lsj 0:9c0e0ac79e75 171 void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) {
jim_lsj 0:9c0e0ac79e75 172 _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
jim_lsj 0:9c0e0ac79e75 173 _connected = false;
jim_lsj 0:9c0e0ac79e75 174 }
jim_lsj 0:9c0e0ac79e75 175
jim_lsj 0:9c0e0ac79e75 176 virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) {
jim_lsj 0:9c0e0ac79e75 177 if (event.getStatus() == BLE_ERROR_NONE) {
jim_lsj 0:9c0e0ac79e75 178 _connected = true;
jim_lsj 0:9c0e0ac79e75 179 }
jim_lsj 0:9c0e0ac79e75 180 }
jim_lsj 0:9c0e0ac79e75 181
jim_lsj 0:9c0e0ac79e75 182 private:
jim_lsj 0:9c0e0ac79e75 183 BLE &_ble;
jim_lsj 0:9c0e0ac79e75 184 events::EventQueue &_event_queue;
jim_lsj 0:9c0e0ac79e75 185 DigitalOut _led1;
jim_lsj 0:9c0e0ac79e75 186
jim_lsj 0:9c0e0ac79e75 187 bool _connected;
jim_lsj 0:9c0e0ac79e75 188
jim_lsj 0:9c0e0ac79e75 189 UUID * _uuid_list;
jim_lsj 0:9c0e0ac79e75 190
jim_lsj 0:9c0e0ac79e75 191 uint8_t _hr_counter;
jim_lsj 0:9c0e0ac79e75 192 HeartRateService _hr_service;
jim_lsj 0:9c0e0ac79e75 193
jim_lsj 0:9c0e0ac79e75 194 uint8_t _battery_level;
jim_lsj 0:9c0e0ac79e75 195 BatteryService _bt_service;
jim_lsj 0:9c0e0ac79e75 196
jim_lsj 0:9c0e0ac79e75 197 ESS _air;
jim_lsj 0:9c0e0ac79e75 198 ESS2 _wind;
jim_lsj 0:9c0e0ac79e75 199
jim_lsj 0:9c0e0ac79e75 200
jim_lsj 0:9c0e0ac79e75 201 DeviceInformationService _deviceInfo;
jim_lsj 0:9c0e0ac79e75 202
jim_lsj 0:9c0e0ac79e75 203 uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
jim_lsj 0:9c0e0ac79e75 204 ble::AdvertisingDataBuilder _adv_data_builder;
jim_lsj 0:9c0e0ac79e75 205 };
jim_lsj 0:9c0e0ac79e75 206
jim_lsj 0:9c0e0ac79e75 207 /** Schedule processing of events from the BLE middleware in the event queue. */
jim_lsj 0:9c0e0ac79e75 208 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
jim_lsj 0:9c0e0ac79e75 209 event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));
jim_lsj 0:9c0e0ac79e75 210 }
jim_lsj 0:9c0e0ac79e75 211
jim_lsj 0:9c0e0ac79e75 212 int main()
jim_lsj 0:9c0e0ac79e75 213 {
jim_lsj 0:9c0e0ac79e75 214 static XNucleoIKS01A2 *Sensors = XNucleoIKS01A2::instance(D14, D15, D4, D5);
jim_lsj 0:9c0e0ac79e75 215 BLE &ble = BLE::Instance();
jim_lsj 0:9c0e0ac79e75 216 ble.onEventsToProcess(schedule_ble_events);
jim_lsj 0:9c0e0ac79e75 217
jim_lsj 0:9c0e0ac79e75 218 HeartrateDemo demo(ble, event_queue);
jim_lsj 0:9c0e0ac79e75 219 demo.start();
jim_lsj 0:9c0e0ac79e75 220
jim_lsj 0:9c0e0ac79e75 221 return 0;
jim_lsj 0:9c0e0ac79e75 222 }
jim_lsj 0:9c0e0ac79e75 223