BLE project for PILLAR
Dependencies: BLE_API mbed simpleBLEControl
Fork of BLE_API_DEMO by
main.cpp@53:f503e75f0c94, 2014-11-28 (annotated)
- Committer:
- antoniorohit
- Date:
- Fri Nov 28 05:27:43 2014 +0000
- Revision:
- 53:f503e75f0c94
- Parent:
- 52:8e483d1199f9
- Child:
- 54:52be0aeba318
Better comments;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
antoniorohit | 51:0bf1116bca52 | 1 | // This code is for the nRF51822 that is used to provide a BLE interface to PILLar |
antoniorohit | 51:0bf1116bca52 | 2 | // There is 1 service and 1 characteristic |
antoniorohit | 51:0bf1116bca52 | 3 | // The service provides a way to write a step value from the phone to a stepper motor |
antoniorohit | 51:0bf1116bca52 | 4 | // controlled by an Arduino |
ktownsend | 0:87a7fc231fae | 5 | #include "mbed.h" |
Rohit Grover |
10:2436164b692e | 6 | #include "BLEDevice.h" |
antoniorohit | 53:f503e75f0c94 | 7 | #define RFID_BUFF_SIZE 8 // Enough to hold 7-byte UID + delimiter |
ktownsend | 0:87a7fc231fae | 8 | |
antoniorohit | 52:8e483d1199f9 | 9 | DigitalOut led1(LED1); // LED toggled on connect and write events |
antoniorohit | 52:8e483d1199f9 | 10 | DigitalOut led2(LED2); // Toggled on button press |
antoniorohit | 51:0bf1116bca52 | 11 | BLEDevice ble; // Declare the ble device |
antoniorohit | 51:0bf1116bca52 | 12 | Serial arduino(USBTX, USBRX); // serial interface to PC or Arduino controlling the stepper |
ktownsend | 0:87a7fc231fae | 13 | |
antoniorohit | 51:0bf1116bca52 | 14 | // Arbit 128-bit UIDs generated from |
antoniorohit | 51:0bf1116bca52 | 15 | // http://www.guidgenerator.com/online-guid-generator.aspx |
antoniorohit | 51:0bf1116bca52 | 16 | // We need one for each service and characteristic |
antoniorohit | 51:0bf1116bca52 | 17 | const uint8_t ARDUINO_WRITE_CHARACTERISTIC_UUID[LENGTH_OF_LONG_UUID] = { |
nebgnahz | 50:4c02add9abba | 18 | 0xfb, 0x71, 0xbc, 0xc0, 0x5a, 0x0c, 0x11, 0xe4, |
nebgnahz | 50:4c02add9abba | 19 | 0x91, 0xae, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b |
nebgnahz | 50:4c02add9abba | 20 | }; |
antoniorohit | 51:0bf1116bca52 | 21 | |
antoniorohit | 52:8e483d1199f9 | 22 | const uint8_t RFID_UUID[LENGTH_OF_LONG_UUID] = { |
antoniorohit | 52:8e483d1199f9 | 23 | 0x7a, 0x77, 0xbe, 0x20, 0x5a, 0x0d, 0x11, 0xe4, |
antoniorohit | 52:8e483d1199f9 | 24 | 0xa9, 0x5e, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b |
antoniorohit | 52:8e483d1199f9 | 25 | }; |
antoniorohit | 52:8e483d1199f9 | 26 | |
nebgnahz | 50:4c02add9abba | 27 | const uint8_t TEST_SERVICE_UUID[LENGTH_OF_LONG_UUID] = { |
nebgnahz | 50:4c02add9abba | 28 | 0xb0, 0xbb, 0x58, 0x20, 0x5a, 0x0d, 0x11, 0xe4, |
antoniorohit | 51:0bf1116bca52 | 29 | 0x93, 0xee, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}; |
nebgnahz | 50:4c02add9abba | 30 | |
antoniorohit | 51:0bf1116bca52 | 31 | const static char DEVICE_NAME[] = "mediCAL BLE"; // For Advertisement |
antoniorohit | 51:0bf1116bca52 | 32 | static volatile uint16_t writeToArduino_handler; // handler to echo data |
antoniorohit | 52:8e483d1199f9 | 33 | static volatile bool is_button_pressed = false; |
antoniorohit | 52:8e483d1199f9 | 34 | static volatile bool uid_read = false; |
antoniorohit | 52:8e483d1199f9 | 35 | |
antoniorohit | 52:8e483d1199f9 | 36 | |
antoniorohit | 52:8e483d1199f9 | 37 | // What happens on connect event - DEBUG purposes ONLY!! |
antoniorohit | 52:8e483d1199f9 | 38 | void onConnection(Gap::Handle_t handle, const Gap::ConnectionParams_t * param_ptr){ |
antoniorohit | 52:8e483d1199f9 | 39 | arduino.printf("Connection Event!\n\r"); |
antoniorohit | 52:8e483d1199f9 | 40 | ble.stopAdvertising(); // stop advertising |
antoniorohit | 52:8e483d1199f9 | 41 | led1 = !led1.read(); |
antoniorohit | 52:8e483d1199f9 | 42 | } |
nebgnahz | 48:908b4ec086ba | 43 | |
antoniorohit | 51:0bf1116bca52 | 44 | // What happens on disconnect event |
antoniorohit | 51:0bf1116bca52 | 45 | void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason){ |
antoniorohit | 52:8e483d1199f9 | 46 | arduino.printf("Disconnection Event!\n\r"); |
rgrover1 | 46:ee7c55907f36 | 47 | ble.startAdvertising(); // restart advertising |
rgrover1 | 7:daab8ba5139e | 48 | } |
Rohit Grover |
3:24e2b056d229 | 49 | |
antoniorohit | 51:0bf1116bca52 | 50 | // This function is called whenever data is written to the BLE device through the phone |
antoniorohit | 51:0bf1116bca52 | 51 | void onDatawritten(const GattCharacteristicWriteCBParams *eventDataP) { |
nebgnahz | 49:14b2df099dfc | 52 | // eventDataP->charHandle is just uint16_t |
nebgnahz | 49:14b2df099dfc | 53 | // it's used to dispatch the callbacks |
antoniorohit | 51:0bf1116bca52 | 54 | if(eventDataP->charHandle==writeToArduino_handler){ // The data is for the motor |
antoniorohit | 51:0bf1116bca52 | 55 | uint16_t bytesRead = eventDataP->len; |
antoniorohit | 51:0bf1116bca52 | 56 | int turnSteps = *((int16_t *)eventDataP->data); |
antoniorohit | 53:f503e75f0c94 | 57 | if(is_button_pressed){ // Hack-way to turn both motors |
antoniorohit | 53:f503e75f0c94 | 58 | arduino.printf("%im\n", turnSteps); // <turn steps>m turns small motor |
antoniorohit | 52:8e483d1199f9 | 59 | } |
antoniorohit | 52:8e483d1199f9 | 60 | else{ |
antoniorohit | 53:f503e75f0c94 | 61 | arduino.printf("%iM\n", turnSteps); // <turn steps>M turns large motor |
antoniorohit | 52:8e483d1199f9 | 62 | } |
antoniorohit | 53:f503e75f0c94 | 63 | led1 = !led1.read(); // debug purposes |
nebgnahz | 48:908b4ec086ba | 64 | } |
nebgnahz | 48:908b4ec086ba | 65 | } |
antoniorohit | 53:f503e75f0c94 | 66 | char read_ch; // temp var to store data from arduino |
antoniorohit | 52:8e483d1199f9 | 67 | uint8_t buff[RFID_BUFF_SIZE] = {0}; // max packet size for GATT is 20 bytes |
antoniorohit | 52:8e483d1199f9 | 68 | uint8_t ct = 0; |
antoniorohit | 52:8e483d1199f9 | 69 | |
antoniorohit | 52:8e483d1199f9 | 70 | void callback() { |
antoniorohit | 52:8e483d1199f9 | 71 | // Note: you need to actually read from the serial to clear the RX interrupt |
antoniorohit | 52:8e483d1199f9 | 72 | read_ch = arduino.getc(); |
antoniorohit | 53:f503e75f0c94 | 73 | buff[ct++] = int(read_ch); |
antoniorohit | 53:f503e75f0c94 | 74 | |
antoniorohit | 53:f503e75f0c94 | 75 | if((ct > RFID_BUFF_SIZE-1)){ // Arduino sends 8-bytes [UID][;][0 padding] |
antoniorohit | 52:8e483d1199f9 | 76 | uid_read = true; |
antoniorohit | 52:8e483d1199f9 | 77 | } |
antoniorohit | 53:f503e75f0c94 | 78 | led2 = !led2.read(); // debug purposes |
antoniorohit | 52:8e483d1199f9 | 79 | } |
antoniorohit | 52:8e483d1199f9 | 80 | |
antoniorohit | 52:8e483d1199f9 | 81 | // Button1 pressed routine - toggle is_button pressed |
antoniorohit | 52:8e483d1199f9 | 82 | void button1Pressed() { |
antoniorohit | 52:8e483d1199f9 | 83 | is_button_pressed = !is_button_pressed; |
antoniorohit | 53:f503e75f0c94 | 84 | led2 = !led2.read(); // debug |
antoniorohit | 52:8e483d1199f9 | 85 | } |
antoniorohit | 52:8e483d1199f9 | 86 | |
antoniorohit | 52:8e483d1199f9 | 87 | // Button2 pressed routine |
antoniorohit | 52:8e483d1199f9 | 88 | void button2Pressed() { |
antoniorohit | 53:f503e75f0c94 | 89 | led2 = !led2.read(); // debug |
antoniorohit | 52:8e483d1199f9 | 90 | } |
rgrover1 | 47:430545f41113 | 91 | |
ktownsend | 0:87a7fc231fae | 92 | int main(void) |
ktownsend | 0:87a7fc231fae | 93 | { |
antoniorohit | 52:8e483d1199f9 | 94 | arduino.baud(115200); |
antoniorohit | 51:0bf1116bca52 | 95 | arduino.printf("Entered main\n\r"); |
ktownsend | 0:87a7fc231fae | 96 | |
antoniorohit | 52:8e483d1199f9 | 97 | // RFID Interrupt initialization |
antoniorohit | 52:8e483d1199f9 | 98 | // button initialization |
antoniorohit | 52:8e483d1199f9 | 99 | InterruptIn button1(BUTTON1); |
antoniorohit | 52:8e483d1199f9 | 100 | button1.mode(PullUp); |
antoniorohit | 52:8e483d1199f9 | 101 | button1.rise(&button1Pressed); |
antoniorohit | 52:8e483d1199f9 | 102 | |
antoniorohit | 52:8e483d1199f9 | 103 | InterruptIn button2(BUTTON2); |
antoniorohit | 52:8e483d1199f9 | 104 | button2.mode(PullUp); |
antoniorohit | 52:8e483d1199f9 | 105 | button2.rise(&button2Pressed); |
antoniorohit | 52:8e483d1199f9 | 106 | |
antoniorohit | 53:f503e75f0c94 | 107 | arduino.attach(&callback); // callback is triggered when there is incoming serial data |
antoniorohit | 53:f503e75f0c94 | 108 | |
antoniorohit | 51:0bf1116bca52 | 109 | // You can write from the phone to control what is written to Arduino |
antoniorohit | 51:0bf1116bca52 | 110 | GattCharacteristic writeToArduino_characteristics( |
antoniorohit | 51:0bf1116bca52 | 111 | ARDUINO_WRITE_CHARACTERISTIC_UUID, NULL, sizeof(int16_t), sizeof(int16_t), |
antoniorohit | 52:8e483d1199f9 | 112 | GattCharacteristic::BLE_GATT_FORMAT_SINT16 | // 16-bit signed int |
antoniorohit | 51:0bf1116bca52 | 113 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | // has read |
antoniorohit | 51:0bf1116bca52 | 114 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); // and write properties |
antoniorohit | 51:0bf1116bca52 | 115 | writeToArduino_handler = writeToArduino_characteristics.getValueAttribute().getHandle();// save the handler |
rgrover1 | 45:98c5a34b07a4 | 116 | |
antoniorohit | 52:8e483d1199f9 | 117 | GattCharacteristic RFID_characteristics( |
antoniorohit | 52:8e483d1199f9 | 118 | RFID_UUID, NULL, RFID_BUFF_SIZE*sizeof(uint8_t), RFID_BUFF_SIZE*sizeof(uint8_t), |
antoniorohit | 52:8e483d1199f9 | 119 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | |
antoniorohit | 52:8e483d1199f9 | 120 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
antoniorohit | 52:8e483d1199f9 | 121 | |
antoniorohit | 52:8e483d1199f9 | 122 | |
antoniorohit | 52:8e483d1199f9 | 123 | GattCharacteristic *charTable[] = {&writeToArduino_characteristics, |
antoniorohit | 52:8e483d1199f9 | 124 | &RFID_characteristics}; // Characteristic table |
antoniorohit | 51:0bf1116bca52 | 125 | GattService testService(TEST_SERVICE_UUID, charTable, // Add the char(s) to this service |
nebgnahz | 49:14b2df099dfc | 126 | sizeof(charTable) / sizeof(GattCharacteristic *)); |
nebgnahz | 50:4c02add9abba | 127 | |
nebgnahz | 48:908b4ec086ba | 128 | // BLE setup, mainly we add service and callbacks |
nebgnahz | 48:908b4ec086ba | 129 | ble.init(); |
nebgnahz | 48:908b4ec086ba | 130 | ble.addService(testService); |
antoniorohit | 52:8e483d1199f9 | 131 | ble.onDataWritten(onDatawritten); |
antoniorohit | 52:8e483d1199f9 | 132 | ble.onConnection(onConnection); |
nebgnahz | 48:908b4ec086ba | 133 | ble.onDisconnection(disconnectionCallback); |
nebgnahz | 48:908b4ec086ba | 134 | |
nebgnahz | 48:908b4ec086ba | 135 | // setup advertising |
nebgnahz | 49:14b2df099dfc | 136 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | |
nebgnahz | 50:4c02add9abba | 137 | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
nebgnahz | 49:14b2df099dfc | 138 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, |
nebgnahz | 49:14b2df099dfc | 139 | (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
rgrover1 | 7:daab8ba5139e | 140 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
antoniorohit | 52:8e483d1199f9 | 141 | ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ |
rgrover1 | 7:daab8ba5139e | 142 | ble.startAdvertising(); |
Rohit Grover |
3:24e2b056d229 | 143 | |
Rohit Grover |
11:1d9aafee4984 | 144 | while (true) { |
antoniorohit | 52:8e483d1199f9 | 145 | if (uid_read) { |
antoniorohit | 52:8e483d1199f9 | 146 | ble.updateCharacteristicValue(RFID_characteristics.getValueAttribute().getHandle(), |
antoniorohit | 52:8e483d1199f9 | 147 | buff, RFID_BUFF_SIZE*sizeof(uint8_t)); |
antoniorohit | 52:8e483d1199f9 | 148 | uid_read = false; |
antoniorohit | 52:8e483d1199f9 | 149 | ct = 0; |
antoniorohit | 52:8e483d1199f9 | 150 | } |
antoniorohit | 52:8e483d1199f9 | 151 | else { |
antoniorohit | 52:8e483d1199f9 | 152 | ble.waitForEvent(); |
antoniorohit | 52:8e483d1199f9 | 153 | } |
ktownsend | 0:87a7fc231fae | 154 | } |
nebgnahz | 50:4c02add9abba | 155 | } |