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