仕倫 林 / Mbed OS 12_1

Dependencies:   X_NUCLEO_IKS01A2

Committer:
lsl097
Date:
Thu Apr 30 14:28:59 2020 +0000
Revision:
2:5da515ba10ff
Parent:
1:b12ac7b02a21
FIN

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"
lsl097 2:5da515ba10ff 36 #include "EnvironmentalService.h"
jim_lsj 0:9c0e0ac79e75 37
jim_lsj 1:b12ac7b02a21 38 //const static char DEVICE_NAME[] = "Heartrate";
jim_lsj 0:9c0e0ac79e75 39
jim_lsj 0:9c0e0ac79e75 40
jim_lsj 0:9c0e0ac79e75 41
jim_lsj 0:9c0e0ac79e75 42 // new code
jim_lsj 1:b12ac7b02a21 43 Serial pc(USBTX, USBRX);
jim_lsj 1:b12ac7b02a21 44 static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);
jim_lsj 1:b12ac7b02a21 45 static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer;
jim_lsj 1:b12ac7b02a21 46 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor;
jim_lsj 1:b12ac7b02a21 47 static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor;
jim_lsj 1:b12ac7b02a21 48 static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro;
jim_lsj 1:b12ac7b02a21 49 static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer;
jim_lsj 1:b12ac7b02a21 50 volatile float TEMPERATURE_C=20;
jim_lsj 1:b12ac7b02a21 51 volatile float TEMPERATURE_F;
jim_lsj 1:b12ac7b02a21 52 volatile float TEMPERATURE_K;
jim_lsj 1:b12ac7b02a21 53 volatile float HUMIDITY=50;
jim_lsj 1:b12ac7b02a21 54 volatile float PRESSURE=1000;
jim_lsj 1:b12ac7b02a21 55 volatile float WIND_DIRECTION=0;
jim_lsj 0:9c0e0ac79e75 56 int16_t MagRaw[3];
jim_lsj 1:b12ac7b02a21 57 int16_t * MAGNETIC = new int16_t[3];
jim_lsj 0:9c0e0ac79e75 58 const static char DEVICE_NAME[] = "WEATHER";
jim_lsj 0:9c0e0ac79e75 59
jim_lsj 0:9c0e0ac79e75 60 static volatile bool triggerSensorPolling = false;
jim_lsj 0:9c0e0ac79e75 61 //end
jim_lsj 0:9c0e0ac79e75 62
jim_lsj 0:9c0e0ac79e75 63 static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE);
jim_lsj 0:9c0e0ac79e75 64
jim_lsj 0:9c0e0ac79e75 65 class HeartrateDemo : ble::Gap::EventHandler {
jim_lsj 0:9c0e0ac79e75 66 public:
jim_lsj 0:9c0e0ac79e75 67 HeartrateDemo(BLE &ble, events::EventQueue &event_queue) :
jim_lsj 0:9c0e0ac79e75 68 _ble(ble),
jim_lsj 0:9c0e0ac79e75 69 _event_queue(event_queue),
jim_lsj 0:9c0e0ac79e75 70 _led1(LED1, 1),
jim_lsj 0:9c0e0ac79e75 71 _connected(false),
jim_lsj 0:9c0e0ac79e75 72 _hr_counter(100),
jim_lsj 0:9c0e0ac79e75 73 _bt_service(ble, 25),
jim_lsj 1:b12ac7b02a21 74 //_hr_service(ble, _hr_counter, HeartRateService::LOCATION_FINGER),
lsl097 2:5da515ba10ff 75 _deviceInfo(ble, "ST", "Nucleo", "SN1","","","" ),
jim_lsj 0:9c0e0ac79e75 76 _adv_data_builder(_adv_buffer),
jim_lsj 0:9c0e0ac79e75 77
lsl097 2:5da515ba10ff 78 _air (ble)
lsl097 2:5da515ba10ff 79 //_es(ble),
lsl097 2:5da515ba10ff 80 //_wind (ble, (uint16_t) WIND_DIRECTION, (uint32_t) PRESSURE)
jim_lsj 0:9c0e0ac79e75 81 {
jim_lsj 1:b12ac7b02a21 82 uuid16_list = new UUID[1]{0x181A};
jim_lsj 0:9c0e0ac79e75 83 //_uuid_list = new UUID(3);
jim_lsj 0:9c0e0ac79e75 84 // _uuid_list[0] = GattService::UUID_HEART_RATE_SERVICE;
jim_lsj 0:9c0e0ac79e75 85 // _uuid_list[1] = GattService::UUID_BATTERY_SERVICE;
jim_lsj 0:9c0e0ac79e75 86 // _uuid_list[2] = GattService::UUID_DEVICE_INFORMATION_SERVICE;
jim_lsj 0:9c0e0ac79e75 87 }
jim_lsj 0:9c0e0ac79e75 88 ~HeartrateDemo(){
jim_lsj 1:b12ac7b02a21 89 delete [] uuid16_list;
jim_lsj 0:9c0e0ac79e75 90 }
jim_lsj 0:9c0e0ac79e75 91
jim_lsj 0:9c0e0ac79e75 92 void start() {
jim_lsj 0:9c0e0ac79e75 93 _ble.gap().setEventHandler(this);
jim_lsj 0:9c0e0ac79e75 94
jim_lsj 0:9c0e0ac79e75 95 _ble.init(this, &HeartrateDemo::on_init_complete);
jim_lsj 0:9c0e0ac79e75 96
jim_lsj 0:9c0e0ac79e75 97 _event_queue.call_every(500, this, &HeartrateDemo::blink);
jim_lsj 0:9c0e0ac79e75 98 _event_queue.call_every(1000, this, &HeartrateDemo::update_sensor_value);
jim_lsj 0:9c0e0ac79e75 99
jim_lsj 0:9c0e0ac79e75 100 _event_queue.dispatch_forever();
jim_lsj 0:9c0e0ac79e75 101 }
jim_lsj 0:9c0e0ac79e75 102
jim_lsj 0:9c0e0ac79e75 103 private:
jim_lsj 0:9c0e0ac79e75 104 /** Callback triggered when the ble initialization process has finished */
jim_lsj 0:9c0e0ac79e75 105 void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
jim_lsj 0:9c0e0ac79e75 106 if (params->error != BLE_ERROR_NONE) {
jim_lsj 0:9c0e0ac79e75 107 printf("Ble initialization failed.");
jim_lsj 0:9c0e0ac79e75 108 return;
jim_lsj 0:9c0e0ac79e75 109 }
jim_lsj 0:9c0e0ac79e75 110
jim_lsj 0:9c0e0ac79e75 111 print_mac_address();
jim_lsj 0:9c0e0ac79e75 112
jim_lsj 0:9c0e0ac79e75 113 start_advertising();
jim_lsj 0:9c0e0ac79e75 114 }
jim_lsj 0:9c0e0ac79e75 115
jim_lsj 0:9c0e0ac79e75 116 void start_advertising() {
jim_lsj 0:9c0e0ac79e75 117 /* Create advertising parameters and payload */
jim_lsj 0:9c0e0ac79e75 118
jim_lsj 0:9c0e0ac79e75 119 ble::AdvertisingParameters adv_parameters(
jim_lsj 0:9c0e0ac79e75 120 ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
jim_lsj 0:9c0e0ac79e75 121 ble::adv_interval_t(ble::millisecond_t(1000))
jim_lsj 0:9c0e0ac79e75 122 );
jim_lsj 0:9c0e0ac79e75 123
jim_lsj 0:9c0e0ac79e75 124 _adv_data_builder.setFlags();
jim_lsj 0:9c0e0ac79e75 125 _adv_data_builder.setAppearance(ble::adv_data_appearance_t::GENERIC_THERMOMETER);
jim_lsj 1:b12ac7b02a21 126 _adv_data_builder.setLocalServiceList(mbed::make_Span(uuid16_list, 1));
jim_lsj 0:9c0e0ac79e75 127 _adv_data_builder.setName(DEVICE_NAME);
jim_lsj 0:9c0e0ac79e75 128
jim_lsj 0:9c0e0ac79e75 129 /* Setup advertising */
jim_lsj 0:9c0e0ac79e75 130
jim_lsj 0:9c0e0ac79e75 131 ble_error_t error = _ble.gap().setAdvertisingParameters(
jim_lsj 0:9c0e0ac79e75 132 ble::LEGACY_ADVERTISING_HANDLE,
jim_lsj 0:9c0e0ac79e75 133 adv_parameters
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().setAdvertisingParameters() failed\r\n");
jim_lsj 0:9c0e0ac79e75 138 return;
jim_lsj 0:9c0e0ac79e75 139 }
jim_lsj 0:9c0e0ac79e75 140
jim_lsj 0:9c0e0ac79e75 141 error = _ble.gap().setAdvertisingPayload(
jim_lsj 0:9c0e0ac79e75 142 ble::LEGACY_ADVERTISING_HANDLE,
jim_lsj 0:9c0e0ac79e75 143 _adv_data_builder.getAdvertisingData()
jim_lsj 0:9c0e0ac79e75 144 );
jim_lsj 0:9c0e0ac79e75 145
jim_lsj 0:9c0e0ac79e75 146 if (error) {
jim_lsj 0:9c0e0ac79e75 147 printf("_ble.gap().setAdvertisingPayload() failed\r\n");
jim_lsj 0:9c0e0ac79e75 148 return;
jim_lsj 0:9c0e0ac79e75 149 }
jim_lsj 0:9c0e0ac79e75 150
jim_lsj 0:9c0e0ac79e75 151 /* Start advertising */
jim_lsj 0:9c0e0ac79e75 152
jim_lsj 0:9c0e0ac79e75 153 error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
jim_lsj 0:9c0e0ac79e75 154
jim_lsj 0:9c0e0ac79e75 155 if (error) {
jim_lsj 0:9c0e0ac79e75 156 printf("_ble.gap().startAdvertising() failed\r\n");
jim_lsj 0:9c0e0ac79e75 157 return;
jim_lsj 0:9c0e0ac79e75 158 }
jim_lsj 0:9c0e0ac79e75 159 }
jim_lsj 0:9c0e0ac79e75 160
jim_lsj 0:9c0e0ac79e75 161 void update_sensor_value() {
jim_lsj 0:9c0e0ac79e75 162 if (_connected) {
jim_lsj 0:9c0e0ac79e75 163 // Do blocking calls or whatever is necessary for sensor polling.
jim_lsj 0:9c0e0ac79e75 164 // In our case, we simply update the HRM measurement.
jim_lsj 1:b12ac7b02a21 165 hum_temp->get_temperature((float *)&TEMPERATURE_C);
jim_lsj 1:b12ac7b02a21 166 hum_temp->get_humidity((float *)&HUMIDITY);
jim_lsj 1:b12ac7b02a21 167 press_temp->get_pressure((float *)&PRESSURE);
jim_lsj 1:b12ac7b02a21 168 magnetometer->get_m_axes_raw((int16_t *)MAGNETIC);
lsl097 2:5da515ba10ff 169 //TEMPERATURE_C = TEMPERATURE_C*100; //2 decimals
lsl097 2:5da515ba10ff 170 //HUMIDITY = HUMIDITY*100; //2 decimals
jim_lsj 1:b12ac7b02a21 171 PRESSURE = PRESSURE*1000; //hPa to Pa + 1 decimal
jim_lsj 1:b12ac7b02a21 172
jim_lsj 1:b12ac7b02a21 173
jim_lsj 1:b12ac7b02a21 174 //Calcule the direction where the system is pointing relative to North.
jim_lsj 1:b12ac7b02a21 175 //I have used a simple empirical method to distinguish between 8 directions.
jim_lsj 1:b12ac7b02a21 176 if (MAGNETIC[0] < 140) WIND_DIRECTION = 0; //North
jim_lsj 1:b12ac7b02a21 177 else if (MAGNETIC[0] >= 140 && MAGNETIC[0] < 200 && -MAGNETIC[1] > 250 ) WIND_DIRECTION = 45; //Northeast
jim_lsj 1:b12ac7b02a21 178 else if (MAGNETIC[0] >= 140 && MAGNETIC[0] < 200 && -MAGNETIC[1] < 250 ) WIND_DIRECTION = 315; //Northwest
jim_lsj 1:b12ac7b02a21 179 else if (MAGNETIC[0] >= 200 && MAGNETIC[0] < 280 && -MAGNETIC[1] > 250 ) WIND_DIRECTION = 90; //East
jim_lsj 1:b12ac7b02a21 180 else if (MAGNETIC[0] >= 200 && MAGNETIC[0] < 280 && -MAGNETIC[1] < 250 ) WIND_DIRECTION = 270; //Weast
jim_lsj 1:b12ac7b02a21 181 else if (MAGNETIC[0] >= 280 && MAGNETIC[0] < 380 && -MAGNETIC[1] > 250 ) WIND_DIRECTION = 135; //Southeast
jim_lsj 1:b12ac7b02a21 182 else if (MAGNETIC[0] >= 280 && MAGNETIC[0] < 380 && -MAGNETIC[1] < 250 ) WIND_DIRECTION = 225; //Soutwest
jim_lsj 1:b12ac7b02a21 183 else if (MAGNETIC[0] >= 380) WIND_DIRECTION = 180; //South
jim_lsj 1:b12ac7b02a21 184
jim_lsj 1:b12ac7b02a21 185 WIND_DIRECTION *=100; //2 decimals
jim_lsj 1:b12ac7b02a21 186
lsl097 2:5da515ba10ff 187 _air.updateTemperature((float)TEMPERATURE_C);
lsl097 2:5da515ba10ff 188 //_es.updateTemperature((float)TEMPERATURE_C);
lsl097 2:5da515ba10ff 189 _air.updateHumidity((uint16_t)1);
lsl097 2:5da515ba10ff 190 //_es.updateHumidity((uint16_t)1);
lsl097 2:5da515ba10ff 191 _air.updateWinddirection((uint16_t)WIND_DIRECTION);
lsl097 2:5da515ba10ff 192 _air.updatePressure((uint16_t)PRESSURE);
lsl097 2:5da515ba10ff 193 //_es.updatePressure((uint16_t)PRESSURE);
jim_lsj 1:b12ac7b02a21 194
jim_lsj 1:b12ac7b02a21 195
jim_lsj 1:b12ac7b02a21 196 TEMPERATURE_F = (TEMPERATURE_C * 1.8f) + 32.0f; //Convert the temperature from Celsius to Fahrenheit
jim_lsj 1:b12ac7b02a21 197 TEMPERATURE_K = (TEMPERATURE_C + 273.15f); //Convert the temperature from Celsius to Kelvin
jim_lsj 1:b12ac7b02a21 198 pc.printf("Temperature:\t %.2f C / %.2f F / %.2f K\r\n", TEMPERATURE_C, TEMPERATURE_F, TEMPERATURE_K);
jim_lsj 1:b12ac7b02a21 199 pc.printf("Humidity:\t %.2f%%\r\n", HUMIDITY);
jim_lsj 1:b12ac7b02a21 200 pc.printf("Pressure:\t %.2f hPa\r\n", PRESSURE);
jim_lsj 1:b12ac7b02a21 201 pc.printf("\r\n");
jim_lsj 1:b12ac7b02a21 202
jim_lsj 0:9c0e0ac79e75 203 }
jim_lsj 0:9c0e0ac79e75 204 }
jim_lsj 0:9c0e0ac79e75 205
jim_lsj 0:9c0e0ac79e75 206 void blink(void) {
jim_lsj 0:9c0e0ac79e75 207 _led1 = !_led1;
jim_lsj 0:9c0e0ac79e75 208 }
jim_lsj 0:9c0e0ac79e75 209
jim_lsj 0:9c0e0ac79e75 210 private:
jim_lsj 0:9c0e0ac79e75 211 /* Event handler */
jim_lsj 0:9c0e0ac79e75 212
jim_lsj 0:9c0e0ac79e75 213 void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) {
jim_lsj 0:9c0e0ac79e75 214 _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
jim_lsj 0:9c0e0ac79e75 215 _connected = false;
jim_lsj 0:9c0e0ac79e75 216 }
jim_lsj 0:9c0e0ac79e75 217
jim_lsj 0:9c0e0ac79e75 218 virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) {
jim_lsj 0:9c0e0ac79e75 219 if (event.getStatus() == BLE_ERROR_NONE) {
jim_lsj 0:9c0e0ac79e75 220 _connected = true;
jim_lsj 0:9c0e0ac79e75 221 }
jim_lsj 0:9c0e0ac79e75 222 }
jim_lsj 0:9c0e0ac79e75 223
jim_lsj 0:9c0e0ac79e75 224 private:
jim_lsj 0:9c0e0ac79e75 225 BLE &_ble;
jim_lsj 0:9c0e0ac79e75 226 events::EventQueue &_event_queue;
jim_lsj 0:9c0e0ac79e75 227 DigitalOut _led1;
jim_lsj 0:9c0e0ac79e75 228
jim_lsj 0:9c0e0ac79e75 229 bool _connected;
jim_lsj 0:9c0e0ac79e75 230
jim_lsj 0:9c0e0ac79e75 231 uint8_t _hr_counter;
jim_lsj 1:b12ac7b02a21 232 //HeartRateService _hr_service;
jim_lsj 0:9c0e0ac79e75 233
jim_lsj 0:9c0e0ac79e75 234 uint8_t _battery_level;
jim_lsj 0:9c0e0ac79e75 235 BatteryService _bt_service;
jim_lsj 0:9c0e0ac79e75 236
jim_lsj 1:b12ac7b02a21 237 EnvironmentalSensingService _air;
lsl097 2:5da515ba10ff 238 //EnvironmentalSensingService2 _wind;
lsl097 2:5da515ba10ff 239 //EnvironmentalService _es;
jim_lsj 1:b12ac7b02a21 240
jim_lsj 1:b12ac7b02a21 241 UUID * uuid16_list;
jim_lsj 0:9c0e0ac79e75 242
jim_lsj 0:9c0e0ac79e75 243 DeviceInformationService _deviceInfo;
jim_lsj 0:9c0e0ac79e75 244
jim_lsj 0:9c0e0ac79e75 245 uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
jim_lsj 0:9c0e0ac79e75 246 ble::AdvertisingDataBuilder _adv_data_builder;
jim_lsj 0:9c0e0ac79e75 247 };
jim_lsj 0:9c0e0ac79e75 248
jim_lsj 0:9c0e0ac79e75 249 /** Schedule processing of events from the BLE middleware in the event queue. */
jim_lsj 0:9c0e0ac79e75 250 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
jim_lsj 0:9c0e0ac79e75 251 event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));
jim_lsj 0:9c0e0ac79e75 252 }
jim_lsj 0:9c0e0ac79e75 253
jim_lsj 0:9c0e0ac79e75 254 int main()
jim_lsj 0:9c0e0ac79e75 255 {
jim_lsj 0:9c0e0ac79e75 256 static XNucleoIKS01A2 *Sensors = XNucleoIKS01A2::instance(D14, D15, D4, D5);
jim_lsj 1:b12ac7b02a21 257 hum_temp->enable();
jim_lsj 1:b12ac7b02a21 258 press_temp->enable();
jim_lsj 1:b12ac7b02a21 259 magnetometer->enable();
jim_lsj 1:b12ac7b02a21 260 accelerometer->enable();
jim_lsj 1:b12ac7b02a21 261 acc_gyro->enable_x();
jim_lsj 1:b12ac7b02a21 262 acc_gyro->enable_g();
jim_lsj 1:b12ac7b02a21 263
jim_lsj 0:9c0e0ac79e75 264 BLE &ble = BLE::Instance();
jim_lsj 0:9c0e0ac79e75 265 ble.onEventsToProcess(schedule_ble_events);
jim_lsj 1:b12ac7b02a21 266
jim_lsj 0:9c0e0ac79e75 267 HeartrateDemo demo(ble, event_queue);
jim_lsj 0:9c0e0ac79e75 268 demo.start();
jim_lsj 0:9c0e0ac79e75 269
jim_lsj 0:9c0e0ac79e75 270 return 0;
jim_lsj 0:9c0e0ac79e75 271 }
jim_lsj 0:9c0e0ac79e75 272