Skip to main content

Bluetooth peripheral mode

What this example shows​

Use Inkplate 7SPECTRA as a display you control from a phone over Bluetooth LE. The sketch starts a Bluetooth LE service with a serial-style receive and transmit characteristic. Text the phone writes is passed to the run() function in the example's Peripheral.h, which draws on the display.

Pair the Inkplate with your phone in the phone's Bluetooth settings, then open a Bluetooth serial terminal app (the sketch's comments name Serial Bluetooth Terminal; a similar app works too) and pick the Inkplate from its device list. A command starts with # and ends with *. After the drawing commands, send #L(1)* to show the result on the screen; the sketch's comments say it equals display->display().

This example also uses the Bluetooth LE library (BLEDevice, BLEServer, BLEUtils, BLE2902) from arduino-esp32, which is not part of the Inkplate library and comes with the ESP32 board package.

Example code​

The listing is the sketch file. The run() function and the command parser live in Peripheral.h, in the same example folder; open the complete example below to read it.

Select Board
Inkplate7SPECTRA_Bluetooth_Peripheral_Mode.ino
#include "Inkplate.h"
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

#include "Peripheral.h"

#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" // For data coming IN to Inkplate
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" // For data coming OUT from Inkplate

BLEServer *pServer = NULL; // Pointer to BLEServer
BLECharacteristic *pTxCharacteristic; // Pointer to TX characteristic
bool deviceConnected = false; // Is client currently connected
bool oldDeviceConnected = false; // Store the previous connection

Inkplate inkplate;

#define BUFFER_SIZE 1000

char commandBuffer[BUFFER_SIZE + 1];

class MyServerCallbacks : public BLEServerCallbacks
{
void onConnect(BLEServer *pServer) {
deviceConnected = true;
Serial.println("Device connected");
};

void onDisconnect(BLEServer *pServer) {
deviceConnected = false;
Serial.println("Device disconnected");
}
};

class MyCallbacks : public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *pCharacteristic) {
String rxValue = pCharacteristic->getValue();

if (rxValue.length() > 0)
{
size_t len = rxValue.length();
if (len > BUFFER_SIZE)
{
len = BUFFER_SIZE;
}
memcpy(commandBuffer, rxValue.c_str(), len);
commandBuffer[len] = 0;

run(commandBuffer, len, &inkplate, pTxCharacteristic);
}
}
};

void setup() // Initialize everything
{
Serial.begin(115200);

inkplate.begin();

BLEDevice::init("Inkplate 7 SPECTRA");

pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());

BLEService *pService = pServer->createService(SERVICE_UUID);

pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);

pTxCharacteristic->addDescriptor(new BLE2902());

BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);

pRxCharacteristic->setCallbacks(new MyCallbacks());

pService->start();

pServer->getAdvertising()->start();

if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED)
{
Serial.println("BLE controller failed to start.");
}
else
{
Serial.println("The device started, now you can pair it with Bluetooth and send commands.");
}
}

void loop()
{
if (!deviceConnected && oldDeviceConnected)
{
delay(500); // Allow bluetooth stack some time
pServer->startAdvertising(); // Restart advertising
oldDeviceConnected = false;
}

if (deviceConnected && !oldDeviceConnected)
{
oldDeviceConnected = true;
}
}

Functions used​

Inkplate()returns None

Creates the Inkplate object. Inkplate 7SPECTRA has a single six-color mode, so the constructor takes no mode argument.

ReturnsConstructor; no return value.

inkplate.begin()returns void

Initializes the library, the peripherals and the frame buffer. Call it once in setup().

ReturnsNothing.

run(char commandBuffer[], size_t n, Inkplate *display, BLECharacteristic *pTxCharacteristic)returns void

Defined in the example's Peripheral.h. Looks for a command between # and * in the received text, runs the matching drawing function on the Inkplate object, and answers on the transmit characteristic when a command asks for it (the command `#?` replies OK).

ReturnsNothing.

Serial.begin(115200)returns void

Arduino core function: starts the serial port at 115200 baud.

ReturnsNothing.

BLEDevice::init(name)returns void

Bluetooth LE library of the ESP32 board package: starts Bluetooth LE with the device name the phone sees, here Inkplate 7 SPECTRA.

ReturnsNothing.

BLEDevice::createServer()returns BLEServer *

Bluetooth LE library: creates the Bluetooth LE server.

ReturnsThe server.

pServer->setCallbacks(callbacks)returns void

Bluetooth LE library: registers the object whose onConnect and onDisconnect functions run when a phone connects or disconnects. The sketch prints Device connected or Device disconnected.

ReturnsNothing.

pServer->createService(SERVICE_UUID)returns BLEService *

Bluetooth LE library: creates the service with the UART service UUID defined at the top of the sketch.

ReturnsThe service.

pService->createCharacteristic(uuid, properties)returns BLECharacteristic *

Bluetooth LE library: creates a characteristic. The sketch makes a transmit characteristic with PROPERTY_NOTIFY (data going out from Inkplate) and a receive characteristic with PROPERTY_WRITE (data coming in).

ReturnsThe characteristic.

pTxCharacteristic->addDescriptor(new BLE2902())returns void

Bluetooth LE library: lets the phone turn notifications on and off for the transmit characteristic.

ReturnsNothing.

pRxCharacteristic->setCallbacks(new MyCallbacks())returns void

Bluetooth LE library: registers the object whose onWrite function runs when the phone writes to the receive characteristic.

ReturnsNothing.

pCharacteristic->getValue()returns String

Bluetooth LE library: returns the text the phone wrote. The sketch copies at most 1000 characters of it into a buffer and passes the buffer to run().

ReturnsThe received text.

pTxCharacteristic->setValue(value)returns void

Bluetooth LE library, called inside run(): sets the value to send back to the phone.

ReturnsNothing.

pTxCharacteristic->notify()returns void

Bluetooth LE library, called inside run(): sends the value to the connected phone.

ReturnsNothing.

pService->start()returns void

Bluetooth LE library: starts the service.

ReturnsNothing.

pServer->getAdvertising()->start()returns void

Bluetooth LE library: starts advertising, so the phone can find the Inkplate.

ReturnsNothing.

pServer->startAdvertising()returns void

Bluetooth LE library: restarts advertising. The sketch calls it in loop() half a second after a phone disconnects, so a new one can connect.

ReturnsNothing.

esp_bt_controller_get_status()returns esp_bt_controller_status_t

ESP32 board package function: returns the state of the Bluetooth controller. The sketch compares it with ESP_BT_CONTROLLER_STATUS_ENABLED to report whether Bluetooth started.

ReturnsThe controller state.

Serial.println(text)returns size_t

Arduino core function: prints a line to the Serial Monitor.

ReturnsNumber of bytes printed.

delay(ms)returns void

Arduino core function: waits for the given number of milliseconds.

ReturnsNothing.

What to expect​

With the Serial Monitor at 115200 baud, the sketch prints once Bluetooth has started:

Serial MonitorAutoscrollShow timestampNewline115200 baud
Message (Enter to send message to the board)
The device started, now you can pair it with Bluetooth and send commands.

It prints Device connected when a phone connects and Device disconnected when it leaves; if Bluetooth does not start, it prints BLE controller failed to start. instead. The screen shows nothing until the phone sends drawing commands followed by #L(1)*.

🔗Open the complete example

examples/Inkplate7SPECTRA/Advanced/Communications/Inkplate7SPECTRA_Bluetooth_Peripheral_Mode

→