You can control from iPhone and put some command. h=show commands help, v=show TY51822r3 VDD data, t=show chip temperature, q=you can make deep sleep condition.

Dependencies:   BLE_API mbed nRF51822 nRF51_Vdd nRF51_WakeUp nRF51_LowPwr

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Please refer follows.
/users/kenjiArai/notebook/ty51822r3-current-consumption-using-nrf51_wakeup-l/#

Revision:
14:f9b4d659d717
Parent:
13:15764cc1f12c
Child:
15:d7764da3f37c
--- a/main.cpp	Tue Sep 29 12:02:15 2015 +0000
+++ b/main.cpp	Sat Apr 02 06:35:44 2016 +0000
@@ -14,72 +14,351 @@
  * limitations under the License.
  */
 
-#include "mbed.h"
-#include "ble/BLE.h"
+/*
+ *  /////// Tested on Switch Science mbed TY51822r3 ///////
+ *  Modified by Kenji Arai
+ *      http://www.page.sannet.ne.jp/kenjia/index.html
+ *      http://mbed.org/users/kenjiArai/
+ *
+ *      Started:  March     7th, 2016
+ *      Revised:  March    30th, 2016
+ *
+ *  Original program:
+ *      BLE_LoopbackUART
+ *      https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_LoopbackUART/
+ *  Tested Controller Device:
+ *      iPhone6 nRF UART by Nordic
+ *      https://itunes.apple.com/us/app/nrf-uart/id614594903?mt=8
+ *
+ */
 
-#include "ble/services/UARTService.h"
+//  Include ---------------------------------------------------------------------------------------
+#include <string.h>
+#include "mbed.h"
+#include "BLE.h"
+#include "UARTService.h"
+#include "nRF51_Vdd.h"
+#include "nRF51_WakeUp.h"
 
-#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
-                               * it will have an impact on code-size and power consumption. */
-
+//  Definition ------------------------------------------------------------------------------------
+#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. */
 #if NEED_CONSOLE_OUTPUT
 #define DEBUG(...) { printf(__VA_ARGS__); }
 #else
 #define DEBUG(...) /* nothing */
 #endif /* #if NEED_CONSOLE_OUTPUT */
 
-BLEDevice  ble;
-DigitalOut led1(LED1);
+#define HIGH_PWR                1
+#define TXRX_BUF_LEN            22              // send & receive number = 20
+#define PWR_RANG_NO             8
 
-UARTService *uartServicePtr;
+enum TX_Content {
+                TX_VDD = 1,
+                TX_TEMP,
+                TX_PWR_UP,
+                TX_PWR_DWN,
+                TX_QUIT,
+                TX_HELP
+                };
 
-void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
-{
-    DEBUG("Disconnected!\n\r");
-    DEBUG("Restarting the advertising process\n\r");
-    ble.startAdvertising();
-}
+//  Object ----------------------------------------------------------------------------------------
+BLEDevice       ble;
+DigitalOut      myled(LED2);
+InterruptIn     wake_up_sw(P0_1);  // If you change P0_1, you also need to change PORT_OUTPUT.
+nRF51_WakeUp    wakeup(LED1, P0_0);
+nRF51_Vdd       vdd(3.0f, 2.2f);
+UARTService     *uartServicePtr;
+Ticker          ticker;
+#if DEBUG
+Serial          pc(P0_4,P0_0);
+#endif
+
+//  ROM / Constant data ---------------------------------------------------------------------------
+const char      *deviceName = "JH1PJL";
+const uint8_t   pwr_range[PWR_RANG_NO] =
+                    {
+                    RADIO_TXPOWER_TXPOWER_Neg30dBm,/*!< -30dBm. */
+                    RADIO_TXPOWER_TXPOWER_Neg20dBm,/*!< -20dBm. */
+                    RADIO_TXPOWER_TXPOWER_Neg16dBm,/*!< -16dBm. */
+                    RADIO_TXPOWER_TXPOWER_Neg12dBm,/*!< -12dBm. */
+                    RADIO_TXPOWER_TXPOWER_Neg8dBm, /*!< -8dBm.  */
+                    RADIO_TXPOWER_TXPOWER_Neg4dBm, /*!< -4dBm.  */
+                    RADIO_TXPOWER_TXPOWER_0dBm,    /*!< 0dBm.   */
+                    RADIO_TXPOWER_TXPOWER_Pos4dBm, /*!< +4dBm.  */
+                    };
 
-void onDataWritten(const GattWriteCallbackParams *params)
-{
-    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
-        uint16_t bytesRead = params->len;
-        DEBUG("received %u bytes\n\r", bytesRead);
-        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
-    }
-}
+//  RAM -------------------------------------------------------------------------------------------
+uint8_t tx_buf[TXRX_BUF_LEN];
+uint8_t tx_len=0;
+uint8_t time_data[TXRX_BUF_LEN];
+uint8_t pwr_selection;
+volatile bool trigger_transmit = false;
+volatile bool trigger_receive = false;
+volatile uint8_t command_continue = 0;
+TX_Content transmit_contents;
+uint8_t time_out_cntr = 120;
+volatile bool time_out = false;
 
-void periodicCallback(void)
-{
-    led1 = !led1;
-}
+//  Function prototypes ---------------------------------------------------------------------------
+//      BLE
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params);
+void onDataWritten(const GattWriteCallbackParams *params);
+void periodicCallback(void);
+//      Application related
+void action_tx_help(void);
+void action_tx_vdd(void);
+void action_tx_temperature(void);
+void action_tx_pwrup(void);
+void action_tx_pwrdwn(void);
+void fill_space_n(uint8_t *bf, uint8_t n);
+void Update_Values(void);
+//      Interrupt related
+void action_tx_quit(void);
+void interrupt_by_sw(void);
 
-int main(void)
-{
-    led1 = 1;
-    Ticker ticker;
+//-------------------------------------------------------------------------------------------------
+//  Control Program
+//-------------------------------------------------------------------------------------------------
+int main(void){
+    myled = 1;
     ticker.attach(periodicCallback, 1);
-
-    DEBUG("Initialising the nRF51822\n\r");
+    // Interrupt by switch
+    wake_up_sw.fall(&interrupt_by_sw);
+    DEBUG("Initialising the nRF51822\r\n");
     ble.init();
+    //ble.setDeviceName((const uint8_t *)deviceName);
     ble.onDisconnection(disconnectionCallback);
     ble.onDataWritten(onDataWritten);
-
     /* setup advertising */
     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
-                                     (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1);
+                                    (const uint8_t *)deviceName,
+                                     strlen(deviceName)
+                                    );
     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
-                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
-
+                                    (const uint8_t *)UARTServiceUUID_reversed,
+                                     sizeof(UARTServiceUUID_reversed)
+                                    );
+    // Power
+#if HIGH_PWR
+    pwr_selection = 7;
+#else
+    pwr_selection = 0;
+#endif
+    ble.gap().setTxPower(pwr_range[pwr_selection]);
+    // Advertize Interval
     ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */
+    // Start
     ble.startAdvertising();
-
     UARTService uartService(ble);
     uartServicePtr = &uartService;
+    while(true){
+        if (time_out){
+            myled = 0;
+            wakeup.set_and_wait(120);
+            while(true){    // never come here but just in case
+                deepsleep();
+            }
+        }
+        if (trigger_transmit){
+            trigger_transmit = false;
+            switch(transmit_contents){
+                case TX_VDD:
+                    action_tx_vdd();
+                    break;
+                case TX_TEMP:
+                    action_tx_temperature();
+                    break;
+                case TX_QUIT:
+                    action_tx_quit();
+                    break;
+                case TX_PWR_UP:
+                    action_tx_pwrup();
+                    break;
+                case TX_PWR_DWN:
+                    action_tx_pwrdwn();
+                    break;
+                case TX_HELP:
+                    action_tx_help();
+                    break;
+                default:
+                    break;
+            }
+        } else {
+            myled = !myled;
+            ble.waitForEvent();
+        }
+    }
+}
 
-    while (true) {
-        ble.waitForEvent();
+void onDataWritten(const GattWriteCallbackParams *params){
+    uint8_t buf[TXRX_BUF_LEN];
+    uint16_t bytesRead;
+
+    if ((uartServicePtr != NULL) && 
+        (params->handle == uartServicePtr->getTXCharacteristicHandle()))
+    {
+        strcpy((char *)buf, (const char *)params->data);
+        bytesRead = params->len;
+        switch (buf[0]){
+            case 'v':
+                trigger_transmit = true;
+                transmit_contents = TX_VDD;
+                break;
+            case 't':
+                trigger_transmit = true;
+                transmit_contents = TX_TEMP;
+                break;
+            case 'u':
+                trigger_transmit = true;
+                transmit_contents = TX_PWR_UP;
+                break;
+            case 'd':
+                trigger_transmit = true;
+                transmit_contents = TX_PWR_DWN;
+                break;
+            case 'q':
+                trigger_transmit = true;
+                transmit_contents = TX_QUIT;
+                break;
+            case 'h':
+            case '?':
+                trigger_transmit = true;
+                transmit_contents = TX_HELP;
+                break;
+            default:
+                break;
+        }
+        fill_space_n(buf, bytesRead);
+        DEBUG("RX_data\r\n");
+        DEBUG("Length: %d\r\n", bytesRead);
+        DEBUG("Data: ");
+        DEBUG("%s", buf);
+        DEBUG("\r\n");
     }
 }
+
+void action_tx_help(){
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"?:help by JH1PJL");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.1);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"v:vdd");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.1);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"t:temperature");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.1);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"u:power up");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.1);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"d:power down");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.1);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"q(0x71):quit/sleep");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+}
+
+void action_tx_pwrup(){
+    if (pwr_selection != 0){
+        --pwr_selection;
+    }
+    ble.gap().setTxPower(pwr_range[pwr_selection]);
+    sprintf((char *)tx_buf,"Pwr:%+ddBm", (4 - (pwr_selection * 4)));
+    tx_len = strlen((const char *)tx_buf);
+    Update_Values();
+}
+
+void action_tx_pwrdwn(){
+    if (pwr_selection != (PWR_RANG_NO - 1)){
+        ++pwr_selection;
+    }
+    ble.gap().setTxPower(pwr_range[pwr_selection]);  
+    sprintf((char *)tx_buf,"Pwr:%+ddBm", (4 - (pwr_selection * 4)));
+    tx_len = strlen((const char *)tx_buf);
+    Update_Values();
+}
+
+void action_tx_vdd(){
+    sprintf((char *)tx_buf,"Vdd:%3.2fV", vdd.read_real_value());
+    tx_len = strlen((const char *)tx_buf);
+    Update_Values();
+}
+
+void action_tx_temperature(){
+    int32_t p_temp;
+    float temperature;
+ 
+    // Update a temperature (inside nRF51822 chip)
+    sd_temp_get(&p_temp);
+    // -16.0f is offset vale for chip die temp to ambient temp (depend on your board)
+    temperature = float(p_temp) / 4; // Original = float(p_temp)/4.0f - 16.0f;
+    sprintf((char *)tx_buf,"T:%+4.1fdC", temperature);
+    tx_len = strlen((const char *)tx_buf);
+    Update_Values();
+}
+
+void action_tx_quit(){
+    ticker.detach();
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"Terminated the BLE");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    myled = 0;
+    wait(1.0);
+    wakeup.set_and_wait(120);
+    while(true){    // never come here but just in case
+        deepsleep();
+    }
+}
+
+void interrupt_by_sw(){         // Go to sleep
+    NVIC_SystemReset();
+    // Not come here (Just in case)
+    deepsleep();
+}
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
+    DEBUG("Disconnected!\r\n");
+    DEBUG("Restarting the advertising process\r\n");
+    ble.startAdvertising();
+}
+
+void periodicCallback(void){
+    if (--time_out_cntr == 0){
+        time_out = true;
+    }
+}
+
+void fill_space_n(uint8_t *bf, uint8_t n){
+    bf += n;
+    for (uint8_t i = n; i <= 20; bf++, i++){
+        *bf = ' ';
+    }
+    *bf = '.';
+    *(bf + 1) = 0;
+}
+
+void Update_Values(void){
+    ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),
+                                  tx_buf,
+                                  tx_len
+                                 );
+    DEBUG("TX_data: %s\r\n", tx_buf);
+    DEBUG("Length: %d\r\n", tx_len);
+    tx_len = 0;
+}
+