士鈞 林 / Mbed OS 12_1

Dependencies:   X_NUCLEO_IKS01A2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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