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

Dependencies:   Adafruit_GFX BLE_API mbed nRF51822 SemVer

Revision:
0:d89c10040630
Child:
1:9e9c52d8270a
diff -r 000000000000 -r d89c10040630 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Mar 30 10:06:34 2015 +0000
@@ -0,0 +1,166 @@
+/**
+ *  @file
+ *  @date   30 March 2015
+ *  @author Richard Osterloh <richard.osterloh@gmail.com>
+ */
+ 
+#include "mbed.h"
+#include "BLEDevice.h"
+#include "UARTService.h"
+
+#include "Adafruit_SSD1306.h"
+
+#define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console;
+                               * it will have an impact on code-size and power consumption. */
+
+#if NEED_CONSOLE_OUTPUT
+#define DEBUG(STR) { if (uartServicePtr) uartServicePtr->writeString(STR); }
+#else
+#define DEBUG(...) /* nothing */
+#endif /* #if NEED_CONSOLE_OUTPUT */
+
+BLEDevice  ble;
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+InterruptIn btn1(BUTTON1);
+
+DigitalOut oled_gnd(p3);
+
+// an I2C sub-class that provides a constructed default
+class I2CPreInit : public I2C
+{
+public:
+    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
+    {
+        oled_gnd = 0;
+        frequency(400000);
+        start();
+    };
+};
+
+I2CPreInit gI2C(p5, p4); // SDA, SCL
+Adafruit_SSD1306_I2c gOled(gI2C, p2, 0x78, 64, 128); // I2C, RST, ADDRESS, WIDTH, HEIGHT
+
+bool rxPayloadUpdated = false;
+const static unsigned MAX_SIZEOF_RX_PAYLOAD = 20;
+char rxPayload[MAX_SIZEOF_RX_PAYLOAD] = {0,};
+
+UARTService *uartServicePtr;
+
+const char *deviceName = "BLE DISPLAY";
+
+/**
+ *  Callback to write to connected client and display
+ */
+void buttonCallback(void)
+{
+    if(btn1) {
+        gOled.clearDisplay();
+        gOled.printf("%s", "BTN 0 released");
+        gOled.display();
+        uartServicePtr->writeString("Button 0 released\r\n");
+    } else {
+        gOled.clearDisplay();
+        gOled.printf("%s", "BTN 0 pressed");
+        gOled.display();
+        uartServicePtr->writeString("Button 0 pressed\r\n");
+    }
+}
+
+/**
+ * Callback when new client connects to device
+ * 
+ * @param tHandle handle to this specific client
+ * @param ePeerAddrType the type of the connected clients address
+ * @param c6PeerAddr the address of the connected client
+ * @param params requested connection parameters
+ */
+void connectionCallback(Gap::Handle_t tHandle, Gap::addr_type_t ePeerAddrType, const Gap::address_t c6PeerAddr, const Gap::ConnectionParams_t *params)
+{
+    //DEBUG("CONNECT: Handle:%u, eType:%d, Add:%u\r\n", tHandle, ePeerAddrType, c6PeerAddr);
+    //DEBUG("         minInterval:%d, maxInterval:%d, latency:%d, timeout:%d\r\n",
+    //          params->minConnectionInterval, params->maxConnectionInterval, params->slaveLatency, params->connectionSupervisionTimeout);
+    DEBUG("CONNECTED\r\n");
+    led2 = 1; led4 = 0;
+}
+
+/**
+ * Callback called when a client disconnects
+ * 
+ * @param tHandle handle of the disconnected client
+ * @param eReason the reason they disconnected
+ */
+void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
+{
+    DEBUG("Disconnected!\n\r");
+    DEBUG("Restarting the advertising process\n\r");
+    ble.startAdvertising();
+    led2 = 0; led4 = 1;
+}
+
+/**
+ * Callback called when a client writes to this device
+ * 
+ * @param params all parameters related to this data
+ */
+void onDataWritten(const GattCharacteristicWriteCBParams *params)
+{
+    if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
+        uint16_t bytesRead = params->len;
+        if (bytesRead < MAX_SIZEOF_RX_PAYLOAD) {
+            strncpy(rxPayload, (const char *)params->data, MAX_SIZEOF_RX_PAYLOAD - 1);
+            rxPayload[bytesRead] = '\0';
+            rxPayloadUpdated = true;
+            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
+        }
+    }
+}
+
+void periodicCallback(void)
+{
+    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
+}
+
+int main(void)
+{
+    led1 = 1; led2 = 1; led3 = 1; led4 = 1;
+    Ticker ticker;
+    ticker.attach(periodicCallback, 1);
+    btn1.fall(buttonCallback);
+    btn1.rise(buttonCallback);
+
+    DEBUG("Initialising the nRF51822\n\r");
+    ble.init();
+    ble.onConnection(connectionCallback);
+    ble.onDisconnection(disconnectionCallback);
+    ble.onDataWritten(onDataWritten);
+    
+    /* setup advertising */
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)deviceName, strlen(deviceName));
+    /*ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
+                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));*/
+
+    ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
+    ble.startAdvertising();
+
+    UARTService uartService(ble);
+    uartServicePtr = &uartService;
+    
+    while (true) {
+        if (rxPayloadUpdated) {
+            gOled.clearDisplay();
+            gOled.printf("%s", rxPayload);
+            gOled.display();
+
+            rxPayloadUpdated = false;
+        }
+
+        ble.waitForEvent();
+    }
+}
+