BLE Lightning sensor for Nordic NRF51822 based module

Dependencies:   AS3935 AS3935_ext BLE_API mbed nRF51822 nrf51_rtc

Revision:
3:2ea547dab8a8
Parent:
2:e1e638cbf972
Child:
4:8f815f8d804e
--- a/main.cpp	Sun Aug 30 06:27:27 2015 +0000
+++ b/main.cpp	Sun Aug 30 10:15:31 2015 +0000
@@ -3,14 +3,11 @@
 */
 
 #include "mbed.h"
-#include "BLE.h"
 #include "nrf51_rtc.h"
 #include "AS3935_ext.h"
 
-#include "nrf_soc.h" // for internal Thermo sensoer
-
-#define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console;
-                               * it will have an impact on code-size and power consumption. */
+#define NEED_CONSOLE_OUTPUT 1 // Set this if you need debug messages on the console; 
+#define NEED_BLE_CONSOLE 1
 
 #if NEED_CONSOLE_OUTPUT
 Serial  pc(USBTX, USBRX);
@@ -19,52 +16,18 @@
 #define DEBUG(...) /* nothing */
 #endif /* #if NEED_CONSOLE_OUTPUT */
 
-// Prepare BLE device
-BLEDevice  ble;
-const static char  DEVICE_NAME[] = "BLE-LITNING-S";
-
-/* Health Thermometer Service */ 
-/* Service:  https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml */
-/* HTM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml */
-uint8_t             thermTempPayload[5] = { 0, 0, 0, 0, 0 };
-
-GattCharacteristic  tempChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR,
-                                thermTempPayload, sizeof(thermTempPayload), sizeof(thermTempPayload),
-                                GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
-GattCharacteristic *htmChars[] = {&tempChar, };
-GattService        htmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, htmChars, 
-                                sizeof(htmChars) / sizeof(GattCharacteristic *));
-
-/* Original Thermometer Service */
-/* with nRF51822 internal thermal sensor */
-uint8_t             internalTempPayload[5] = { 0, 0, 0, 0, 0 };
+#if NEED_BLE_CONSOLE
+#include "BLE.h"
+#include "UARTService.h"
+#define BLEC(...) { char __blecstr[32]; sprintf(__blecstr,__VA_ARGS__); if (uart) uart->write(__blecstr, strlen(__blecstr)); }
+#else
+#define BLEC(...) /* nothing */
+#endif /* #if NEED_BLE_CONSOLE */
 
-GattCharacteristic  internalTempChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR + 0x2000,
-                                internalTempPayload, sizeof(internalTempPayload), sizeof(internalTempPayload),
-                                GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
-GattCharacteristic *itmChars[] = {&internalTempChar, };
-GattService        itmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE + 0x2000, itmChars, 
-                                sizeof(itmChars) / sizeof(GattCharacteristic *));
-
-/* Battery Level Service */
-uint8_t            batt = 98;     /* Battery level */
-uint8_t            read_batt = 0; /* Variable to hold battery level reads */
-static uint8_t bpm2[1] = {batt};
-GattCharacteristic battLevel   ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, bpm2, sizeof(bpm2), sizeof(bpm2),
-                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
-                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
-GattCharacteristic *battChars[] = {&battLevel, };
-GattService        battService(GattService::UUID_BATTERY_SERVICE, battChars, sizeof(battChars) / sizeof(GattCharacteristic *));
-
-static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE, GattService::UUID_BATTERY_SERVICE, GattService::UUID_HEALTH_THERMOMETER_SERVICE + 0x2000 };
-
-static volatile bool triggerSensorPolling = false; /* set to high periodically to indicate to the main thread that
-                                                    * polling is necessary. */
-static Gap::ConnectionParams_t connectionParams;
-
-uint32_t quick_ieee11073_from_float(float temperature);
-
-void Update_Values();
+#if NEED_BLE_CONSOLE
+// Prepare BLE device
+const uint8_t DEVICE_NAME[] = "BLE Ligttning Sensor";
+#endif // #if NEED_BLE_CONSOLE
 
 
 // Prepare LED device
@@ -78,6 +41,20 @@
 DigitalIn  button1(BUTTON1);  // used to trigger the time report
 InterruptIn button1Press(BUTTON1);
 
+// event record buffer struct
+const int s_evrecord=10;
+struct t_evrecord {
+    public:
+        int event;
+        time_t time;
+        int distance;
+        
+        t_evrecord() {
+            event = 0;
+            time = 0;
+            distance = 0;
+        }
+} evrecord[s_evrecord];
 
 time_t example_time() {
     // set an intial time
@@ -126,20 +103,63 @@
     Lightning.lightningDistanceKm();
     led1 = !led1;
 
-    triggerSensorPolling = true;
     // print_time();
 }
 
+#if NEED_BLE_CONSOLE
+BLEDevice  ble;
+UARTService *uart;
+static Gap::ConnectionParams_t connectionParams;
+int buff_flash_flag;
+
+void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)    // Mod
+{
+    DEBUG("Disconnected handle %u!\n\r", handle);
+    DEBUG("Restarting the advertising process\n\r");
+    led2 = 0;
+    ble.gap().startAdvertising();
+    
+    
+}
+
+void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
+{
+    DEBUG("connected. Got handle %u\r\n", params->handle);
+
+    connectionParams.slaveLatency = 1;
+    led2 = 1;
+    if (ble.gap().updateConnectionParams(params->handle, &connectionParams) != BLE_ERROR_NONE) {
+        DEBUG("failed to update connection paramter\r\n");
+    }
+    buff_flash_flag = 1;
+
+}
+
+void onDataWritten(const GattWriteCallbackParams *params)
+{
+    uint8_t buff[21];
+    if ((uart != NULL) && (params->handle == uart->getTXCharacteristicHandle())) {
+        uint16_t bytesRead = params->len;
+        DEBUG("received %u bytes\n\r", bytesRead);
+        strncpy((char*)buff,(char*)params->data,bytesRead);
+        // ble.updateCharacteristicValue(uart->getRXCharacteristicHandle(), params->data, bytesRead);
+        ble.updateCharacteristicValue(uart->getRXCharacteristicHandle(), buff, bytesRead);
+    }
+}
+
+#endif // if NEED_BLE_CONSOLE
+
 void DetectLightning()
 {
     char OriginInt;
     time_t rawtime=rtc.time();
     struct tm * timeinfo;
     timeinfo = localtime(&rawtime);
-    char date[24];
+    char date[24],sdate[9];
     int distance;
     
     strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",timeinfo);
+    strftime(sdate,sizeof(sdate),"%H%M%S",timeinfo);
 
     wait_ms(2); //on attend 2ms préconisation constructeur
     OriginInt = Lightning.interruptSource();
@@ -159,28 +179,22 @@
         }
 }
 
-void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)    // Mod
-{
-    DEBUG("Disconnected handle %u!\n\r", handle);
-    DEBUG("Restarting the advertising process\n\r");
-    led2 = 0;
-    ble.gap().startAdvertising();
-}
-
-void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
-{
-    DEBUG("connected. Got handle %u\r\n", params->handle);
-
-    connectionParams.slaveLatency = 1;
-    led2 = 1;
-    if (ble.gap().updateConnectionParams(params->handle, &connectionParams) != BLE_ERROR_NONE) {
-        DEBUG("failed to update connection paramter\r\n");
-    }
-    
-}
 
 int main(void)
 {
+#if NEED_BLE_CONSOLE
+    ble.init();
+    ble.gap().onDisconnection(disconnectionCallback);
+    ble.gap().onConnection(onConnectionCallback);
+    ble.gattServer().onDataWritten(onDataWritten);
+    ble.gap().getPreferredConnectionParams(&connectionParams);
+    
+    uart = new UARTService(ble);
+    buff_flash_flag = 0;
+
+#endif // if NEED_BLE_CONSOLE
+
+
     led1=0;
     led2=0;
     int hz=0;
@@ -215,6 +229,7 @@
     hz = Lightning.MeasureLCOFreq();
     float err = (hz-500000.)/500000.*100.;
     DEBUG("Final %d : hz=%10d Hz (%5.2f%%)\r\n",fincap,hz,err);
+    BLEC("%1x:%10dHz:%5.2f:final\n",fincap,hz,err);
     
     DEBUG("Auto Calibration finished\r\n");
     
@@ -230,74 +245,39 @@
     
     IntLightning.rise(&DetectLightning);
 
-    ble.init();
-    ble.gap().onDisconnection(disconnectionCallback);
-    ble.gap().onConnection(onConnectionCallback);
-
-    ble.gap().getPreferredConnectionParams(&connectionParams);
-
+#if NEED_BLE_CONSOLE
     /* setup advertising */
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list));
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
+                                     DEVICE_NAME, sizeof(DEVICE_NAME) - 1);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
+                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
 
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
-
-    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
     ble.gap().setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
     ble.gap().startAdvertising();
-
-    ble.gattServer().addService(htmService);
-    ble.gattServer().addService(battService);
-
+#endif // #if NEED_BLE_CONSOLE
 
     while (true) {
-        if (triggerSensorPolling) {
-            triggerSensorPolling = false;
+        if ( buff_flash_flag != 0) {
+            wait_ms(4000);
+            BLEC("test1\n");
+            wait_ms(300);
+            time_t rawtime=rtc.time();
+            BLEC("%4x:current time\n",rawtime);
+    
+            for(int i=0;i<s_evrecord;i++) {
+                BLEC("%1d:%4x:%1x:%2x\n",i,evrecord[i].time,evrecord[i].event,evrecord[i].distance);
+                wait_ms(300);
+            }
+            BLEC("finished\n");
 
-            Update_Values();
+            buff_flash_flag = 0;
             
         } else {
-            ble.waitForEvent();
+            BLEC("pong\n");
+            wait(5);
         }
     }
 }
 
-void Update_Values()
-{
-    /* Update the temperature. Note that we need to convert to an ieee11073 format float. */
-
-    int32_t p_temp;
-    sd_temp_get(&p_temp);
-    float temperature = float(p_temp)/4.;
-    temperature -= 14.; // It should be changed device by device. 
-           
-    // DEBUG("temp:%f\n\r", temperature);
-    uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature);
-    memcpy(thermTempPayload+1, &temp_ieee11073, 4);
-
-    /* Battery Service Update */
-    /* Update battery level */
-    //ble.getGattServer().updateValue(battLevel.handle, (uint8_t*)&batt, sizeof(batt));
-    /* Decrement the battery level. */
-    batt <=50 ? batt=100 : batt--;;
-    bpm2[0] = batt;
-
-    if (ble.gap().getState().connected ) {
-        ble.gattServer().write(tempChar.getValueAttribute().getHandle(), thermTempPayload, sizeof(thermTempPayload));
-        ble.gattServer().write(battLevel.getValueAttribute().getHandle(), (uint8_t *)&batt, sizeof(batt));
-    }
-}
-
-/**
- * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
- * @param temperature The temperature as a float.
- * @return The temperature in 11073-20601 FLOAT-Type format.
- */
-uint32_t quick_ieee11073_from_float(float temperature)
-{
-    uint8_t  exponent = 0xFE; //exponent is -2
-    uint32_t mantissa = (uint32_t)(temperature*100);
-    
-    return ( ((uint32_t)exponent) << 24) | mantissa;
-}