A simple program that uses the UARTService to transfer string data over GATT. Can be used with the nRF Toolbox app for rapid prototyping.

Dependencies:   BLE_API mbed nRF51822

Fork of UART_TEMPLATE by daniel veilleux

Committer:
VicenteFerrara
Date:
Wed Jun 21 01:33:50 2017 +0000
Revision:
1:32c6991f7180
Parent:
0:442c7a6f1978
Leer caracter?stica y responder en base a ello

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Daniel Veilleux 0:442c7a6f1978 1 /* mbed Microcontroller Library
Daniel Veilleux 0:442c7a6f1978 2 * Copyright (c) 2006-2013 ARM Limited
Daniel Veilleux 0:442c7a6f1978 3 *
Daniel Veilleux 0:442c7a6f1978 4 * Licensed under the Apache License, Version 2.0 (the "License");
Daniel Veilleux 0:442c7a6f1978 5 * you may not use this file except in compliance with the License.
Daniel Veilleux 0:442c7a6f1978 6 * You may obtain a copy of the License at
Daniel Veilleux 0:442c7a6f1978 7 *
Daniel Veilleux 0:442c7a6f1978 8 * http://www.apache.org/licenses/LICENSE-2.0
Daniel Veilleux 0:442c7a6f1978 9 *
Daniel Veilleux 0:442c7a6f1978 10 * Unless required by applicable law or agreed to in writing, software
Daniel Veilleux 0:442c7a6f1978 11 * distributed under the License is distributed on an "AS IS" BASIS,
Daniel Veilleux 0:442c7a6f1978 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Daniel Veilleux 0:442c7a6f1978 13 * See the License for the specific language governing permissions and
Daniel Veilleux 0:442c7a6f1978 14 * limitations under the License.
Daniel Veilleux 0:442c7a6f1978 15 */
Daniel Veilleux 0:442c7a6f1978 16
Daniel Veilleux 0:442c7a6f1978 17 #include "mbed.h"
Daniel Veilleux 0:442c7a6f1978 18 #include "BLEDevice.h"
Daniel Veilleux 0:442c7a6f1978 19 #include "UARTService.h"
Daniel Veilleux 0:442c7a6f1978 20 #include "nrf_temp.h"
Daniel Veilleux 0:442c7a6f1978 21
Daniel Veilleux 0:442c7a6f1978 22 #define MAX_REPLY_LEN (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN)
Daniel Veilleux 0:442c7a6f1978 23 #define SENSOR_READ_INTERVAL_S (0.5F)
Daniel Veilleux 0:442c7a6f1978 24 #define ADV_INTERVAL_MS (1000UL)
Daniel Veilleux 0:442c7a6f1978 25 #define UART_BAUD_RATE (19200UL)
VicenteFerrara 1:32c6991f7180 26 #define DEVICE_NAME ("EVA") // This can be read AFTER connecting to the device.
VicenteFerrara 1:32c6991f7180 27 #define SHORT_NAME ("EVA") // Keep this short: max 8 chars if a 128bit UUID is also advertised.
Daniel Veilleux 0:442c7a6f1978 28
Daniel Veilleux 0:442c7a6f1978 29 #define DEBUG(...) { m_serial_port.printf(__VA_ARGS__); }
Daniel Veilleux 0:442c7a6f1978 30
VicenteFerrara 1:32c6991f7180 31 //static const char DEVICE_NAME[] = "EVA";
Daniel Veilleux 0:442c7a6f1978 32
Daniel Veilleux 0:442c7a6f1978 33 BLEDevice m_ble;
Daniel Veilleux 0:442c7a6f1978 34 Serial m_serial_port(p9, p11); // TX pin, RX pin
VicenteFerrara 1:32c6991f7180 35 Serial pc(USBTX, USBRX); // tx, rx
VicenteFerrara 1:32c6991f7180 36 DigitalOut led1(LED1);
Daniel Veilleux 0:442c7a6f1978 37 AnalogIn m_analog_in(p1);
Daniel Veilleux 0:442c7a6f1978 38 uint16_t m_analog_in_value;
Daniel Veilleux 0:442c7a6f1978 39 UARTService *m_uart_service_ptr;
Daniel Veilleux 0:442c7a6f1978 40
Daniel Veilleux 0:442c7a6f1978 41
Daniel Veilleux 0:442c7a6f1978 42 /**
Daniel Veilleux 0:442c7a6f1978 43 * This callback is used whenever a disconnection occurs.
Daniel Veilleux 0:442c7a6f1978 44 */
Daniel Veilleux 0:442c7a6f1978 45 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
Daniel Veilleux 0:442c7a6f1978 46 {
Daniel Veilleux 0:442c7a6f1978 47 switch (reason) {
Daniel Veilleux 0:442c7a6f1978 48 case Gap::REMOTE_USER_TERMINATED_CONNECTION:
Daniel Veilleux 0:442c7a6f1978 49 DEBUG("Disconnected (REMOTE_USER_TERMINATED_CONNECTION)\n\r");
Daniel Veilleux 0:442c7a6f1978 50 break;
Daniel Veilleux 0:442c7a6f1978 51 case Gap::LOCAL_HOST_TERMINATED_CONNECTION:
Daniel Veilleux 0:442c7a6f1978 52 DEBUG("Disconnected (LOCAL_HOST_TERMINATED_CONNECTION)\n\r");
Daniel Veilleux 0:442c7a6f1978 53 break;
Daniel Veilleux 0:442c7a6f1978 54 case Gap::CONN_INTERVAL_UNACCEPTABLE:
Daniel Veilleux 0:442c7a6f1978 55 DEBUG("Disconnected (CONN_INTERVAL_UNACCEPTABLE)\n\r");
Daniel Veilleux 0:442c7a6f1978 56 break;
Daniel Veilleux 0:442c7a6f1978 57 }
Daniel Veilleux 0:442c7a6f1978 58
Daniel Veilleux 0:442c7a6f1978 59 DEBUG("Restarting the advertising process\n\r");
Daniel Veilleux 0:442c7a6f1978 60 m_ble.startAdvertising();
Daniel Veilleux 0:442c7a6f1978 61 }
Daniel Veilleux 0:442c7a6f1978 62
Daniel Veilleux 0:442c7a6f1978 63
Daniel Veilleux 0:442c7a6f1978 64 /**
Daniel Veilleux 0:442c7a6f1978 65 * This callback is used whenever the host writes data to one of our GATT characteristics.
Daniel Veilleux 0:442c7a6f1978 66 */
Daniel Veilleux 0:442c7a6f1978 67 void dataWrittenCallback(const GattCharacteristicWriteCBParams *params)
Daniel Veilleux 0:442c7a6f1978 68 {
Daniel Veilleux 0:442c7a6f1978 69 // Ensure that initialization is finished and the host has written to the TX characteristic.
Daniel Veilleux 0:442c7a6f1978 70 if ((m_uart_service_ptr != NULL) && (params->charHandle == m_uart_service_ptr->getTXCharacteristicHandle())) {
Daniel Veilleux 0:442c7a6f1978 71 uint8_t buf[MAX_REPLY_LEN];
VicenteFerrara 1:32c6991f7180 72 uint8_t buf2[3]= {0xFF, 0x01, 0x02};
Daniel Veilleux 0:442c7a6f1978 73 uint32_t len = 0;
VicenteFerrara 1:32c6991f7180 74
Daniel Veilleux 0:442c7a6f1978 75 if (1 == params->len) {
Daniel Veilleux 0:442c7a6f1978 76 switch (params->data[0]) {
Daniel Veilleux 0:442c7a6f1978 77 case '0':
Daniel Veilleux 0:442c7a6f1978 78 len = snprintf((char*) buf, MAX_REPLY_LEN, "OK");
VicenteFerrara 1:32c6991f7180 79 pc.printf("Si llego prro\n");
Daniel Veilleux 0:442c7a6f1978 80 break;
VicenteFerrara 1:32c6991f7180 81 case 1:
VicenteFerrara 1:32c6991f7180 82 led1 = 1;
VicenteFerrara 1:32c6991f7180 83 wait(1.0);
VicenteFerrara 1:32c6991f7180 84 led1 = 0;
VicenteFerrara 1:32c6991f7180 85 wait(1.0);
VicenteFerrara 1:32c6991f7180 86 led1 = 1;
VicenteFerrara 1:32c6991f7180 87 wait(1.0);
VicenteFerrara 1:32c6991f7180 88 led1 = 0;
VicenteFerrara 1:32c6991f7180 89 len = snprintf((char*) buf, MAX_REPLY_LEN, "prrow");
Daniel Veilleux 0:442c7a6f1978 90 break;
Daniel Veilleux 0:442c7a6f1978 91 case 'a':
Daniel Veilleux 0:442c7a6f1978 92 len = snprintf((char*) buf, MAX_REPLY_LEN, "%d", m_analog_in_value);
Daniel Veilleux 0:442c7a6f1978 93 break;
Daniel Veilleux 0:442c7a6f1978 94 default:
Daniel Veilleux 0:442c7a6f1978 95 len = snprintf((char*) buf, MAX_REPLY_LEN, "ERROR: Unknown char");
Daniel Veilleux 0:442c7a6f1978 96 break;
Daniel Veilleux 0:442c7a6f1978 97 }
Daniel Veilleux 0:442c7a6f1978 98 }
Daniel Veilleux 0:442c7a6f1978 99 else
Daniel Veilleux 0:442c7a6f1978 100 {
Daniel Veilleux 0:442c7a6f1978 101 len = snprintf((char*) buf, MAX_REPLY_LEN, "ERROR: Invalid len");
Daniel Veilleux 0:442c7a6f1978 102 }
VicenteFerrara 1:32c6991f7180 103 //m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len);
VicenteFerrara 1:32c6991f7180 104 m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf2, 3);
Daniel Veilleux 0:442c7a6f1978 105
Daniel Veilleux 0:442c7a6f1978 106 DEBUG("%d bytes received from host\n\r", params->len);
Daniel Veilleux 0:442c7a6f1978 107 }
Daniel Veilleux 0:442c7a6f1978 108 }
Daniel Veilleux 0:442c7a6f1978 109
Daniel Veilleux 0:442c7a6f1978 110
Daniel Veilleux 0:442c7a6f1978 111 /**
Daniel Veilleux 0:442c7a6f1978 112 * This callback is used whenever a write to a GATT characteristic causes data to be sent to the host.
Daniel Veilleux 0:442c7a6f1978 113 */
Daniel Veilleux 0:442c7a6f1978 114 void dataSentCallback(unsigned count)
Daniel Veilleux 0:442c7a6f1978 115 {
Daniel Veilleux 0:442c7a6f1978 116 // NOTE: The count always seems to be 1 regardless of data.
Daniel Veilleux 0:442c7a6f1978 117 DEBUG("%d bytes sent to host\n\r", count);
Daniel Veilleux 0:442c7a6f1978 118 }
Daniel Veilleux 0:442c7a6f1978 119
Daniel Veilleux 0:442c7a6f1978 120
Daniel Veilleux 0:442c7a6f1978 121 /**
Daniel Veilleux 0:442c7a6f1978 122 * This callback is scheduled to be called periodically via a low-priority interrupt.
Daniel Veilleux 0:442c7a6f1978 123 */
Daniel Veilleux 0:442c7a6f1978 124 void periodicCallback(void)
Daniel Veilleux 0:442c7a6f1978 125 {
Daniel Veilleux 0:442c7a6f1978 126 m_analog_in_value = m_analog_in.read_u16();
Daniel Veilleux 0:442c7a6f1978 127 }
Daniel Veilleux 0:442c7a6f1978 128
Daniel Veilleux 0:442c7a6f1978 129
Daniel Veilleux 0:442c7a6f1978 130 void error(ble_error_t err, uint32_t line)
Daniel Veilleux 0:442c7a6f1978 131 {
VicenteFerrara 1:32c6991f7180 132 //m_error_led = 1;
Daniel Veilleux 0:442c7a6f1978 133 DEBUG("Error %d on line number %d\n\r", err, line);
Daniel Veilleux 0:442c7a6f1978 134 }
Daniel Veilleux 0:442c7a6f1978 135
Daniel Veilleux 0:442c7a6f1978 136
Daniel Veilleux 0:442c7a6f1978 137 int main(void)
Daniel Veilleux 0:442c7a6f1978 138 {
Daniel Veilleux 0:442c7a6f1978 139 ble_error_t err;
Daniel Veilleux 0:442c7a6f1978 140 Ticker ticker;
Daniel Veilleux 0:442c7a6f1978 141
Daniel Veilleux 0:442c7a6f1978 142 m_serial_port.baud(UART_BAUD_RATE);
Daniel Veilleux 0:442c7a6f1978 143
Daniel Veilleux 0:442c7a6f1978 144 DEBUG("Initialising\n\r");
Daniel Veilleux 0:442c7a6f1978 145
VicenteFerrara 1:32c6991f7180 146 led1 = 0;
Daniel Veilleux 0:442c7a6f1978 147 m_analog_in_value = 0;
Daniel Veilleux 0:442c7a6f1978 148
Daniel Veilleux 0:442c7a6f1978 149 ticker.attach(periodicCallback, SENSOR_READ_INTERVAL_S);
Daniel Veilleux 0:442c7a6f1978 150
Daniel Veilleux 0:442c7a6f1978 151 m_ble.init();
Daniel Veilleux 0:442c7a6f1978 152 m_ble.onDisconnection(disconnectionCallback);
Daniel Veilleux 0:442c7a6f1978 153 m_ble.onDataWritten(dataWrittenCallback);
Daniel Veilleux 0:442c7a6f1978 154 m_ble.onDataSent(dataSentCallback);
Daniel Veilleux 0:442c7a6f1978 155
Daniel Veilleux 0:442c7a6f1978 156 // Set the TX power in dBm units.
Daniel Veilleux 0:442c7a6f1978 157 // Possible values (in decreasing order): 4, 0, -4, -8, -12, -16, -20.
Daniel Veilleux 0:442c7a6f1978 158 err = m_ble.setTxPower(4);
Daniel Veilleux 0:442c7a6f1978 159 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 160 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 161 }
Daniel Veilleux 0:442c7a6f1978 162
Daniel Veilleux 0:442c7a6f1978 163 // Setup advertising (GAP stuff).
Daniel Veilleux 0:442c7a6f1978 164 err = m_ble.setDeviceName(DEVICE_NAME);
Daniel Veilleux 0:442c7a6f1978 165 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 166 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 167 }
Daniel Veilleux 0:442c7a6f1978 168
Daniel Veilleux 0:442c7a6f1978 169 err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
Daniel Veilleux 0:442c7a6f1978 170 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 171 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 172 }
Daniel Veilleux 0:442c7a6f1978 173
Daniel Veilleux 0:442c7a6f1978 174 m_ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
Daniel Veilleux 0:442c7a6f1978 175
Daniel Veilleux 0:442c7a6f1978 176 err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
Daniel Veilleux 0:442c7a6f1978 177 (const uint8_t *)SHORT_NAME,
Daniel Veilleux 0:442c7a6f1978 178 (sizeof(SHORT_NAME) - 1));
Daniel Veilleux 0:442c7a6f1978 179 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 180 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 181 }
Daniel Veilleux 0:442c7a6f1978 182
Daniel Veilleux 0:442c7a6f1978 183 err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
Daniel Veilleux 0:442c7a6f1978 184 (const uint8_t *)UARTServiceUUID_reversed,
Daniel Veilleux 0:442c7a6f1978 185 sizeof(UARTServiceUUID_reversed));
Daniel Veilleux 0:442c7a6f1978 186 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 187 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 188 }
Daniel Veilleux 0:442c7a6f1978 189
Daniel Veilleux 0:442c7a6f1978 190 m_ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADV_INTERVAL_MS));
Daniel Veilleux 0:442c7a6f1978 191 m_ble.startAdvertising();
Daniel Veilleux 0:442c7a6f1978 192
Daniel Veilleux 0:442c7a6f1978 193 // Create a UARTService object (GATT stuff).
Daniel Veilleux 0:442c7a6f1978 194 UARTService uartService(m_ble);
Daniel Veilleux 0:442c7a6f1978 195 m_uart_service_ptr = &uartService;
Daniel Veilleux 0:442c7a6f1978 196
Daniel Veilleux 0:442c7a6f1978 197 while (true) {
Daniel Veilleux 0:442c7a6f1978 198 m_ble.waitForEvent();
Daniel Veilleux 0:442c7a6f1978 199 }
Daniel Veilleux 0:442c7a6f1978 200 }