BLE ー> USBシリアル変換します。 通信速度は9600bps固定です。

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

うまく接続できない時は、iPhone/iPadのBluetoothをOFF->ONしてキャッシュをクリアしてみてください。

"#define"を修正して”Nordic UART Service”用UUIDを選択すると、NORDICのデモアプリ"nRF UART 2.0 for Android"にも接続できました。(main.cpp 38行目)

https://play.google.com/store/apps/details?id=com.nordicsemi.nrfUARTv2&hl=en

/media/uploads/robo8080/---------_2014-09-22_15.29.32.png

Revision:
6:a50b4fd97e1a
Parent:
5:4bc41267a03a
--- a/main.cpp	Tue Sep 02 16:32:58 2014 +0000
+++ b/main.cpp	Tue Sep 16 00:58:53 2014 +0000
@@ -21,26 +21,39 @@
 #define BLE_UUID_NUS_TX_CHARACTERISTIC  0x0002 /**< The UUID of the TX Characteristic. */
 #define BLE_UUID_NUS_RX_CHARACTERISTIC  0x0003 /**< The UUID of the RX Characteristic. */
 
-#define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console;
+#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. */
 
 #if NEED_CONSOLE_OUTPUT
-Serial  pc(USBTX, USBRX);
+//Serial  pc(USBTX, USBRX);
 #define DEBUG(...) { pc.printf(__VA_ARGS__); }
 #else
 #define DEBUG(...) /* nothing */
 #endif /* #if NEED_CONSOLE_OUTPUT */
 
+Serial  pc(USBTX, USBRX);
 BLEDevice  ble;
 DigitalOut led1(LED1);
 
+#define USE_BLE_SERIAL_UUID 1   //BLESerialのUUIDを使う時1にする
+#if USE_BLE_SERIAL_UUID
+// BLESerial
+const static char  DEVICE_NAME[] = "BLESerial";
+static const uint8_t uart_base_uuid[] = {0x56,0x9a,0x11,0x01,0xb8,0x7F,0x49,0x0c,0x92,0xcb,0x11,0xba,0x5e,0xa5,0x16,0x7c};
+static const uint8_t uart_tx_uuid[]   = {0x56,0x9a,0x20,0x01,0xb8,0x7F,0x49,0x0c,0x92,0xcb,0x11,0xba,0x5e,0xa5,0x16,0x7c};
+static const uint8_t uart_rx_uuid[]   = {0x56,0x9a,0x20,0x00,0xb8,0x7F,0x49,0x0c,0x92,0xcb,0x11,0xba,0x5e,0xa5,0x16,0x7c};
+static const uint8_t uart_base_uuid_rev[] = {0x7c,0x16,0xa5,0x5e,0xba,0x11,0xcb,0x92,0x0c,0x49,0x7F,0xb8,0x01,0x11,0x9a,0x56};
+#else
 // The Nordic UART Service
+const static char  DEVICE_NAME[] = "mbed HRM1017";
 static const uint8_t uart_base_uuid[] = {0x6e, 0x40, 0x00, 0x01, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5,0x0e, 0x24, 0xdc, 0xca, 0x9e};
 static const uint8_t uart_tx_uuid[]   = {0x6e, 0x40, 0x00, 0x02, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5,0x0e, 0x24, 0xdc, 0xca, 0x9e};
 static const uint8_t uart_rx_uuid[]   = {0x6e, 0x40, 0x00, 0x03, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5,0x0e, 0x24, 0xdc, 0xca, 0x9e};
 static const uint8_t uart_base_uuid_rev[] = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e};
+#endif
 
-static const uint8_t SIZEOF_TX_RX_BUFFER = 128;
+//static const uint8_t SIZEOF_TX_RX_BUFFER = 128;
+static const uint8_t SIZEOF_TX_RX_BUFFER = 20;
 uint8_t rxPayload[SIZEOF_TX_RX_BUFFER] = {0,};
 uint8_t txPayload[SIZEOF_TX_RX_BUFFER] = {0,};
 GattCharacteristic  rxCharacteristic (uart_tx_uuid, rxPayload, 1, SIZEOF_TX_RX_BUFFER,
@@ -52,9 +65,15 @@
 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
 {
     DEBUG("Disconnected!\n\r");
+    led1 = 1;
     DEBUG("Restarting the advertising process\n\r");
     ble.startAdvertising();
 }
+void onConnectionCallback(Gap::Handle_t handle, const Gap::ConnectionParams_t *params)
+{
+    DEBUG("connected. Got handle %u\r\n", handle);
+    led1 = 0;
+}
 
 void onDataWritten(uint16_t charHandle, const GattCharacteristicWriteCBParams *params)
 {
@@ -66,40 +85,97 @@
             rxPayload[bytesRead] = 0;
         }
         DEBUG("ECHO: %s\n\r", (char *)rxPayload);
+#if NEED_CONSOLE_OUTPUT
         ble.updateCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), rxPayload, bytesRead);
+#else
+        for(int i = 0; i < bytesRead; i++) {
+            pc.putc(rxPayload[i]);
+        }
+#endif  //NEED_CONSOLE_OUTPUT
     }
 }
 
+static volatile bool uartTxUpdatesEnable = false;
+void onUpdatesEnabled(uint16_t charHandle)
+{
+    DEBUG("onUpdatesEnabled handle %u!\n\r", charHandle);
+    if (charHandle == txCharacteristic.getValueAttribute().getHandle()) {
+        DEBUG("uartRxCharacteristic!\n\r");
+        uartTxUpdatesEnable = true;
+    }              
+}
+void onUpdatesDisabled(uint16_t charHandle)
+{
+    DEBUG("onUpdatesDisabled handle %u!\n\r", charHandle);
+    if (charHandle == txCharacteristic.getValueAttribute().getHandle()) {
+        DEBUG("uartRxCharacteristic!\n\r");
+        uartTxUpdatesEnable = false;
+    }                     
+}
+static volatile bool triggerUartPolling = false;
 void periodicCallback(void)
 {
-    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
+//    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
+    /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
+     * heavy-weight sensor polling from the main thread. */
+    triggerUartPolling = true;
 }
 
 int main(void)
 {
     led1 = 1;
     Ticker ticker;
-    ticker.attach(periodicCallback, 1);
+    ticker.attach(periodicCallback, 0.1);       //100ms
 
     DEBUG("Initialising the nRF51822\n\r");
     ble.init();
+    ble.setDeviceName((uint8_t *)DEVICE_NAME);
+    ble.onConnection(onConnectionCallback);
     ble.onDisconnection(disconnectionCallback);
     ble.onDataWritten(onDataWritten);
+    ble.onUpdatesEnabled(onUpdatesEnabled);
+    ble.onUpdatesDisabled(onUpdatesDisabled);
 
     /* setup advertising */
     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+#if USE_BLE_SERIAL_UUID
     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
-                                    (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1);
+                                    (const uint8_t *)"BLESerial", sizeof("BLESerial") - 1);
+#else
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
+                                    (const uint8_t *)"HRM1017", sizeof("HRM1017") - 1);
+#endif
     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                     (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
-
     ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
     ble.startAdvertising();
 
     ble.addService(uartService);
 
     while (true) {
-        ble.waitForEvent();
+        if (triggerUartPolling) {
+            triggerUartPolling = false;
+            /* Do blocking calls or whatever is necessary for sensor polling. */
+            if(ble.getGapState().connected) { 
+#if !NEED_CONSOLE_OUTPUT
+                if(uartTxUpdatesEnable) {
+                    uint16_t bytesRead = 0;
+                    while(pc.readable()) {
+                        if (bytesRead < sizeof(txPayload)) {
+                            txPayload[bytesRead++] = pc.getc();
+                        } else {
+                            break;
+                        }
+                    }
+                    if(bytesRead > 0) {    
+                        ble.updateCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), (uint8_t*)txPayload, bytesRead);
+                    }
+                }
+#endif
+            }
+        } else {
+            ble.waitForEvent();
+        }
     }
 }