sandeepmistry / arduino-BLEPeripheral

An Arduino library for creating custom BLE peripherals with Nordic Semiconductor's nRF8001 or nR51822.
MIT License
462 stars 179 forks source link

Redbear BLE Nano v1.5 can't write to remote characteristic #154

Open jacobmh1177 opened 7 years ago

jacobmh1177 commented 7 years ago

I'm trying to implement the ancs example again, except this time using a Redbear BLE Nano. I can subscribe to the Notification Source just fine. However ancsControlPointCharacteristic.canWrite() returns False and ancsControlPointCharacteristic.write(...) also returns false. Have you encountered this error before on this board where you can't write to remote characteristics? Here is my code below:

include

include

include

//custom boards may override default pin definitions with BLEPeripheral(PIN_REQ, PIN_RDY, PIN_RST) BLEPeripheral blePeripheral = BLEPeripheral(-1, -1, -1); BLEBondStore bleBondStore;

// remote services BLERemoteService ancsService = BLERemoteService("7905f431b5ce4e99a40f4b1e122d00d0");

// remote characteristics BLERemoteCharacteristic ancsNotificationSourceCharacteristic = BLERemoteCharacteristic("9fbf120d630142d98c5825e699a21dbd", BLENotify); BLERemoteCharacteristic ancsControlPointCharacteristic = BLERemoteCharacteristic("69d1d8f345e149a898219bbdfdaad9d9", BLEWrite); BLERemoteCharacteristic ancsDataSourceCharacteristic = BLERemoteCharacteristic("22eac6e924d64bb5be44b36ace7c7bfb", BLENotify);

void setup() { Serial.begin(9600);

if defined (__AVR_ATmega32U4__)

while(!Serial);

endif

// clears bond data on every boot bleBondStore.clearData();

blePeripheral.setBondStore(bleBondStore);

blePeripheral.setServiceSolicitationUuid(ancsService.uuid()); blePeripheral.setLocalName("ANCS");

// set device name and appearance blePeripheral.setDeviceName("Arduino ANCS"); blePeripheral.setAppearance(0x0080);

blePeripheral.addRemoteAttribute(ancsService); blePeripheral.addRemoteAttribute(ancsNotificationSourceCharacteristic); blePeripheral.addRemoteAttribute(ancsControlPointCharacteristic); blePeripheral.addRemoteAttribute(ancsDataSourceCharacteristic);

// assign event handlers for connected, disconnected to peripheral blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler); blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler); blePeripheral.setEventHandler(BLEBonded, blePeripheralBondedHandler); blePeripheral.setEventHandler(BLERemoteServicesDiscovered, blePeripheralRemoteServicesDiscoveredHandler);

// assign event handlers for characteristic ancsNotificationSourceCharacteristic.setEventHandler(BLEValueUpdated, ancsNotificationSourceCharacteristicValueUpdated); // ancsDataSourceCharacteristic.setEventHandler(BLEValueUpdated, ancsDataSourceCharacteristicCharacteristicValueUpdated);

// begin initialization blePeripheral.begin();

Serial.println(F("BLE Peripheral - ANCS")); }

void loop() { blePeripheral.poll(); }

void blePeripheralConnectHandler(BLECentral& central) { // central connected event handler Serial.print(F("Connected event, central: ")); Serial.println(central.address()); }

void blePeripheralDisconnectHandler(BLECentral& central) { // central disconnected event handler Serial.print(F("Disconnected event, central: ")); Serial.println(central.address()); }

void blePeripheralBondedHandler(BLECentral& central) { // central bonded event handler Serial.print(F("Remote bonded event, central: ")); Serial.println(central.address());

if (ancsNotificationSourceCharacteristic.canSubscribe()) { ancsNotificationSourceCharacteristic.subscribe(); } }

void blePeripheralRemoteServicesDiscoveredHandler(BLECentral& central) { // central remote services discovered event handler Serial.print(F("Remote services discovered event, central: ")); Serial.println(central.address());

if (ancsNotificationSourceCharacteristic.canSubscribe()) { ancsNotificationSourceCharacteristic.subscribe(); } }

enum AncsNotificationEventId { AncsNotificationEventIdAdded = 0, AncsNotificationEventIdModified = 1, AncsNotificationEventIdRemoved = 2 };

enum AncsNotificationEventFlags { AncsNotificationEventFlagsSilent = 1, AncsNotificationEventFlagsImportant = 2, AncsNotificationEventFlagsPositiveAction = 4, AncsNotificationEventFlagsNegativeAction = 8 };

enum AncsNotificationCategoryId { AncsNotificationCategoryIdOther = 0, AncsNotificationCategoryIdIncomingCall = 1, AncsNotificationCategoryIdMissedCall = 2, AncsNotificationCategoryIdVoicemail = 3, AncsNotificationCategoryIdSocial = 4, AncsNotificationCategoryIdSchedule = 5, AncsNotificationCategoryIdEmail = 6, AncsNotificationCategoryIdNews = 7, AncsNotificationCategoryIdHealthAndFitness = 8, AncsNotificationCategoryIdBusinessAndFinance = 9, AncsNotificationCategoryIdLocation = 10, AncsNotificationCategoryIdEntertainment = 11 };

struct AncsNotification { unsigned char eventId; unsigned char eventFlags; unsigned char catergoryId; unsigned char catergoryCount; unsigned long notificationUid; };

void ancsNotificationSourceCharacteristicValueUpdated(BLECentral& central, BLERemoteCharacteristic& characteristic) { Serial.println(F("ANCS Notification Source Value Updated:")); struct AncsNotification notification;

memcpy(&notification, characteristic.value(), sizeof(notification));

Serial.print("\tEvent ID: "); Serial.println(notification.eventId); Serial.print("\tEvent Flags: 0x"); Serial.println(notification.eventFlags, HEX); Serial.print("\tCategory ID: "); Serial.println(notification.catergoryId); Serial.print("\tCategory Count: "); Serial.println(notification.catergoryCount); Serial.print("\tNotification UID: "); Serial.println(notification.notificationUid); if (ancsDataSourceCharacteristic.canSubscribe()) { ancsDataSourceCharacteristic.subscribe(); Serial.println("Subscribed to Data Source"); } unsigned long uid = notification.notificationUid; byte buffer[8]; buffer[0] = 0; buffer[4] = (uid >> 24) & 0xFF; buffer[3] = (uid >> 16) & 0xFF; buffer[2] = (uid >> 8) & 0xFF; buffer[1] = uid & 0xFF; buffer[5] = 3;//ANCS_NOTIFICATION_ATTRIBUTE_MESSAGE; buffer[6] = 20; //ANCS_NOTIFICATION_ATTRIBUTE_MESSAGE; buffer[7] = 0; //ANCS_NOTIFICATION_ATTRIBUTE_MESSAGE; BLEUtil::printBuffer(buffer, 8); Serial.println("Sending notification attribute buffer "); Serial.println(); Serial.println(ancsControlPointCharacteristic.canWrite()); Serial.println(ancsControlPointCharacteristic.write((const unsigned char*)buffer, 8));

// BLEUtil::printBuffer(characteristic.value(), characteristic.valueLength()); }

void ancsDataSourceCharacteristicCharacteristicValueUpdated(BLECentral& central, BLERemoteCharacteristic& characteristic) { Serial.print(F("ANCS Data Source Value Updated: "));

BLEUtil::printBuffer(characteristic.value(), characteristic.valueLength()); }

claudioarduino commented 7 years ago

@jacobmh1177 Hi jacob, I commented you on issue #142 . I solved the problem with the data source. Did you see?

jacobmh1177 commented 7 years ago

@claudioarduino Yes, and it works great thank you so much :) I switched boards to the redbear ble nano because of memory issues. I'm trying to get our code working on the ble nano and created this issue because it won't even write to the control point (as opposed to our original problem using the nrf8001 where we could write to the control point but were having trouble subscribing to the data source). If you've got any tips here I'd love your help again!