I'm using a MKR 1010 WiFi to send text commands to a device using a custom API. The commands are variable length HEX and upwards of 20 bytes. I've tried splitting them into 4 bytes and sending them sequentially, and storing an array and sending one byte at a time. The receiving device should be able to reconstruct commands sent in pieces using the presence of a total message length field and a footer. Reading the Characteristic after writing only shows the last byte sent and not the full message.
So, two questions:
Does the BLECharacteristic.writeValue() function have a limit or buffer for the length it can send?
Does Arduino actually store and send zero values? If I'm sending as part of the full command const long DEP2 = 0x00980080; is the leading byte of 0x00 dropped shifting the other bytes of the command?
Thanks,
#include <ArduinoBLE.h>
// Define ActiveLook advertising data
const char* deviceNamePrefix = "A.LooK";
const char* manufacturerName = "Microoled";
const char* serialNumber = "090105"; // Replace "xxxxxx" with the actual serial number
const int manufacturerDataLength = 9; // Length of the manufacturer data
// Custom service UUIDs
const char* activeLookCommandsServiceUUID = "0783B03E-8535-B5A0-7140-A304D2495CB7";
const char* firmwareUpdateServiceUUID = "0000FEF5-0000-1000-8000-00805F9B34FB";
// ActiveLook command characteristic UUIDs
const char* txActiveLookCharacteristicUUID = "0783B03E-8535-B5A0-7140-A304D2495CB8";
const char* rxActiveLookCharacteristicUUID = "0783B03E-8535-B5A0-7140-A304D2495CBA";
const char* controlCharacteristicUUID = "0783B03E-8535-B5A0-7140-A304D2495CB9";
const char* gestureEventCharacteristicUUID = "0783B03E-8535-B5A0-7140-A304D2495CBB";
const char* touchEventCharacteristicUUID = "0783B03E-8535-B5A0-7140-A304D2495CBC";
// ActiveLook command descriptor UUIDs
// BLE advertising parameters
const int initialAdvertisingInterval = 25;
BLEService activeLookCommandsService(activeLookCommandsServiceUUID); //Creates the service
BLEService firmwareUpdateService(firmwareUpdateServiceUUID);
BLECharacteristic txActiveLookCharacteristic;
BLELongCharacteristic rxActiveLookCharacteristic(rxActiveLookCharacteristicUUID, BLEWrite | BLERead); //Creates the RX characteristic
BLECharacteristic controlCharacteristic;
BLECharacteristic gestureEventCharacteristic;
BLECharacteristic touchEventCharacteristic;
BLEDescriptor ServerRXData("2901", "Server RX Data"); //Not sure if this is needed CJ
//Long and int variable types only hold 4 bytes, need to send 20 or more bytes
const long HELLO_TEXT = 0xFF3700140098008000020F68656C6C6F203000AA; //20 Bytes, Demo hello command form AL API
int clearScreen[] = { 0xFF, 0x01, 0x00, 0x05, 0xAA };
const unsigned long CLEAR = 0xFF010005; //FF010005 //5 Bytes, Clear Display command from AL API
const long CLEAR_B = 0b11111111000000010000000000000101; //first 4 bytes clear command in binary
const long END = 0xAA;
const long END_B = 0b10101010; // last byte of clear command (footer) of clear command in binary
//Approaching command in HEX array
long approaching[] = { 0xFF, 0x37, 0x00, 0x14, 0x00, 0x98, 0x00, 0x80, 0x00, 0x02, 0x0F, 0x41, 0x70, 0x70, 0x72, 0x6F, 0x61, 0x63, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x21, 0x00, 0xAA };
//Approaching Command, Separated into 4 bytes, 26 bytes total
//FF 37 00 14 00 98 00 80 00 02 0F 41 70 70 72 6F 61 63 68 69 6E 67 20 21 00 AA
const long APP1 = 0xFF370014;
const long APP2 = 0x00980080;
const long APP3 = 0x00020F41;
const long APP4 = 0x7070726F;
const long APP5 = 0x61636869;
const long APP6 = 0x6E672021;
const long APP7 = 0x00AA;
//Departing Command, Separated into 4 byte, 23 bytes total
//FF 37 00 14 00 98 00 80 00 02 0F 44 65 70 61 72 74 69 6E 67 20 00 AA
const long DEP1 = 0xFF370014;
const long DEP2 = 0x00980080;
const long DEP3 = 0x00020F44;
const long DEP4 = 0x65706172;
const long DEP5 = 0x74696E67;
const long DEP6 = 0x2000AA;
void setup() {
Serial.begin(9600);
while (!Serial)
;
// begin initialization
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1)
;
}
Serial.println("Bluetooth® Low Energy Central - Peripheral Explorer");
// start scanning for peripherals
BLE.scan();
}
void loop() {
// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
// see if peripheral is a LED
if (peripheral.localName() == "ENGO 2 090145") {
// stop scanning
BLE.stopScan();
explorerPeripheral(peripheral); //Connects only, removed all other functions
}
// Add services
BLE.setAdvertisedService(activeLookCommandsService);
BLE.setAdvertisedService(firmwareUpdateService);
// Add characteristics to services
activeLookCommandsService.addCharacteristic(txActiveLookCharacteristic);
activeLookCommandsService.addCharacteristic(rxActiveLookCharacteristic);
activeLookCommandsService.addCharacteristic(controlCharacteristic);
activeLookCommandsService.addCharacteristic(gestureEventCharacteristic);
activeLookCommandsService.addCharacteristic(touchEventCharacteristic);
// Add descriptor(s) to rx characteristic
rxActiveLookCharacteristic.addDescriptor(ServerRXData);
if (peripheral.connected()) {
//for (int i = 0; i < 26; i = i + 1){
//rxActiveLookCharacteristic.writeValue(clearScreen[i]);
//rxActiveLookCharacteristic.writeValue(CLEAR);
//rxActiveLookCharacteristic.writeValue(END);
//Serial.print(CLEAR, HEX);
//approachingDisplay();
clearDisplay();
}
}
//Serial.println(rxActiveLookCharacteristic.value(), HEX);
//Serial.println(APP2, HEX);
//Serial.println(CLEAR, HEX);
}
void clearDisplay() {
rxActiveLookCharacteristic.writeValueBE(CLEAR_B);
rxActiveLookCharacteristic.writeValueBE(END_B);
}
void approachingDisplay() {
for (int i = 0; i < 26; i = i + 1) {
rxActiveLookCharacteristic.writeValueBE(approaching[i]);
Serial.println(approaching[i], HEX);
}
Serial.println(rxActiveLookCharacteristic.value(), HEX);
/*rxActiveLookCharacteristic.writeValue(APP1);
rxActiveLookCharacteristic.writeValue(APP2);
rxActiveLookCharacteristic.writeValue(APP3);
rxActiveLookCharacteristic.writeValue(APP4);
rxActiveLookCharacteristic.writeValue(APP5);
rxActiveLookCharacteristic.writeValue(APP6);
rxActiveLookCharacteristic.writeValue(APP7);*/
}
void departingDisplay() {
rxActiveLookCharacteristic.writeValue(DEP1);
rxActiveLookCharacteristic.writeValue(DEP2);
rxActiveLookCharacteristic.writeValue(DEP3);
rxActiveLookCharacteristic.writeValue(DEP4);
rxActiveLookCharacteristic.writeValue(DEP5);
rxActiveLookCharacteristic.writeValue(DEP6);
}
void explorerPeripheral(BLEDevice peripheral) {
// connect to the peripheral
Serial.println("Connecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
}
void canWrite(BLEDevice peripheral) {
if (rxActiveLookCharacteristic.canWrite()) {
Serial.println("characteristic is writable");
} else {
Serial.println("characteristic is NOT writable");
}
}
void printServiceUUID(BLEDevice peripheral) {
// print the advertised service UUIDs, if present
if (peripheral.hasAdvertisedServiceUuid()) {
Serial.print("Service UUIDs: ");
for (int i = 0; i < peripheral.advertisedServiceUuidCount(); i++) {
Serial.print(peripheral.advertisedServiceUuid(i));
Serial.print(" ");
}
Serial.println();
}
}