RedBearLab BLE Nano chat, modified to produce 5 digital outputs

Dependencies:   BLE_API mbed nRF51822

Committer:
gogodi91
Date:
Fri Mar 27 17:15:49 2015 +0000
Revision:
0:14ab14e85dc2
Final Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gogodi91 0:14ab14e85dc2 1 /*
gogodi91 0:14ab14e85dc2 2
gogodi91 0:14ab14e85dc2 3 Copyright (c) 2012-2014 RedBearLab
gogodi91 0:14ab14e85dc2 4
gogodi91 0:14ab14e85dc2 5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
gogodi91 0:14ab14e85dc2 6 and associated documentation files (the "Software"), to deal in the Software without restriction,
gogodi91 0:14ab14e85dc2 7 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
gogodi91 0:14ab14e85dc2 8 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
gogodi91 0:14ab14e85dc2 9 subject to the following conditions:
gogodi91 0:14ab14e85dc2 10 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
gogodi91 0:14ab14e85dc2 11
gogodi91 0:14ab14e85dc2 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
gogodi91 0:14ab14e85dc2 13 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
gogodi91 0:14ab14e85dc2 14 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
gogodi91 0:14ab14e85dc2 15 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
gogodi91 0:14ab14e85dc2 16 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
gogodi91 0:14ab14e85dc2 17
gogodi91 0:14ab14e85dc2 18 */
gogodi91 0:14ab14e85dc2 19
gogodi91 0:14ab14e85dc2 20 #include "mbed.h"
gogodi91 0:14ab14e85dc2 21 #include "BLEDevice.h"
gogodi91 0:14ab14e85dc2 22
gogodi91 0:14ab14e85dc2 23 #define BLE_UUID_TXRX_SERVICE 0x0000 /**< The UUID of the Nordic UART Service. */
gogodi91 0:14ab14e85dc2 24 #define BLE_UUID_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */
gogodi91 0:14ab14e85dc2 25 #define BLE_UUIDS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */
gogodi91 0:14ab14e85dc2 26
gogodi91 0:14ab14e85dc2 27 #define TXRX_BUF_LEN 20
gogodi91 0:14ab14e85dc2 28
gogodi91 0:14ab14e85dc2 29 BLEDevice ble;
gogodi91 0:14ab14e85dc2 30 DigitalOut myled1(LED1);
gogodi91 0:14ab14e85dc2 31 DigitalOut light1(P0_15); //green
gogodi91 0:14ab14e85dc2 32 DigitalOut light2(P0_6); //yellow
gogodi91 0:14ab14e85dc2 33 DigitalOut light3(P0_7); //red
gogodi91 0:14ab14e85dc2 34 DigitalOut vib(P0_4); //vibration
gogodi91 0:14ab14e85dc2 35 DigitalOut sound(P0_5); //sound
gogodi91 0:14ab14e85dc2 36
gogodi91 0:14ab14e85dc2 37 Serial pc(USBTX, USBRX);
gogodi91 0:14ab14e85dc2 38
gogodi91 0:14ab14e85dc2 39 // The Nordic UART Service
gogodi91 0:14ab14e85dc2 40 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
gogodi91 0:14ab14e85dc2 41 static const uint8_t uart_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
gogodi91 0:14ab14e85dc2 42 static const uint8_t uart_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
gogodi91 0:14ab14e85dc2 43 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
gogodi91 0:14ab14e85dc2 44
gogodi91 0:14ab14e85dc2 45
gogodi91 0:14ab14e85dc2 46 uint8_t txPayload[TXRX_BUF_LEN] = {0,};
gogodi91 0:14ab14e85dc2 47 uint8_t rxPayload[TXRX_BUF_LEN] = {0,};
gogodi91 0:14ab14e85dc2 48
gogodi91 0:14ab14e85dc2 49 static uint8_t rx_buf[TXRX_BUF_LEN];
gogodi91 0:14ab14e85dc2 50 static uint8_t rx_len=0;
gogodi91 0:14ab14e85dc2 51
gogodi91 0:14ab14e85dc2 52
gogodi91 0:14ab14e85dc2 53 GattCharacteristic txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
gogodi91 0:14ab14e85dc2 54
gogodi91 0:14ab14e85dc2 55 GattCharacteristic rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
gogodi91 0:14ab14e85dc2 56
gogodi91 0:14ab14e85dc2 57 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
gogodi91 0:14ab14e85dc2 58
gogodi91 0:14ab14e85dc2 59 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
gogodi91 0:14ab14e85dc2 60
gogodi91 0:14ab14e85dc2 61
gogodi91 0:14ab14e85dc2 62
gogodi91 0:14ab14e85dc2 63 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
gogodi91 0:14ab14e85dc2 64 {
gogodi91 0:14ab14e85dc2 65 pc.printf("Disconnected \r\n");
gogodi91 0:14ab14e85dc2 66 pc.printf("Restart advertising \r\n");
gogodi91 0:14ab14e85dc2 67 ble.startAdvertising();
gogodi91 0:14ab14e85dc2 68 }
gogodi91 0:14ab14e85dc2 69
gogodi91 0:14ab14e85dc2 70 void vibrate(){//Function used when audio and tactile output is required
gogodi91 0:14ab14e85dc2 71 pc.printf("\nVIBRATE\n");
gogodi91 0:14ab14e85dc2 72 sound = 0;
gogodi91 0:14ab14e85dc2 73 light1 = 1;
gogodi91 0:14ab14e85dc2 74 light2 = 1;
gogodi91 0:14ab14e85dc2 75 light3 = 1;
gogodi91 0:14ab14e85dc2 76 for (int i=0;i<250;i++){
gogodi91 0:14ab14e85dc2 77 sound = !sound;//sound requires high frequency
gogodi91 0:14ab14e85dc2 78 if ((i+1)/20 == 0)//vibrate at 250Hz for best result
gogodi91 0:14ab14e85dc2 79 vib = !vib;
gogodi91 0:14ab14e85dc2 80 if ((i+1)/50 == 0){//reduce blinking frequency so flicker is visible
gogodi91 0:14ab14e85dc2 81 light1 = !light1;
gogodi91 0:14ab14e85dc2 82 light2 = !light2;
gogodi91 0:14ab14e85dc2 83 light3 = !light3;
gogodi91 0:14ab14e85dc2 84 }
gogodi91 0:14ab14e85dc2 85 wait(0.0002);
gogodi91 0:14ab14e85dc2 86 }
gogodi91 0:14ab14e85dc2 87 //turn everything off just in case
gogodi91 0:14ab14e85dc2 88 vib = 0;
gogodi91 0:14ab14e85dc2 89 sound = 0;
gogodi91 0:14ab14e85dc2 90 light1 = 0;
gogodi91 0:14ab14e85dc2 91 light2 = 0;
gogodi91 0:14ab14e85dc2 92 light3 = 0;
gogodi91 0:14ab14e85dc2 93 }
gogodi91 0:14ab14e85dc2 94
gogodi91 0:14ab14e85dc2 95
gogodi91 0:14ab14e85dc2 96 void WrittenHandler(const GattCharacteristicWriteCBParams *Handler)
gogodi91 0:14ab14e85dc2 97 {
gogodi91 0:14ab14e85dc2 98 uint8_t buf[TXRX_BUF_LEN];
gogodi91 0:14ab14e85dc2 99 uint16_t bytesRead, index;
gogodi91 0:14ab14e85dc2 100
gogodi91 0:14ab14e85dc2 101 if (Handler->charHandle == txCharacteristic.getValueAttribute().getHandle())
gogodi91 0:14ab14e85dc2 102 {
gogodi91 0:14ab14e85dc2 103 ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead);
gogodi91 0:14ab14e85dc2 104 memset(txPayload, 0, TXRX_BUF_LEN);
gogodi91 0:14ab14e85dc2 105 memcpy(txPayload, buf, TXRX_BUF_LEN);
gogodi91 0:14ab14e85dc2 106 pc.printf("WriteHandler \r\n");
gogodi91 0:14ab14e85dc2 107 pc.printf("Length: ");
gogodi91 0:14ab14e85dc2 108 pc.putc(bytesRead);
gogodi91 0:14ab14e85dc2 109 pc.printf("\r\n");
gogodi91 0:14ab14e85dc2 110 pc.printf("Data: ");
gogodi91 0:14ab14e85dc2 111 for(index=0; index<bytesRead; index++)
gogodi91 0:14ab14e85dc2 112 {
gogodi91 0:14ab14e85dc2 113 if (txPayload[0] == 'a'){//get the first letter of the message and see if it is "a"
gogodi91 0:14ab14e85dc2 114 light1 = 1;
gogodi91 0:14ab14e85dc2 115 light2 = 0;
gogodi91 0:14ab14e85dc2 116 light3 = 0;
gogodi91 0:14ab14e85dc2 117 pc.printf("\nGREEN\n");
gogodi91 0:14ab14e85dc2 118 }
gogodi91 0:14ab14e85dc2 119 else if (txPayload[0] == 'b'){
gogodi91 0:14ab14e85dc2 120 light1 = 0;
gogodi91 0:14ab14e85dc2 121 light2 = 1;
gogodi91 0:14ab14e85dc2 122 light3 = 0;
gogodi91 0:14ab14e85dc2 123 pc.printf("\nYELLOW\n");
gogodi91 0:14ab14e85dc2 124 }
gogodi91 0:14ab14e85dc2 125 else if (txPayload[0] == 'c'){
gogodi91 0:14ab14e85dc2 126 light1 = 0;
gogodi91 0:14ab14e85dc2 127 light2 = 0;
gogodi91 0:14ab14e85dc2 128 light3 = 1;
gogodi91 0:14ab14e85dc2 129 pc.printf("\nRED\n");
gogodi91 0:14ab14e85dc2 130 }
gogodi91 0:14ab14e85dc2 131 else if (txPayload[0] == 'd'){
gogodi91 0:14ab14e85dc2 132 vibrate();
gogodi91 0:14ab14e85dc2 133 }
gogodi91 0:14ab14e85dc2 134 else {//turn everything off
gogodi91 0:14ab14e85dc2 135 light1 = 0;
gogodi91 0:14ab14e85dc2 136 light2 = 0;
gogodi91 0:14ab14e85dc2 137 light3 = 0;
gogodi91 0:14ab14e85dc2 138 vib = 0;
gogodi91 0:14ab14e85dc2 139 sound = 0;
gogodi91 0:14ab14e85dc2 140 }
gogodi91 0:14ab14e85dc2 141 pc.putc(txPayload[index]);
gogodi91 0:14ab14e85dc2 142 }
gogodi91 0:14ab14e85dc2 143 pc.printf("\r\n");
gogodi91 0:14ab14e85dc2 144 }
gogodi91 0:14ab14e85dc2 145 }
gogodi91 0:14ab14e85dc2 146
gogodi91 0:14ab14e85dc2 147 void uartCB(void)
gogodi91 0:14ab14e85dc2 148 {
gogodi91 0:14ab14e85dc2 149 while(pc.readable())
gogodi91 0:14ab14e85dc2 150 {
gogodi91 0:14ab14e85dc2 151 rx_buf[rx_len++] = pc.getc();
gogodi91 0:14ab14e85dc2 152 if(rx_len>=20 || rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\n')
gogodi91 0:14ab14e85dc2 153 {
gogodi91 0:14ab14e85dc2 154 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), rx_buf, rx_len);
gogodi91 0:14ab14e85dc2 155 pc.printf("RecHandler \r\n");
gogodi91 0:14ab14e85dc2 156 pc.printf("Length: ");
gogodi91 0:14ab14e85dc2 157 pc.putc(rx_len);
gogodi91 0:14ab14e85dc2 158 pc.printf("\r\n");
gogodi91 0:14ab14e85dc2 159 rx_len = 0;
gogodi91 0:14ab14e85dc2 160 break;
gogodi91 0:14ab14e85dc2 161 }
gogodi91 0:14ab14e85dc2 162 }
gogodi91 0:14ab14e85dc2 163 }
gogodi91 0:14ab14e85dc2 164
gogodi91 0:14ab14e85dc2 165 int main(void)
gogodi91 0:14ab14e85dc2 166 {
gogodi91 0:14ab14e85dc2 167 ble.init();
gogodi91 0:14ab14e85dc2 168
gogodi91 0:14ab14e85dc2 169 ble.onDisconnection(disconnectionCallback);
gogodi91 0:14ab14e85dc2 170 ble.onDataWritten(WrittenHandler);
gogodi91 0:14ab14e85dc2 171
gogodi91 0:14ab14e85dc2 172 pc.baud(9600);
gogodi91 0:14ab14e85dc2 173 pc.printf("SimpleChat Init \r\n");
gogodi91 0:14ab14e85dc2 174
gogodi91 0:14ab14e85dc2 175 pc.attach( uartCB , pc.RxIrq);
gogodi91 0:14ab14e85dc2 176 // setup advertising
gogodi91 0:14ab14e85dc2 177 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
gogodi91 0:14ab14e85dc2 178 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
gogodi91 0:14ab14e85dc2 179 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
gogodi91 0:14ab14e85dc2 180 (const uint8_t *)"Biscuit", sizeof("Biscuit") - 1);
gogodi91 0:14ab14e85dc2 181 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
gogodi91 0:14ab14e85dc2 182 (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
gogodi91 0:14ab14e85dc2 183 // 100ms; in multiples of 0.625ms.
gogodi91 0:14ab14e85dc2 184 ble.setAdvertisingInterval(160);
gogodi91 0:14ab14e85dc2 185
gogodi91 0:14ab14e85dc2 186 ble.addService(uartService);
gogodi91 0:14ab14e85dc2 187
gogodi91 0:14ab14e85dc2 188 ble.startAdvertising();
gogodi91 0:14ab14e85dc2 189 pc.printf("Advertising Start \r\n");
gogodi91 0:14ab14e85dc2 190 //myled1 = 1;
gogodi91 0:14ab14e85dc2 191 while(1)
gogodi91 0:14ab14e85dc2 192 {
gogodi91 0:14ab14e85dc2 193 ble.waitForEvent();
gogodi91 0:14ab14e85dc2 194 }
gogodi91 0:14ab14e85dc2 195 }