Simple program to enable me to write to a 128x64 OLED display over BLE

Dependencies:   Adafruit_GFX BLE_API mbed nRF51822 SemVer

Committer:
rosterloh84
Date:
Mon Mar 30 13:23:29 2015 +0000
Revision:
1:9e9c52d8270a
Parent:
0:d89c10040630
added version support and device info

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rosterloh84 0:d89c10040630 1 /**
rosterloh84 0:d89c10040630 2 * @file
rosterloh84 0:d89c10040630 3 * @date 30 March 2015
rosterloh84 0:d89c10040630 4 * @author Richard Osterloh <richard.osterloh@gmail.com>
rosterloh84 0:d89c10040630 5 */
rosterloh84 0:d89c10040630 6
rosterloh84 0:d89c10040630 7 #include "mbed.h"
rosterloh84 0:d89c10040630 8 #include "BLEDevice.h"
rosterloh84 1:9e9c52d8270a 9 #include "DeviceInformationService.h"
rosterloh84 0:d89c10040630 10 #include "UARTService.h"
rosterloh84 0:d89c10040630 11
rosterloh84 0:d89c10040630 12 #include "Adafruit_SSD1306.h"
rosterloh84 1:9e9c52d8270a 13 #include "SemVer.h"
rosterloh84 0:d89c10040630 14
rosterloh84 0:d89c10040630 15 #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console;
rosterloh84 0:d89c10040630 16 * it will have an impact on code-size and power consumption. */
rosterloh84 0:d89c10040630 17
rosterloh84 0:d89c10040630 18 #if NEED_CONSOLE_OUTPUT
rosterloh84 1:9e9c52d8270a 19 #define DEBUG(...) { if (uartServicePtr) uartServicePtr->writeString(__VA_ARGS__); }
rosterloh84 0:d89c10040630 20 #else
rosterloh84 0:d89c10040630 21 #define DEBUG(...) /* nothing */
rosterloh84 0:d89c10040630 22 #endif /* #if NEED_CONSOLE_OUTPUT */
rosterloh84 0:d89c10040630 23
rosterloh84 1:9e9c52d8270a 24 SemVer version("1.0.0");
rosterloh84 1:9e9c52d8270a 25
rosterloh84 0:d89c10040630 26 BLEDevice ble;
rosterloh84 0:d89c10040630 27 DigitalOut led1(LED1);
rosterloh84 0:d89c10040630 28 DigitalOut led2(LED2);
rosterloh84 0:d89c10040630 29 DigitalOut led3(LED3);
rosterloh84 0:d89c10040630 30 DigitalOut led4(LED4);
rosterloh84 0:d89c10040630 31
rosterloh84 0:d89c10040630 32 InterruptIn btn1(BUTTON1);
rosterloh84 0:d89c10040630 33
rosterloh84 0:d89c10040630 34 DigitalOut oled_gnd(p3);
rosterloh84 0:d89c10040630 35
rosterloh84 0:d89c10040630 36 // an I2C sub-class that provides a constructed default
rosterloh84 0:d89c10040630 37 class I2CPreInit : public I2C
rosterloh84 0:d89c10040630 38 {
rosterloh84 0:d89c10040630 39 public:
rosterloh84 0:d89c10040630 40 I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
rosterloh84 0:d89c10040630 41 {
rosterloh84 0:d89c10040630 42 oled_gnd = 0;
rosterloh84 0:d89c10040630 43 frequency(400000);
rosterloh84 0:d89c10040630 44 start();
rosterloh84 0:d89c10040630 45 };
rosterloh84 0:d89c10040630 46 };
rosterloh84 0:d89c10040630 47
rosterloh84 0:d89c10040630 48 I2CPreInit gI2C(p5, p4); // SDA, SCL
rosterloh84 0:d89c10040630 49 Adafruit_SSD1306_I2c gOled(gI2C, p2, 0x78, 64, 128); // I2C, RST, ADDRESS, WIDTH, HEIGHT
rosterloh84 0:d89c10040630 50
rosterloh84 0:d89c10040630 51 bool rxPayloadUpdated = false;
rosterloh84 0:d89c10040630 52 const static unsigned MAX_SIZEOF_RX_PAYLOAD = 20;
rosterloh84 0:d89c10040630 53 char rxPayload[MAX_SIZEOF_RX_PAYLOAD] = {0,};
rosterloh84 0:d89c10040630 54
rosterloh84 0:d89c10040630 55 UARTService *uartServicePtr;
rosterloh84 0:d89c10040630 56
rosterloh84 1:9e9c52d8270a 57 const static char DEVICE_NAME[] = "BLE DISPLAY";
rosterloh84 1:9e9c52d8270a 58 static const uint16_t uuid16_list[] = {GattService::UUID_DEVICE_INFORMATION_SERVICE};
rosterloh84 1:9e9c52d8270a 59
rosterloh84 0:d89c10040630 60 /**
rosterloh84 0:d89c10040630 61 * Callback to write to connected client and display
rosterloh84 0:d89c10040630 62 */
rosterloh84 0:d89c10040630 63 void buttonCallback(void)
rosterloh84 0:d89c10040630 64 {
rosterloh84 0:d89c10040630 65 if(btn1) {
rosterloh84 0:d89c10040630 66 gOled.clearDisplay();
rosterloh84 0:d89c10040630 67 gOled.printf("%s", "BTN 0 released");
rosterloh84 0:d89c10040630 68 gOled.display();
rosterloh84 0:d89c10040630 69 uartServicePtr->writeString("Button 0 released\r\n");
rosterloh84 0:d89c10040630 70 } else {
rosterloh84 0:d89c10040630 71 gOled.clearDisplay();
rosterloh84 0:d89c10040630 72 gOled.printf("%s", "BTN 0 pressed");
rosterloh84 0:d89c10040630 73 gOled.display();
rosterloh84 0:d89c10040630 74 uartServicePtr->writeString("Button 0 pressed\r\n");
rosterloh84 0:d89c10040630 75 }
rosterloh84 0:d89c10040630 76 }
rosterloh84 0:d89c10040630 77
rosterloh84 0:d89c10040630 78 /**
rosterloh84 0:d89c10040630 79 * Callback when new client connects to device
rosterloh84 0:d89c10040630 80 *
rosterloh84 0:d89c10040630 81 * @param tHandle handle to this specific client
rosterloh84 0:d89c10040630 82 * @param ePeerAddrType the type of the connected clients address
rosterloh84 0:d89c10040630 83 * @param c6PeerAddr the address of the connected client
rosterloh84 0:d89c10040630 84 * @param params requested connection parameters
rosterloh84 0:d89c10040630 85 */
rosterloh84 0:d89c10040630 86 void connectionCallback(Gap::Handle_t tHandle, Gap::addr_type_t ePeerAddrType, const Gap::address_t c6PeerAddr, const Gap::ConnectionParams_t *params)
rosterloh84 0:d89c10040630 87 {
rosterloh84 0:d89c10040630 88 //DEBUG("CONNECT: Handle:%u, eType:%d, Add:%u\r\n", tHandle, ePeerAddrType, c6PeerAddr);
rosterloh84 0:d89c10040630 89 //DEBUG(" minInterval:%d, maxInterval:%d, latency:%d, timeout:%d\r\n",
rosterloh84 0:d89c10040630 90 // params->minConnectionInterval, params->maxConnectionInterval, params->slaveLatency, params->connectionSupervisionTimeout);
rosterloh84 0:d89c10040630 91 DEBUG("CONNECTED\r\n");
rosterloh84 0:d89c10040630 92 led2 = 1; led4 = 0;
rosterloh84 0:d89c10040630 93 }
rosterloh84 0:d89c10040630 94
rosterloh84 0:d89c10040630 95 /**
rosterloh84 0:d89c10040630 96 * Callback called when a client disconnects
rosterloh84 0:d89c10040630 97 *
rosterloh84 0:d89c10040630 98 * @param tHandle handle of the disconnected client
rosterloh84 0:d89c10040630 99 * @param eReason the reason they disconnected
rosterloh84 0:d89c10040630 100 */
rosterloh84 0:d89c10040630 101 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
rosterloh84 0:d89c10040630 102 {
rosterloh84 0:d89c10040630 103 DEBUG("Disconnected!\n\r");
rosterloh84 0:d89c10040630 104 DEBUG("Restarting the advertising process\n\r");
rosterloh84 0:d89c10040630 105 ble.startAdvertising();
rosterloh84 0:d89c10040630 106 led2 = 0; led4 = 1;
rosterloh84 0:d89c10040630 107 }
rosterloh84 0:d89c10040630 108
rosterloh84 0:d89c10040630 109 /**
rosterloh84 0:d89c10040630 110 * Callback called when a client writes to this device
rosterloh84 0:d89c10040630 111 *
rosterloh84 0:d89c10040630 112 * @param params all parameters related to this data
rosterloh84 0:d89c10040630 113 */
rosterloh84 0:d89c10040630 114 void onDataWritten(const GattCharacteristicWriteCBParams *params)
rosterloh84 0:d89c10040630 115 {
rosterloh84 0:d89c10040630 116 if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
rosterloh84 0:d89c10040630 117 uint16_t bytesRead = params->len;
rosterloh84 0:d89c10040630 118 if (bytesRead < MAX_SIZEOF_RX_PAYLOAD) {
rosterloh84 0:d89c10040630 119 strncpy(rxPayload, (const char *)params->data, MAX_SIZEOF_RX_PAYLOAD - 1);
rosterloh84 0:d89c10040630 120 rxPayload[bytesRead] = '\0';
rosterloh84 0:d89c10040630 121 rxPayloadUpdated = true;
rosterloh84 0:d89c10040630 122 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
rosterloh84 0:d89c10040630 123 }
rosterloh84 0:d89c10040630 124 }
rosterloh84 0:d89c10040630 125 }
rosterloh84 0:d89c10040630 126
rosterloh84 0:d89c10040630 127 void periodicCallback(void)
rosterloh84 0:d89c10040630 128 {
rosterloh84 0:d89c10040630 129 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
rosterloh84 0:d89c10040630 130 }
rosterloh84 0:d89c10040630 131
rosterloh84 0:d89c10040630 132 int main(void)
rosterloh84 0:d89c10040630 133 {
rosterloh84 0:d89c10040630 134 led1 = 1; led2 = 1; led3 = 1; led4 = 1;
rosterloh84 0:d89c10040630 135 Ticker ticker;
rosterloh84 0:d89c10040630 136 ticker.attach(periodicCallback, 1);
rosterloh84 0:d89c10040630 137 btn1.fall(buttonCallback);
rosterloh84 0:d89c10040630 138 btn1.rise(buttonCallback);
rosterloh84 0:d89c10040630 139
rosterloh84 0:d89c10040630 140 DEBUG("Initialising the nRF51822\n\r");
rosterloh84 0:d89c10040630 141 ble.init();
rosterloh84 0:d89c10040630 142 ble.onConnection(connectionCallback);
rosterloh84 0:d89c10040630 143 ble.onDisconnection(disconnectionCallback);
rosterloh84 0:d89c10040630 144 ble.onDataWritten(onDataWritten);
rosterloh84 0:d89c10040630 145
rosterloh84 1:9e9c52d8270a 146 DeviceInformationService deviceInfo(ble, "NORDIC", "NRF51-DK", DEVICE_NAME, "HW-00", version.getVersion().c_str());
rosterloh84 1:9e9c52d8270a 147
rosterloh84 0:d89c10040630 148 /* setup advertising */
rosterloh84 1:9e9c52d8270a 149 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
rosterloh84 1:9e9c52d8270a 150 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
rosterloh84 1:9e9c52d8270a 151 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
rosterloh84 0:d89c10040630 152 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
rosterloh84 1:9e9c52d8270a 153 ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(100));
rosterloh84 0:d89c10040630 154 ble.startAdvertising();
rosterloh84 0:d89c10040630 155
rosterloh84 0:d89c10040630 156 UARTService uartService(ble);
rosterloh84 0:d89c10040630 157 uartServicePtr = &uartService;
rosterloh84 0:d89c10040630 158
rosterloh84 0:d89c10040630 159 while (true) {
rosterloh84 0:d89c10040630 160 if (rxPayloadUpdated) {
rosterloh84 0:d89c10040630 161 gOled.clearDisplay();
rosterloh84 0:d89c10040630 162 gOled.printf("%s", rxPayload);
rosterloh84 0:d89c10040630 163 gOled.display();
rosterloh84 0:d89c10040630 164
rosterloh84 0:d89c10040630 165 rxPayloadUpdated = false;
rosterloh84 0:d89c10040630 166 }
rosterloh84 0:d89c10040630 167
rosterloh84 0:d89c10040630 168 ble.waitForEvent();
rosterloh84 0:d89c10040630 169 }
rosterloh84 0:d89c10040630 170 }
rosterloh84 0:d89c10040630 171