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

Dependencies:   Adafruit_GFX BLE_API mbed nRF51822 SemVer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /**
00002  *  @file
00003  *  @date   30 March 2015
00004  *  @author Richard Osterloh <richard.osterloh@gmail.com>
00005  */
00006  
00007 #include "mbed.h"
00008 #include "BLEDevice.h"
00009 #include "DeviceInformationService.h"
00010 #include "UARTService.h"
00011 
00012 #include "Adafruit_SSD1306.h"
00013 #include "SemVer.h"
00014 
00015 #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console;
00016                                * it will have an impact on code-size and power consumption. */
00017 
00018 #if NEED_CONSOLE_OUTPUT
00019 #define DEBUG(...) { if (uartServicePtr) uartServicePtr->writeString(__VA_ARGS__); }
00020 #else
00021 #define DEBUG(...) /* nothing */
00022 #endif /* #if NEED_CONSOLE_OUTPUT */
00023 
00024 SemVer version("1.0.0");
00025 
00026 BLEDevice  ble;
00027 DigitalOut led1(LED1);
00028 DigitalOut led2(LED2);
00029 DigitalOut led3(LED3);
00030 DigitalOut led4(LED4);
00031 
00032 InterruptIn btn1(BUTTON1);
00033 
00034 DigitalOut oled_gnd(p3);
00035 
00036 // an I2C sub-class that provides a constructed default
00037 class I2CPreInit : public I2C
00038 {
00039 public:
00040     I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
00041     {
00042         oled_gnd = 0;
00043         frequency(400000);
00044         start();
00045     };
00046 };
00047 
00048 I2CPreInit gI2C(p5, p4); // SDA, SCL
00049 Adafruit_SSD1306_I2c gOled(gI2C, p2, 0x78, 64, 128); // I2C, RST, ADDRESS, WIDTH, HEIGHT
00050 
00051 bool rxPayloadUpdated = false;
00052 const static unsigned MAX_SIZEOF_RX_PAYLOAD = 20;
00053 char rxPayload[MAX_SIZEOF_RX_PAYLOAD] = {0,};
00054 
00055 UARTService *uartServicePtr;
00056 
00057 const static char     DEVICE_NAME[] = "BLE DISPLAY";
00058 static const uint16_t uuid16_list[] = {GattService::UUID_DEVICE_INFORMATION_SERVICE};
00059                     
00060 /**
00061  *  Callback to write to connected client and display
00062  */
00063 void buttonCallback(void)
00064 {
00065     if(btn1) {
00066         gOled.clearDisplay();
00067         gOled.printf("%s", "BTN 0 released");
00068         gOled.display();
00069         uartServicePtr->writeString("Button 0 released\r\n");
00070     } else {
00071         gOled.clearDisplay();
00072         gOled.printf("%s", "BTN 0 pressed");
00073         gOled.display();
00074         uartServicePtr->writeString("Button 0 pressed\r\n");
00075     }
00076 }
00077 
00078 /**
00079  * Callback when new client connects to device
00080  * 
00081  * @param tHandle handle to this specific client
00082  * @param ePeerAddrType the type of the connected clients address
00083  * @param c6PeerAddr the address of the connected client
00084  * @param params requested connection parameters
00085  */
00086 void connectionCallback(Gap::Handle_t tHandle, Gap::addr_type_t ePeerAddrType, const Gap::address_t c6PeerAddr, const Gap::ConnectionParams_t *params)
00087 {
00088     //DEBUG("CONNECT: Handle:%u, eType:%d, Add:%u\r\n", tHandle, ePeerAddrType, c6PeerAddr);
00089     //DEBUG("         minInterval:%d, maxInterval:%d, latency:%d, timeout:%d\r\n",
00090     //          params->minConnectionInterval, params->maxConnectionInterval, params->slaveLatency, params->connectionSupervisionTimeout);
00091     DEBUG("CONNECTED\r\n");
00092     led2 = 1; led4 = 0;
00093 }
00094 
00095 /**
00096  * Callback called when a client disconnects
00097  * 
00098  * @param tHandle handle of the disconnected client
00099  * @param eReason the reason they disconnected
00100  */
00101 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00102 {
00103     DEBUG("Disconnected!\n\r");
00104     DEBUG("Restarting the advertising process\n\r");
00105     ble.startAdvertising();
00106     led2 = 0; led4 = 1;
00107 }
00108 
00109 /**
00110  * Callback called when a client writes to this device
00111  * 
00112  * @param params all parameters related to this data
00113  */
00114 void onDataWritten(const GattCharacteristicWriteCBParams *params)
00115 {
00116     if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
00117         uint16_t bytesRead = params->len;
00118         if (bytesRead < MAX_SIZEOF_RX_PAYLOAD) {
00119             strncpy(rxPayload, (const char *)params->data, MAX_SIZEOF_RX_PAYLOAD - 1);
00120             rxPayload[bytesRead] = '\0';
00121             rxPayloadUpdated = true;
00122             ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
00123         }
00124     }
00125 }
00126 
00127 void periodicCallback(void)
00128 {
00129     led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
00130 }
00131 
00132 int main(void)
00133 {
00134     led1 = 1; led2 = 1; led3 = 1; led4 = 1;
00135     Ticker ticker;
00136     ticker.attach(periodicCallback, 1);
00137     btn1.fall(buttonCallback);
00138     btn1.rise(buttonCallback);
00139 
00140     DEBUG("Initialising the nRF51822\n\r");
00141     ble.init();
00142     ble.onConnection(connectionCallback);
00143     ble.onDisconnection(disconnectionCallback);
00144     ble.onDataWritten(onDataWritten);
00145     
00146     DeviceInformationService deviceInfo(ble, "NORDIC", "NRF51-DK", DEVICE_NAME, "HW-00", version.getVersion().c_str());
00147     
00148     /* setup advertising */
00149     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00150     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00151     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00152     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00153     ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(100));
00154     ble.startAdvertising();
00155 
00156     UARTService uartService(ble);
00157     uartServicePtr = &uartService;
00158     
00159     while (true) {
00160         if (rxPayloadUpdated) {
00161             gOled.clearDisplay();
00162             gOled.printf("%s", rxPayload);
00163             gOled.display();
00164 
00165             rxPayloadUpdated = false;
00166         }
00167 
00168         ble.waitForEvent();
00169     }
00170 }
00171