仕倫 林 / 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 #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