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

Committer:
robo8080
Date:
Tue Sep 16 00:58:53 2014 +0000
Revision:
6:a50b4fd97e1a
Parent:
5:4bc41267a03a
test1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:e910d9bb040f 1 /* mbed Microcontroller Library
yihui 0:e910d9bb040f 2 * Copyright (c) 2006-2013 ARM Limited
yihui 0:e910d9bb040f 3 *
yihui 0:e910d9bb040f 4 * Licensed under the Apache License, Version 2.0 (the "License");
yihui 0:e910d9bb040f 5 * you may not use this file except in compliance with the License.
yihui 0:e910d9bb040f 6 * You may obtain a copy of the License at
yihui 0:e910d9bb040f 7 *
yihui 0:e910d9bb040f 8 * http://www.apache.org/licenses/LICENSE-2.0
yihui 0:e910d9bb040f 9 *
yihui 0:e910d9bb040f 10 * Unless required by applicable law or agreed to in writing, software
yihui 0:e910d9bb040f 11 * distributed under the License is distributed on an "AS IS" BASIS,
yihui 0:e910d9bb040f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
yihui 0:e910d9bb040f 13 * See the License for the specific language governing permissions and
yihui 0:e910d9bb040f 14 * limitations under the License.
yihui 0:e910d9bb040f 15 */
yihui 0:e910d9bb040f 16
yihui 0:e910d9bb040f 17 #include "mbed.h"
Rohit Grover 2:e060367b9024 18 #include "BLEDevice.h"
yihui 0:e910d9bb040f 19
Rohit Grover 2:e060367b9024 20 #define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */
Rohit Grover 2:e060367b9024 21 #define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */
Rohit Grover 2:e060367b9024 22 #define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */
yihui 0:e910d9bb040f 23
robo8080 6:a50b4fd97e1a 24 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
Rohit Grover 2:e060367b9024 25 * it will have an impact on code-size and power consumption. */
yihui 0:e910d9bb040f 26
Rohit Grover 2:e060367b9024 27 #if NEED_CONSOLE_OUTPUT
robo8080 6:a50b4fd97e1a 28 //Serial pc(USBTX, USBRX);
Rohit Grover 2:e060367b9024 29 #define DEBUG(...) { pc.printf(__VA_ARGS__); }
yihui 0:e910d9bb040f 30 #else
Rohit Grover 2:e060367b9024 31 #define DEBUG(...) /* nothing */
Rohit Grover 2:e060367b9024 32 #endif /* #if NEED_CONSOLE_OUTPUT */
yihui 0:e910d9bb040f 33
robo8080 6:a50b4fd97e1a 34 Serial pc(USBTX, USBRX);
Rohit Grover 2:e060367b9024 35 BLEDevice ble;
Rohit Grover 2:e060367b9024 36 DigitalOut led1(LED1);
yihui 0:e910d9bb040f 37
robo8080 6:a50b4fd97e1a 38 #define USE_BLE_SERIAL_UUID 1 //BLESerialのUUIDを使う時1にする
robo8080 6:a50b4fd97e1a 39 #if USE_BLE_SERIAL_UUID
robo8080 6:a50b4fd97e1a 40 // BLESerial
robo8080 6:a50b4fd97e1a 41 const static char DEVICE_NAME[] = "BLESerial";
robo8080 6:a50b4fd97e1a 42 static const uint8_t uart_base_uuid[] = {0x56,0x9a,0x11,0x01,0xb8,0x7F,0x49,0x0c,0x92,0xcb,0x11,0xba,0x5e,0xa5,0x16,0x7c};
robo8080 6:a50b4fd97e1a 43 static const uint8_t uart_tx_uuid[] = {0x56,0x9a,0x20,0x01,0xb8,0x7F,0x49,0x0c,0x92,0xcb,0x11,0xba,0x5e,0xa5,0x16,0x7c};
robo8080 6:a50b4fd97e1a 44 static const uint8_t uart_rx_uuid[] = {0x56,0x9a,0x20,0x00,0xb8,0x7F,0x49,0x0c,0x92,0xcb,0x11,0xba,0x5e,0xa5,0x16,0x7c};
robo8080 6:a50b4fd97e1a 45 static const uint8_t uart_base_uuid_rev[] = {0x7c,0x16,0xa5,0x5e,0xba,0x11,0xcb,0x92,0x0c,0x49,0x7F,0xb8,0x01,0x11,0x9a,0x56};
robo8080 6:a50b4fd97e1a 46 #else
yihui 0:e910d9bb040f 47 // The Nordic UART Service
robo8080 6:a50b4fd97e1a 48 const static char DEVICE_NAME[] = "mbed HRM1017";
Rohit Grover 2:e060367b9024 49 static const uint8_t uart_base_uuid[] = {0x6e, 0x40, 0x00, 0x01, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5,0x0e, 0x24, 0xdc, 0xca, 0x9e};
Rohit Grover 2:e060367b9024 50 static const uint8_t uart_tx_uuid[] = {0x6e, 0x40, 0x00, 0x02, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5,0x0e, 0x24, 0xdc, 0xca, 0x9e};
Rohit Grover 2:e060367b9024 51 static const uint8_t uart_rx_uuid[] = {0x6e, 0x40, 0x00, 0x03, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5,0x0e, 0x24, 0xdc, 0xca, 0x9e};
Rohit Grover 2:e060367b9024 52 static const uint8_t uart_base_uuid_rev[] = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e};
robo8080 6:a50b4fd97e1a 53 #endif
rgrover1 5:4bc41267a03a 54
robo8080 6:a50b4fd97e1a 55 //static const uint8_t SIZEOF_TX_RX_BUFFER = 128;
robo8080 6:a50b4fd97e1a 56 static const uint8_t SIZEOF_TX_RX_BUFFER = 20;
rgrover1 5:4bc41267a03a 57 uint8_t rxPayload[SIZEOF_TX_RX_BUFFER] = {0,};
rgrover1 5:4bc41267a03a 58 uint8_t txPayload[SIZEOF_TX_RX_BUFFER] = {0,};
rgrover1 5:4bc41267a03a 59 GattCharacteristic rxCharacteristic (uart_tx_uuid, rxPayload, 1, SIZEOF_TX_RX_BUFFER,
Rohit Grover 2:e060367b9024 60 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
rgrover1 5:4bc41267a03a 61 GattCharacteristic txCharacteristic (uart_rx_uuid, txPayload, 1, SIZEOF_TX_RX_BUFFER, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
rgrover1 5:4bc41267a03a 62 GattCharacteristic *uartChars[] = {&rxCharacteristic, &txCharacteristic};
Rohit Grover 2:e060367b9024 63 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
yihui 0:e910d9bb040f 64
rgrover1 5:4bc41267a03a 65 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
yihui 0:e910d9bb040f 66 {
Rohit Grover 2:e060367b9024 67 DEBUG("Disconnected!\n\r");
robo8080 6:a50b4fd97e1a 68 led1 = 1;
Rohit Grover 2:e060367b9024 69 DEBUG("Restarting the advertising process\n\r");
Rohit Grover 2:e060367b9024 70 ble.startAdvertising();
Rohit Grover 2:e060367b9024 71 }
robo8080 6:a50b4fd97e1a 72 void onConnectionCallback(Gap::Handle_t handle, const Gap::ConnectionParams_t *params)
robo8080 6:a50b4fd97e1a 73 {
robo8080 6:a50b4fd97e1a 74 DEBUG("connected. Got handle %u\r\n", handle);
robo8080 6:a50b4fd97e1a 75 led1 = 0;
robo8080 6:a50b4fd97e1a 76 }
yihui 0:e910d9bb040f 77
rgrover1 5:4bc41267a03a 78 void onDataWritten(uint16_t charHandle, const GattCharacteristicWriteCBParams *params)
yihui 0:e910d9bb040f 79 {
rgrover1 5:4bc41267a03a 80 if (charHandle == rxCharacteristic.getValueAttribute().getHandle()) {
rgrover1 5:4bc41267a03a 81 uint16_t bytesRead = params->len;
rgrover1 5:4bc41267a03a 82 DEBUG("received %u bytes\n\r", bytesRead);
rgrover1 5:4bc41267a03a 83 if (bytesRead < sizeof(rxPayload)) {
rgrover1 5:4bc41267a03a 84 memcpy(rxPayload, params->data, bytesRead);
rgrover1 5:4bc41267a03a 85 rxPayload[bytesRead] = 0;
rgrover1 5:4bc41267a03a 86 }
rgrover1 5:4bc41267a03a 87 DEBUG("ECHO: %s\n\r", (char *)rxPayload);
robo8080 6:a50b4fd97e1a 88 #if NEED_CONSOLE_OUTPUT
rgrover1 5:4bc41267a03a 89 ble.updateCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), rxPayload, bytesRead);
robo8080 6:a50b4fd97e1a 90 #else
robo8080 6:a50b4fd97e1a 91 for(int i = 0; i < bytesRead; i++) {
robo8080 6:a50b4fd97e1a 92 pc.putc(rxPayload[i]);
robo8080 6:a50b4fd97e1a 93 }
robo8080 6:a50b4fd97e1a 94 #endif //NEED_CONSOLE_OUTPUT
yihui 0:e910d9bb040f 95 }
Rohit Grover 2:e060367b9024 96 }
yihui 0:e910d9bb040f 97
robo8080 6:a50b4fd97e1a 98 static volatile bool uartTxUpdatesEnable = false;
robo8080 6:a50b4fd97e1a 99 void onUpdatesEnabled(uint16_t charHandle)
robo8080 6:a50b4fd97e1a 100 {
robo8080 6:a50b4fd97e1a 101 DEBUG("onUpdatesEnabled handle %u!\n\r", charHandle);
robo8080 6:a50b4fd97e1a 102 if (charHandle == txCharacteristic.getValueAttribute().getHandle()) {
robo8080 6:a50b4fd97e1a 103 DEBUG("uartRxCharacteristic!\n\r");
robo8080 6:a50b4fd97e1a 104 uartTxUpdatesEnable = true;
robo8080 6:a50b4fd97e1a 105 }
robo8080 6:a50b4fd97e1a 106 }
robo8080 6:a50b4fd97e1a 107 void onUpdatesDisabled(uint16_t charHandle)
robo8080 6:a50b4fd97e1a 108 {
robo8080 6:a50b4fd97e1a 109 DEBUG("onUpdatesDisabled handle %u!\n\r", charHandle);
robo8080 6:a50b4fd97e1a 110 if (charHandle == txCharacteristic.getValueAttribute().getHandle()) {
robo8080 6:a50b4fd97e1a 111 DEBUG("uartRxCharacteristic!\n\r");
robo8080 6:a50b4fd97e1a 112 uartTxUpdatesEnable = false;
robo8080 6:a50b4fd97e1a 113 }
robo8080 6:a50b4fd97e1a 114 }
robo8080 6:a50b4fd97e1a 115 static volatile bool triggerUartPolling = false;
Rohit Grover 2:e060367b9024 116 void periodicCallback(void)
Rohit Grover 2:e060367b9024 117 {
robo8080 6:a50b4fd97e1a 118 // led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
robo8080 6:a50b4fd97e1a 119 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
robo8080 6:a50b4fd97e1a 120 * heavy-weight sensor polling from the main thread. */
robo8080 6:a50b4fd97e1a 121 triggerUartPolling = true;
Rohit Grover 2:e060367b9024 122 }
yihui 0:e910d9bb040f 123
yihui 0:e910d9bb040f 124 int main(void)
yihui 0:e910d9bb040f 125 {
Rohit Grover 2:e060367b9024 126 led1 = 1;
Rohit Grover 2:e060367b9024 127 Ticker ticker;
robo8080 6:a50b4fd97e1a 128 ticker.attach(periodicCallback, 0.1); //100ms
yihui 0:e910d9bb040f 129
Rohit Grover 2:e060367b9024 130 DEBUG("Initialising the nRF51822\n\r");
Rohit Grover 2:e060367b9024 131 ble.init();
robo8080 6:a50b4fd97e1a 132 ble.setDeviceName((uint8_t *)DEVICE_NAME);
robo8080 6:a50b4fd97e1a 133 ble.onConnection(onConnectionCallback);
Rohit Grover 2:e060367b9024 134 ble.onDisconnection(disconnectionCallback);
Rohit Grover 2:e060367b9024 135 ble.onDataWritten(onDataWritten);
robo8080 6:a50b4fd97e1a 136 ble.onUpdatesEnabled(onUpdatesEnabled);
robo8080 6:a50b4fd97e1a 137 ble.onUpdatesDisabled(onUpdatesDisabled);
yihui 0:e910d9bb040f 138
Rohit Grover 2:e060367b9024 139 /* setup advertising */
Rohit Grover 2:e060367b9024 140 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
Rohit Grover 2:e060367b9024 141 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
robo8080 6:a50b4fd97e1a 142 #if USE_BLE_SERIAL_UUID
Rohit Grover 2:e060367b9024 143 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
robo8080 6:a50b4fd97e1a 144 (const uint8_t *)"BLESerial", sizeof("BLESerial") - 1);
robo8080 6:a50b4fd97e1a 145 #else
robo8080 6:a50b4fd97e1a 146 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
robo8080 6:a50b4fd97e1a 147 (const uint8_t *)"HRM1017", sizeof("HRM1017") - 1);
robo8080 6:a50b4fd97e1a 148 #endif
Rohit Grover 2:e060367b9024 149 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
Rohit Grover 2:e060367b9024 150 (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
Rohit Grover 2:e060367b9024 151 ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
Rohit Grover 2:e060367b9024 152 ble.startAdvertising();
yihui 0:e910d9bb040f 153
Rohit Grover 2:e060367b9024 154 ble.addService(uartService);
yihui 0:e910d9bb040f 155
Rohit Grover 2:e060367b9024 156 while (true) {
robo8080 6:a50b4fd97e1a 157 if (triggerUartPolling) {
robo8080 6:a50b4fd97e1a 158 triggerUartPolling = false;
robo8080 6:a50b4fd97e1a 159 /* Do blocking calls or whatever is necessary for sensor polling. */
robo8080 6:a50b4fd97e1a 160 if(ble.getGapState().connected) {
robo8080 6:a50b4fd97e1a 161 #if !NEED_CONSOLE_OUTPUT
robo8080 6:a50b4fd97e1a 162 if(uartTxUpdatesEnable) {
robo8080 6:a50b4fd97e1a 163 uint16_t bytesRead = 0;
robo8080 6:a50b4fd97e1a 164 while(pc.readable()) {
robo8080 6:a50b4fd97e1a 165 if (bytesRead < sizeof(txPayload)) {
robo8080 6:a50b4fd97e1a 166 txPayload[bytesRead++] = pc.getc();
robo8080 6:a50b4fd97e1a 167 } else {
robo8080 6:a50b4fd97e1a 168 break;
robo8080 6:a50b4fd97e1a 169 }
robo8080 6:a50b4fd97e1a 170 }
robo8080 6:a50b4fd97e1a 171 if(bytesRead > 0) {
robo8080 6:a50b4fd97e1a 172 ble.updateCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), (uint8_t*)txPayload, bytesRead);
robo8080 6:a50b4fd97e1a 173 }
robo8080 6:a50b4fd97e1a 174 }
robo8080 6:a50b4fd97e1a 175 #endif
robo8080 6:a50b4fd97e1a 176 }
robo8080 6:a50b4fd97e1a 177 } else {
robo8080 6:a50b4fd97e1a 178 ble.waitForEvent();
robo8080 6:a50b4fd97e1a 179 }
yihui 0:e910d9bb040f 180 }
yihui 0:e910d9bb040f 181 }