I would like to be able to communicate back and forth between the a BlueFruit Arduino Feather and an Espruino Puck.js.
Here is my bare bones Arduino Code that I am trying to get to work. It should be a simple - send value from the Puck.js to the Feather (which I am able to do), and then for the Arduino - depending on the value received, send back a specific value to the Puck. All using BLE.
The issue I am having is that the Puck is throwing a CCCD Handle Error.
I'll try to add as much code (with their outputs) and images as possible. Any assistance would be amazing!
Arduino Code:
#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"
#if SOFTWARE_SERIAL_AVAILABLE
#include <SoftwareSerial.h>
#endif
#define FACTORYRESET_ENABLE 1
#define MINIMUM_FIRMWARE_VERSION "0.6.6"
#define MODE_LED_BEHAVIOUR "MODE"
#define LED_BUILTIN 13
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);
void error(const __FlashStringHelper* err) {
Serial.println(err);
while (1);
}
int incomingByte = 0;
String readString;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.println();
Serial.println("Setting beacon configuration details: ");
Serial.println("---------------------------------------");
if (!ble.begin(VERBOSE_MODE)) {
error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
}
if (FACTORYRESET_ENABLE) {
Serial.println(F("Performing a factory reset: "));
if (!ble.factoryReset()) {
error(F("Couldn't factory reset"));
}
}
ble.echo(false);
Serial.println("Requesting Bluefruit info:");
ble.info();
Serial.println();
ble.verbose(false);
Serial.println(F("Setting device name to 'Splitz Start Beacon'"));
if (!ble.sendCommandCheckOK(F("AT+GAPDEVNAME=Splitz Start Beacon"))) {
error(F("Could not set device name?"));
}
Serial.println(F("Switching to DATA mode!"));
ble.setMode(BLUEFRUIT_MODE_DATA);
while (!ble.isConnected()) {
delay(500);
}
if (ble.isConnected()) {
Serial.println(F("BLE device is connected."));
}
}
void loop() {
if (ble.available()) {
char input[64];
int len = ble.readBytesUntil('\n', input, sizeof(input)-1);
input[len] = 0;
Serial.print(F("Received: "));
Serial.println(input);
if (strcmp(input, "hi") == 0) {
Serial.println(F("Sending reply: hello"));
ble.println("hello");
// Write to the characteristic
ble.sendCommandCheckOK(("AT+GATTCHAR=1,hello"));
}
}
}
This is the code I have for the Puck.
// Blink green for 100ms
function blinkGreen() {
LED2.write(true);
setTimeout(function () { LED2.write(false); }, 100);
}
// Variables
var feather = "ff:8d:05:ae:17:64 random";
let gattServer;
// UART Service UUID
const UART_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
// UART RX Characteristic UUID (for sending data to the Arduino)
const UART_RX_CHARACTERISTIC_UUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
// UART TX Characteristic UUID (for receiving data from the Arduino)
const UART_TX_CHARACTERISTIC_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";
// Function to connect and send data
function connectAndSend() {
console.log("Trying to connect to Arduino Board.");
NRF.requestDevice({ filters: [{ id: feather }], active: true })
.then(function(device) {
console.log("Connecting to device...");
return device.gatt.connect();
})
.then(function(gatt) {
console.log("Connected to GATT server");
gattServer = gatt;
return gatt.getPrimaryService(UART_SERVICE_UUID);
})
.then(function(service) {
console.log("Got UART service");
return service.getCharacteristic(UART_RX_CHARACTERISTIC_UUID);
})
.then(function(characteristic) {
console.log("Got RX characteristic, sending 'hi'...");
return characteristic.writeValue("hi");
})
.then(function() {
console.log("Message sent successfully");
blinkGreen();
return gattServer.getPrimaryService(UART_SERVICE_UUID);
})
.then(function(service) {
console.log("Setting up TX Service...");
return service.getCharacteristic(UART_TX_CHARACTERISTIC_UUID);
}).then(function(characteristic) {
console.log("Setting up listener for incoming data");
characteristic.on('characteristicvaluechanged', function(event) {
console.log("RX: "+JSON.stringify(event.target.value.buffer));
});
return characteristic.startNotifications();
})
.catch(function(error) {
console.log("Error: " + error);
});
}
// Function to disconnect
function disconnect() {
if (gattServer && gattServer.connected) {
gattServer.disconnect();
console.log("Disconnected");
}
}
// Button press to initiate connection and sending
setWatch(connectAndSend, BTN, {edge:"rising", repeat:true, debounce:50});
Puck output response:
Trying to connect to Arduino Board.
Connecting to device...
Connected to GATT server
Got UART service
BluetoothRemoteGATTService: {
"device": BluetoothDevice: {
"id": "ff:8d:05:ae:17:64 random",
"rssi": -61,
"data": new Uint8Array([2, 1, 6, 2, 10, 0, 17, 6, 158, 202, 220, 36, 14, 229, 169, 224, 147, 243, 163, 181, 1, 0, 64, 110]).buffer,
"services": [
"6e400001-b5a3-f393-e0a9-e50e24dcca9e"
],
"gatt": BluetoothRemoteGATTServer: {
"device": ... ,
"connected": true, "handle": 1 }
},
"uuid": "6e400001-b5a3-f393-e0a9-e50e24dcca9e",
"isPrimary": true, "start_handle": 31, "end_handle": 65535 }
Got RX characteristic, sending 'hi'...
BluetoothRemoteGATTCharacteristic: {
"service": BluetoothRemoteGATTService: {
"device": BluetoothDevice: {
"id": "ff:8d:05:ae:17:64 random",
"rssi": -61,
"data": new Uint8Array([2, 1, 6, 2, 10, 0, 17, 6, 158, 202, 220, 36, 14, 229, 169, 224, 147, 243, 163, 181, 1, 0, 64, 110]).buffer,
"services": [
"6e400001-b5a3-f393-e0a9-e50e24dcca9e"
],
"gatt": BluetoothRemoteGATTServer: {
"device": ... ,
"connected": true, "handle": 1 }
},
"uuid": "6e400001-b5a3-f393-e0a9-e50e24dcca9e",
"isPrimary": true, "start_handle": 31, "end_handle": 65535 },
"uuid": "6e400002-b5a3-f393-e0a9-e50e24dcca9e",
"handle_value": 37, "handle_decl": 36,
"properties": { "broadcast": false, "read": false, "writeWithoutResponse": true, "write": true,
"notify": false, "indicate": false, "authenticatedSignedWrites": false }
}
Setting up TX Service...
BluetoothRemoteGATTCharacteristic: {
"service": BluetoothRemoteGATTService: {
"device": BluetoothDevice: {
"id": "ff:8d:05:ae:17:64 random",
"rssi": -61,
"data": new Uint8Array([2, 1, 6, 2, 10, 0, 17, 6, 158, 202, 220, 36, 14, 229, 169, 224, 147, 243, 163, 181, 1, 0, 64, 110]).buffer,
"services": [
"6e400001-b5a3-f393-e0a9-e50e24dcca9e"
],
"gatt": BluetoothRemoteGATTServer: {
"device": ... ,
"connected": true, "handle": 1 }
},
"uuid": "6e400001-b5a3-f393-e0a9-e50e24dcca9e",
"isPrimary": true, "start_handle": 31, "end_handle": 65535 },
"uuid": "6e400003-b5a3-f393-e0a9-e50e24dcca9e",
"handle_value": 33, "handle_decl": 32,
"properties": { "broadcast": false, "read": false, "writeWithoutResponse": false, "write": false,
"notify": true, "indicate": false, "authenticatedSignedWrites": false }
}
Setting up listener for incoming data
Error: CCCD Handle not found
Arduino Serial Output: