Simple program to enable me to write to a 128x64 OLED display over BLE
Dependencies: Adafruit_GFX BLE_API mbed nRF51822 SemVer
main.cpp
- Committer:
- rosterloh84
- Date:
- 2015-03-30
- Revision:
- 1:9e9c52d8270a
- Parent:
- 0:d89c10040630
File content as of revision 1:9e9c52d8270a:
/**
* @file
* @date 30 March 2015
* @author Richard Osterloh <richard.osterloh@gmail.com>
*/
#include "mbed.h"
#include "BLEDevice.h"
#include "DeviceInformationService.h"
#include "UARTService.h"
#include "Adafruit_SSD1306.h"
#include "SemVer.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(...) { if (uartServicePtr) uartServicePtr->writeString(__VA_ARGS__); }
#else
#define DEBUG(...) /* nothing */
#endif /* #if NEED_CONSOLE_OUTPUT */
SemVer version("1.0.0");
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 static char DEVICE_NAME[] = "BLE DISPLAY";
static const uint16_t uuid16_list[] = {GattService::UUID_DEVICE_INFORMATION_SERVICE};
/**
* 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);
DeviceInformationService deviceInfo(ble, "NORDIC", "NRF51-DK", DEVICE_NAME, "HW-00", version.getVersion().c_str());
/* setup advertising */
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(100));
ble.startAdvertising();
UARTService uartService(ble);
uartServicePtr = &uartService;
while (true) {
if (rxPayloadUpdated) {
gOled.clearDisplay();
gOled.printf("%s", rxPayload);
gOled.display();
rxPayloadUpdated = false;
}
ble.waitForEvent();
}
}
Richard Osterloh