Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: X_NUCLEO_IKS01A2
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 <events/mbed_events.h> 00018 #include <mbed.h> 00019 #include "ble/BLE.h" 00020 #include "ble/gap/Gap.h" 00021 //#include "ble/services/EnvironmentalSensingService2.h" 00022 #include "ble/services/BatteryService.h" 00023 #include "ble/services/HeartRateService.h" 00024 #include "ble/services/DeviceInformationService.h" 00025 #include "pretty_printer.h" 00026 00027 //#include "BLEDevice.h" 00028 #include "blecommon.h" 00029 #include "Gap.h" 00030 #include "GattServer.h" 00031 //#include "BLEDeviceInstanceBase.h" 00032 00033 #include "XNucleoIKS01A2.h" 00034 #include "ESS.h" 00035 #include "ESS2.h" 00036 00037 //const static char DEVICE_NAME[] = "Heartrate"; 00038 00039 00040 00041 // new code 00042 Serial pc(USBTX, USBRX); 00043 static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5); 00044 static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer; 00045 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; 00046 static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor; 00047 static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro; 00048 static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer; 00049 volatile float TEMPERATURE_C=20; 00050 volatile float TEMPERATURE_F; 00051 volatile float TEMPERATURE_K; 00052 volatile float HUMIDITY=50; 00053 volatile float PRESSURE=1000; 00054 volatile float WIND_DIRECTION=0; 00055 int16_t MagRaw[3]; 00056 int16_t * MAGNETIC = new int16_t[3]; 00057 const static char DEVICE_NAME[] = "WEATHER"; 00058 00059 static volatile bool triggerSensorPolling = false; 00060 //end 00061 00062 static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); 00063 00064 class HeartrateDemo : ble::Gap::EventHandler { 00065 public: 00066 HeartrateDemo(BLE &ble, events::EventQueue &event_queue) : 00067 _ble(ble), 00068 _event_queue(event_queue), 00069 _led1(LED1, 1), 00070 _connected(false), 00071 _hr_counter(100), 00072 _bt_service(ble, 25), 00073 //_hr_service(ble, _hr_counter, HeartRateService::LOCATION_FINGER), 00074 _deviceInfo(ble, "ST", "Nucleo", "SN1" ), 00075 _adv_data_builder(_adv_buffer), 00076 00077 _air (ble, (uint16_t) HUMIDITY, (int16_t) TEMPERATURE_C ), 00078 _wind (ble, (uint16_t) WIND_DIRECTION, (uint32_t) PRESSURE) 00079 { 00080 uuid16_list = new UUID[1]{0x181A}; 00081 //_uuid_list = new UUID(3); 00082 // _uuid_list[0] = GattService::UUID_HEART_RATE_SERVICE; 00083 // _uuid_list[1] = GattService::UUID_BATTERY_SERVICE; 00084 // _uuid_list[2] = GattService::UUID_DEVICE_INFORMATION_SERVICE; 00085 } 00086 ~HeartrateDemo(){ 00087 delete [] uuid16_list; 00088 } 00089 00090 void start() { 00091 _ble.gap().setEventHandler(this); 00092 00093 _ble.init(this, &HeartrateDemo::on_init_complete); 00094 00095 _event_queue.call_every(500, this, &HeartrateDemo::blink); 00096 _event_queue.call_every(1000, this, &HeartrateDemo::update_sensor_value); 00097 00098 _event_queue.dispatch_forever(); 00099 } 00100 00101 private: 00102 /** Callback triggered when the ble initialization process has finished */ 00103 void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { 00104 if (params->error != BLE_ERROR_NONE) { 00105 printf("Ble initialization failed."); 00106 return; 00107 } 00108 00109 print_mac_address(); 00110 00111 start_advertising(); 00112 } 00113 00114 void start_advertising() { 00115 /* Create advertising parameters and payload */ 00116 00117 ble::AdvertisingParameters adv_parameters( 00118 ble::advertising_type_t::CONNECTABLE_UNDIRECTED, 00119 ble::adv_interval_t(ble::millisecond_t(1000)) 00120 ); 00121 00122 _adv_data_builder.setFlags(); 00123 _adv_data_builder.setAppearance(ble::adv_data_appearance_t::GENERIC_THERMOMETER); 00124 _adv_data_builder.setLocalServiceList(mbed::make_Span(uuid16_list, 1)); 00125 _adv_data_builder.setName(DEVICE_NAME); 00126 00127 /* Setup advertising */ 00128 00129 ble_error_t error = _ble.gap().setAdvertisingParameters( 00130 ble::LEGACY_ADVERTISING_HANDLE, 00131 adv_parameters 00132 ); 00133 00134 if (error) { 00135 printf("_ble.gap().setAdvertisingParameters() failed\r\n"); 00136 return; 00137 } 00138 00139 error = _ble.gap().setAdvertisingPayload( 00140 ble::LEGACY_ADVERTISING_HANDLE, 00141 _adv_data_builder.getAdvertisingData() 00142 ); 00143 00144 if (error) { 00145 printf("_ble.gap().setAdvertisingPayload() failed\r\n"); 00146 return; 00147 } 00148 00149 /* Start advertising */ 00150 00151 error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); 00152 00153 if (error) { 00154 printf("_ble.gap().startAdvertising() failed\r\n"); 00155 return; 00156 } 00157 } 00158 00159 void update_sensor_value() { 00160 if (_connected) { 00161 // Do blocking calls or whatever is necessary for sensor polling. 00162 // In our case, we simply update the HRM measurement. 00163 hum_temp->get_temperature((float *)&TEMPERATURE_C); 00164 hum_temp->get_humidity((float *)&HUMIDITY); 00165 press_temp->get_pressure((float *)&PRESSURE); 00166 magnetometer->get_m_axes_raw((int16_t *)MAGNETIC); 00167 TEMPERATURE_C = TEMPERATURE_C*100; //2 decimals 00168 HUMIDITY = HUMIDITY*100; //2 decimals 00169 PRESSURE = PRESSURE*1000; //hPa to Pa + 1 decimal 00170 00171 00172 //Calcule the direction where the system is pointing relative to North. 00173 //I have used a simple empirical method to distinguish between 8 directions. 00174 if (MAGNETIC[0] < 140) WIND_DIRECTION = 0; //North 00175 else if (MAGNETIC[0] >= 140 && MAGNETIC[0] < 200 && -MAGNETIC[1] > 250 ) WIND_DIRECTION = 45; //Northeast 00176 else if (MAGNETIC[0] >= 140 && MAGNETIC[0] < 200 && -MAGNETIC[1] < 250 ) WIND_DIRECTION = 315; //Northwest 00177 else if (MAGNETIC[0] >= 200 && MAGNETIC[0] < 280 && -MAGNETIC[1] > 250 ) WIND_DIRECTION = 90; //East 00178 else if (MAGNETIC[0] >= 200 && MAGNETIC[0] < 280 && -MAGNETIC[1] < 250 ) WIND_DIRECTION = 270; //Weast 00179 else if (MAGNETIC[0] >= 280 && MAGNETIC[0] < 380 && -MAGNETIC[1] > 250 ) WIND_DIRECTION = 135; //Southeast 00180 else if (MAGNETIC[0] >= 280 && MAGNETIC[0] < 380 && -MAGNETIC[1] < 250 ) WIND_DIRECTION = 225; //Soutwest 00181 else if (MAGNETIC[0] >= 380) WIND_DIRECTION = 180; //South 00182 00183 WIND_DIRECTION *=100; //2 decimals 00184 00185 _air.updateTemperature((uint16_t)TEMPERATURE_C); 00186 _air.updateHumidity((uint16_t)HUMIDITY); 00187 _wind.updateWinddirection((uint16_t)WIND_DIRECTION); 00188 _wind.updatePressure((uint16_t)PRESSURE); 00189 00190 00191 TEMPERATURE_F = (TEMPERATURE_C * 1.8f) + 32.0f; //Convert the temperature from Celsius to Fahrenheit 00192 TEMPERATURE_K = (TEMPERATURE_C + 273.15f); //Convert the temperature from Celsius to Kelvin 00193 pc.printf("Temperature:\t %.2f C / %.2f F / %.2f K\r\n", TEMPERATURE_C, TEMPERATURE_F, TEMPERATURE_K); 00194 pc.printf("Humidity:\t %.2f%%\r\n", HUMIDITY); 00195 pc.printf("Pressure:\t %.2f hPa\r\n", PRESSURE); 00196 pc.printf("\r\n"); 00197 00198 } 00199 } 00200 00201 void blink(void) { 00202 _led1 = !_led1; 00203 } 00204 00205 private: 00206 /* Event handler */ 00207 00208 void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { 00209 _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); 00210 _connected = false; 00211 } 00212 00213 virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) { 00214 if (event.getStatus() == BLE_ERROR_NONE) { 00215 _connected = true; 00216 } 00217 } 00218 00219 private: 00220 BLE &_ble; 00221 events::EventQueue &_event_queue; 00222 DigitalOut _led1; 00223 00224 bool _connected; 00225 00226 uint8_t _hr_counter; 00227 //HeartRateService _hr_service; 00228 00229 uint8_t _battery_level; 00230 BatteryService _bt_service; 00231 00232 EnvironmentalSensingService _air; 00233 EnvironmentalSensingService2 _wind; 00234 00235 UUID * uuid16_list; 00236 00237 DeviceInformationService _deviceInfo; 00238 00239 uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; 00240 ble::AdvertisingDataBuilder _adv_data_builder; 00241 }; 00242 00243 /** Schedule processing of events from the BLE middleware in the event queue. */ 00244 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { 00245 event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents)); 00246 } 00247 00248 int main() 00249 { 00250 static XNucleoIKS01A2 *Sensors = XNucleoIKS01A2::instance(D14, D15, D4, D5); 00251 hum_temp->enable(); 00252 press_temp->enable(); 00253 magnetometer->enable(); 00254 accelerometer->enable(); 00255 acc_gyro->enable_x(); 00256 acc_gyro->enable_g(); 00257 00258 BLE &ble = BLE::Instance(); 00259 ble.onEventsToProcess(schedule_ble_events); 00260 00261 HeartrateDemo demo(ble, event_queue); 00262 demo.start(); 00263 00264 return 0; 00265 } 00266
Generated on Sun Aug 7 2022 14:13:24 by
1.7.2