-
Hi Gordon!
Thank you for your patience and support with my project. Good news, we have success!!! I'll post the final code below for anyone that is having a similar issue with the BlueFruit Feather. What seemed to make it finally work were two things - 1) The direct setting of the CCCD handle to 35. 2) Moving the TX up so that it registers the notification before sending the value to the Arduino board.
In the code below I've also added the buffer conversion, and a disconnect once it receives the correct value so that you can push the Puck to start the process again.
Again, thank you so much for your patience and support!
// 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("Setting up TX Service..."); return service.getCharacteristic(UART_TX_CHARACTERISTIC_UUID); }).then(function(txcharacteristic) { console.log("Setting up listener for incoming data..."); txcharacteristic.on('characteristicvaluechanged', function(event) { console.log("Received: "+JSON.stringify(event.target.value.buffer)); // Convert the event target value to a Uint8Array let receivedData = new Uint8Array(event.target.value.buffer); // Convert the array of ASCII codes to a string let decodedValue = String.fromCharCode.apply(null, receivedData); // Log the received value console.log("RX: " + decodedValue); if (decodedValue.trim() === "1") { disconnect(); } else { console.log("Received unexpected value: " + decodedValue); } }); txcharacteristic.handle_cccd = 35; return txcharacteristic.startNotifications(); }) .then(function() { return gattServer.getPrimaryService(UART_SERVICE_UUID); }) .then(function(service) { console.log("Got UART service"); //console.log(service); console.log(" "); return service.getCharacteristic(UART_RX_CHARACTERISTIC_UUID); }) .then(function(rxcharacteristic) { console.log("Got RX characteristic, sending '1'..."); //console.log(rxcharacteristic); console.log(" "); return rxcharacteristic.writeValue("1"); }) .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});
-
Hi Gordon - thanks so much for all of your support!
This is what the Puck returns after connection:
> Connecting Connected > Service 0x1800 1=>7 Characteristic 0x2a00 3 (CCCD 2) {broadcast:false,read:true,writeWithoutResponse:false,write:true,notify:false,indicate:false,authenticatedSignedWrites:false} Characteristic 0x2a01 5 (CCCD 4) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Characteristic 0x2a04 7 (CCCD 6) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Service 0x1801 8=>11 Characteristic 0x2a05 10 (CCCD 9) {broadcast:false,read:false,writeWithoutResponse:false,write:false,notify:false,indicate:true,authenticatedSignedWrites:false} Service 0x0000[vendor] 12=>19 Characteristic 0x0000[vendor] 14 (CCCD 13) {broadcast:false,read:false,writeWithoutResponse:true,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Characteristic 0x0000[vendor] 16 (CCCD 15) {broadcast:false,read:false,writeWithoutResponse:false,write:true,notify:true,indicate:false,authenticatedSignedWrites:false} Characteristic 0x0000[vendor] 19 (CCCD 18) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Service 0x180a 20=>30 Characteristic 0x2a29 22 (CCCD 21) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Characteristic 0x2a24 24 (CCCD 23) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Characteristic 0x2a28 26 (CCCD 25) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Characteristic 0x2a26 28 (CCCD 27) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Characteristic 0x2a27 30 (CCCD 29) {broadcast:false,read:true,writeWithoutResponse:false,write:false,notify:false,indicate:false,authenticatedSignedWrites:false} Service 6e400001-b5a3-f393-e0a9-e50e24dcca9e 31=>65535 Characteristic 6e400003-b5a3-f393-e0a9-e50e24dcca9e 33 (CCCD 32) {broadcast:false,read:false,writeWithoutResponse:false,write:false,notify:true,indicate:false,authenticatedSignedWrites:false} Characteristic 6e400002-b5a3-f393-e0a9-e50e24dcca9e 37 (CCCD 36) {broadcast:false,read:false,writeWithoutResponse:true,write:true,notify:false,indicate:false,authenticatedSignedWrites:false}
I've attached all of the pictures from nRF Connect.
-
I'll try to add as much code and images as possible to see what might help figure this out.
Here is my bare bones Arduino Code. It should receive the value from the Puck and then if it matches, send a value back.
[#include](https://forum.espruino.com/search/?q=%23include) <Arduino.h> [#include](https://forum.espruino.com/search/?q=%23include) <SPI.h> [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BLE.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_SPI.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_UART.h" [#include](https://forum.espruino.com/search/?q=%23include) "BluefruitConfig.h" [#if](https://forum.espruino.com/search/?q=%23if) SOFTWARE_SERIAL_AVAILABLE [#include](https://forum.espruino.com/search/?q=%23include) <SoftwareSerial.h> [#endif](https://forum.espruino.com/search/?q=%23endif) [#define](https://forum.espruino.com/search/?q=%23define) FACTORYRESET_ENABLE 1 [#define](https://forum.espruino.com/search/?q=%23define) MINIMUM_FIRMWARE_VERSION "0.6.6" [#define](https://forum.espruino.com/search/?q=%23define) MODE_LED_BEHAVIOUR "MODE" [#define](https://forum.espruino.com/search/?q=%23define) 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")); } } }
The first image is the Serial response.
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});
The 2nd image is the output I receive. Even if I move the TX handle to before the RX , I still get a CCCD error.
I also just added log to the Primary, RX, and TX return so that we can see what is being returned.
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
-
Hi Gordon, thank you again for spending time helping me with this.
I would like to be able to communicate back and forth between the Arduino and the Puck.
Is there something that I can share from the Bluefruit that would help?
When I use:
return require("ble_uart").connect(device);
I am receiving the error "Uncaught Error: Unhandled promise rejection: CCCD Handle not found"
But if I use
return require("ble_simple_uart").write(device, "1");
The puck will write "1" to the feather.
-
Hi Gordon - Thank you for the reply.
When I try this, I am getting a "Uncaught Error: Unhandled promise rejection: CCCD Handle not found" error from the Puck.
The Puck does connect to the Arduino board. Then it seems to lock/hold a connection to the board (which is because of not having the disconnect), but the Arduino board doesn't register the Puck writing (arduino receiving) the value to the board, so the return promise is never handled. Does that make sense?
Under the Arduino Serial output should be the lines
"if statement worked"
"Sending Start: 1"
if the arduino board received the value. -
Thanks for this info Gordon - and apologies for the delay in getting this updated. I think I'm really stuck on the eval aspect of how to receive data to the Puck.js. I'm sure I'm just missing something trivial in the library that once I see it, it will be so obvious. I tried to reduce the code to just a basic - send a simple vale "1" to the Arduino board, and once the board receives a value of "1" return back to the Puck a value of "1" to confirm the data.
Puck Code:
// Variables var feather = "ff:8d:05:ae:17:64 random"; var uart; function sendMessage() { console.log("Trying to Connect"); NRF.requestDevice({ filters: [{ id: feather }], active:true }).then(function(device) { //return require("ble_simple_uart").write(device, "1"); return require("ble_uart").connect(device); }).then(function(uart) { uart.write("1"); }).then(function() { console.log("Message sent successfully."); uart.on('data', function(d) { console.log("Got:"+JSON.stringify(d)); }); }); } // Send a message when the button is pressed setWatch(function() { sendMessage(); }, BTN, { edge: "rising", debounce: 50, repeat: true });
Arduino Code:
[#include](https://forum.espruino.com/search/?q=%23include) <Arduino.h> [#include](https://forum.espruino.com/search/?q=%23include) <SPI.h> [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BLE.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_SPI.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_UART.h" [#include](https://forum.espruino.com/search/?q=%23include) "BluefruitConfig.h" [#if](https://forum.espruino.com/search/?q=%23if) SOFTWARE_SERIAL_AVAILABLE [#include](https://forum.espruino.com/search/?q=%23include) <SoftwareSerial.h> [#endif](https://forum.espruino.com/search/?q=%23endif) [#define](https://forum.espruino.com/search/?q=%23define) FACTORYRESET_ENABLE 1 [#define](https://forum.espruino.com/search/?q=%23define) MINIMUM_FIRMWARE_VERSION "0.6.6" [#define](https://forum.espruino.com/search/?q=%23define) MODE_LED_BEHAVIOUR "MODE" [#define](https://forum.espruino.com/search/?q=%23define) 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 startRaceSequence() { Serial.println(F("if statement worked")); Serial.print("Sending Start: 1"); ble.println("1"); } void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial1.begin(9600); Serial.begin(115200); 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() { while (ble.available()) { Serial.println("Waiting for message."); char c = ble.read(); readString += c; delay(2); } if (readString.length() > 0) { Serial.println(readString); if (readString == "1") { // Send back a response message after receiving "1" ble.write("Received '1', race sequence triggered"); startRaceSequence(); } } readString = ""; }
I am able to send the value to the Arduino board, and can trigger a function on the Arduino board based on the value sent by the Puck (but usually only when I use the ble uart simple). But am not able to get a value back. I usually receive a CCCD error.
Any direction would be greatly appreciated!
-
One of the things I am stuck on with the ble_uart module, is what does the puck code look like if I already have an established connection. When I look at the source of the module, and most of the examples, they show requestDevice as the default. But when I try to use the standard ble_uart, I am getting errors that I am already connected or if I do something like :
// Function to send a message function sendMessage() { console.log("Trying to Connect"); NRF.requestDevice({ filters: [{ id: feather }], active:true }).then(function(device) { print(device); uart.write(device, "true"); }).then(function() { console.log('Done!'); }); }
I get a "Uncaught Error: Unhandled promise rejection: Error: Function "write" not found!"
Here is all of the testing code:
var feather = "ff:8d:05:ae:17:64 random"; var uart = require("ble_uart"); NRF.setAdvertising({},{ name: "Splitz Puck", showName: true, discoverable: true, connectable: true, scannable : true, }); // Blink green for 100ms function blinkGreen() { LED2.write(true); setTimeout(function () { LED2.write(false); }, 100); } // Function to send a message function sendMessage() { console.log("Trying to Connect"); NRF.requestDevice({ filters: [{ id: feather }], active:true }).then(function(device) { print(device); uart.write(device, "true"); }).then(function() { console.log('Done!'); }); } /*function sendMessage(text, tx) { return new Promise(function sender(resolve, reject) { if (text.length) { tx.writeValue(text.substr(0,20)).then(function() { sender(resolve, reject); }).catch(reject); text = text.substr(20); } else resolve(); }); }*/ // Send a message when the button is pressed setWatch(function() { blinkGreen(); sendMessage(); }, BTN, { edge: "rising", debounce: 50, repeat: true });
-
Thank you so much for all of your support on this! I've been making further progress in other areas and trying to get the arduino board and the puck to talk to each other. What I can't seem to figure out - after looking at the tutorials and digging through the forums is how to receive a ble_art update from the arduino board. I have seen the "eval" function and I've seen the examples with the web and python implementations - but how do those get adapted for the puck? sorry, I have a feeling this is a very basic question, but I can't seem to find the right direction.
-
Thank you so much for all of your support on this! I've been making further progress in other areas and trying to get the arduino board and the puck to talk to each other. What I can't seem to figure out - after looking at the tutorials and digging through the forums is how to receive a ble_art update from the arduino board. I have seen the "eval" function and I've seen the examples with the web and python implementations - but how do those get adapted for the puck? sorry, I have a feeling this is a very basic question, but I can't seem to find the right direction.
-
Lots of progress - thank you both for your patience and guidance!!! In the process, I'm learning a lot about the environments (BLE, Aurduino, and Espruino).
I have the Puck and the Feather talking to each other!!! I'm not sure EXACTLY what made it happen, but I'll go with it
Here is what I have on the Puck that works.
var feather = "ff:8d:05:ae:17:64 random"; // Blink green for 100ms function blinkGreen() { LED2.write(true); setTimeout(function () { LED2.write(false); }, 100); } // Function to send a message function sendMessage() { console.log("Trying to Connect"); NRF.requestDevice({ filters: [{ id: feather }], active:true }).then(function(device) { print(device); return require("ble_simple_uart").write(device, "true"); }).then(function() { console.log('Done!'); }); } // Send a message when the button is pressed setWatch(function() { blinkGreen(); sendMessage(); }, BTN, { edge: "rising", debounce: 50, repeat: true });
Here is what I have on the Feather. I am able to read the serial and then I have an if statement to check the value and if it matches then it triggers another function. This is just a simple example to test it, but it works.
[#include](https://forum.espruino.com/search/?q=%23include) <Arduino.h> [#include](https://forum.espruino.com/search/?q=%23include) <SPI.h> [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BLE.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_SPI.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_UART.h" [#include](https://forum.espruino.com/search/?q=%23include) "BluefruitConfig.h" [#if](https://forum.espruino.com/search/?q=%23if) SOFTWARE_SERIAL_AVAILABLE [#include](https://forum.espruino.com/search/?q=%23include) <SoftwareSerial.h> [#endif](https://forum.espruino.com/search/?q=%23endif) /*========================================================================= -----------------------------------------------------------------------*/ [#define](https://forum.espruino.com/search/?q=%23define) FACTORYRESET_ENABLE 1 [#define](https://forum.espruino.com/search/?q=%23define) MINIMUM_FIRMWARE_VERSION "0.6.6" [#define](https://forum.espruino.com/search/?q=%23define) MODE_LED_BEHAVIOUR "MODE" [#define](https://forum.espruino.com/search/?q=%23define) LED_BUILTIN 13 /*=========================================================================*/ Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); // A small helper void error(const __FlashStringHelper*err) { Serial.println(err); while (1); } /**************************************************************************/ /*! @brief Sets up the HW an the BLE module (this function is called automatically on startup) */ /**************************************************************************/ int incomingByte = 0; // for incoming serial data String readString; void testFunction(){ Serial.println(F("if statement worked")); } void setup() { // Start the hardware serial communication at 9600 baud rate Serial.begin(115200); // Serial Monitor Serial1.begin(115200); // UART Communication (Replace Serial1 with appropriate Serial for your Feather) /* Initialise the module */ Serial.print(F("Initialising the Splitz Start Beacon")); Serial.println(F("---------------------------------------")); if ( !ble.begin(VERBOSE_MODE) ){ error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?")); } Serial.println( F("OK!") ); if ( FACTORYRESET_ENABLE ){ /* Perform a factory reset to make sure everything is in a known state */ Serial.println(F("Performing a factory reset: ")); if ( ! ble.factoryReset() ){ error(F("Couldn't factory reset")); } } /* Disable command echo from Bluefruit */ ble.echo(false); Serial.println("Requesting Bluefruit info:"); /* Print Bluefruit information */ ble.info(); Serial.println(); ble.verbose(false); // debug info is a little annoying after this point! /* Change the device name to make it easier to find */ 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?")); } // Set module to DATA mode Serial.println( F("Switching to DATA mode!") ); ble.setMode(BLUEFRUIT_MODE_DATA); /* Wait for connection */ while (! ble.isConnected()) { delay(500); } if(ble.isConnected()){ Serial.println(F("Device is connected.")); } pinMode(13, OUTPUT); // Optional: Use the built-in LED to indicate received data } void loop() { // Echo received data while ( ble.available() ) { char c = ble.read(); readString += c; //makes the String readString delay(3); //slow looping to allow buffer to fill with next character } if (readString.length() > 0) { Serial.println(readString); //so you can see the captured String if (readString == "true"){ testFunction(); } readString = ""; } }
The only issue is that it disconnects after it sends the info. How would I be able to persist the connection?
I tried the below. It connects to the board but doesn't write to the serial like "requestDevice " did.
NRF.connect(feather).then(function(d){ print(d); return require("ble_simple_uart").write(d, "true"); }).then(function() { console.log('Done!'); });
-
Thank you both for the support! I put in an update using fanoush's recommendation on the Feather.
I removed the while loop so that it just continually loops. The serial response when clicking the Puck returns "I received: -1". The -1 means no data. So I'm not sure if that means the serial ports are not looking on the same space?void loop() { incomingByte = ble.read(); // say what you got: Serial.print("I received: "); Serial.println(incomingByte, DEC); }
-
I've got the Puck to connect and return the promise using requestDevice. I just don't see the result on the Arduino board. I know they connect.
// Blink green for 100ms function blinkGreen() { LED2.write(true); setTimeout(function () { LED2.write(false); }, 100); } // Function to send a message function sendMessage(message) { NRF.requestDevice({ filters: [{ id: 'ff:8d:05:ae:17:64 random' }], timeout: 2000, active:true }).then(function(device) { print(device); return require("ble_simple_uart").write(device, message); }).then(function() { print('Done!'); }); } // Send a message when the button is pressed setWatch(function() { sendMessage("Hello, Arduino!/n"); blinkGreen(); }, BTN, { edge: "rising", debounce: 50, repeat: true });
This is my arduino code with the libraries included.
[#include](https://forum.espruino.com/search/?q=%23include) <Arduino.h> [#include](https://forum.espruino.com/search/?q=%23include) <SPI.h> [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BLE.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_SPI.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_UART.h" [#include](https://forum.espruino.com/search/?q=%23include) "BluefruitConfig.h" [#if](https://forum.espruino.com/search/?q=%23if) SOFTWARE_SERIAL_AVAILABLE [#include](https://forum.espruino.com/search/?q=%23include) <SoftwareSerial.h> [#endif](https://forum.espruino.com/search/?q=%23endif) /*========================================================================= -----------------------------------------------------------------------*/ [#define](https://forum.espruino.com/search/?q=%23define) FACTORYRESET_ENABLE 1 [#define](https://forum.espruino.com/search/?q=%23define) MINIMUM_FIRMWARE_VERSION "0.6.6" [#define](https://forum.espruino.com/search/?q=%23define) MODE_LED_BEHAVIOUR "MODE" [#define](https://forum.espruino.com/search/?q=%23define) LED_BUILTIN 13 /*=========================================================================*/ Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); // A small helper void error(const __FlashStringHelper*err) { Serial.println(err); while (1); } /**************************************************************************/ /*! @brief Sets up the HW an the BLE module (this function is called automatically on startup) */ /**************************************************************************/ void setup() { // Start the hardware serial communication at 9600 baud rate Serial.begin(9600); // Serial Monitor Serial1.begin(9600); // UART Communication (Replace Serial1 with appropriate Serial for your Feather) Serial.println(F("Adafruit Bluefruit Command Mode Example")); Serial.println(F("---------------------------------------")); /* Initialise the module */ Serial.print(F("Initialising the Bluefruit LE module: ")); if ( !ble.begin(VERBOSE_MODE) ){ error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?")); } Serial.println( F("OK!") ); if ( FACTORYRESET_ENABLE ){ /* Perform a factory reset to make sure everything is in a known state */ Serial.println(F("Performing a factory reset: ")); if ( ! ble.factoryReset() ){ error(F("Couldn't factory reset")); } } /* Disable command echo from Bluefruit */ ble.echo(false); Serial.println("Requesting Bluefruit info:"); /* Print Bluefruit information */ ble.info(); Serial.println(F("Please use Adafruit Bluefruit LE app to connect in UART mode")); Serial.println(F("Then Enter characters to send to Bluefruit")); Serial.println(); ble.verbose(false); // debug info is a little annoying after this point! /* Wait for connection */ while (! ble.isConnected()) { delay(500); } while(ble.isConnected()){ Serial.println(F("Device is connected.")); delay(5000); } pinMode(13, OUTPUT); // Optional: Use the built-in LED to indicate received data } void loop() { // Check if there is any data available on Serial1 Serial.println("Serial is Available"); if (Serial.available()) { Serial.println("Serial is Available"); // Read the incoming byte String incomingMessage = ""; while (Serial.available()) { char incomingByte = Serial.read(); incomingMessage += incomingByte; } // Print the incoming message to the Serial Monitor Serial.println("Received: " + incomingMessage); // Optional: Blink LED to indicate message received digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); } }
-
Hi fanoush and Gordon,
Thank you for your help in trying to connect the puck with the Feather. The board that I am using is: https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/using-with-arduino-ide
I can get the puck and feather to "connect" to each other - when I push the button on the puck the Bluetooth LED on the Feather lights up - which means it is making a connection.
Figuring out how to exchange/communicate UART data between them after they are connected seems to be tricky.
When I include the code above I get the following error:
Device BluetoothRemoteGATTServer: { "device": BluetoothDevice: { "id": "ff:8d:05:ae:17:64 random", "gatt": ... }, "connected": true, "handle": 1 } Uncaught Error: Unhandled promise rejection: Error: Can't read property 'connect' of undefined at line 1 col 97 in .bootcde var d;return h.gatt.connect().then(function(a){d=a;return a.... ^ in function "write" called from line 16 col 6 in .bootcde }); ^ in function called from system
-
Ok, I think I am getting closer. I'm just really trying to navigate how the two different libraries (Arduino and Espruino) talk to each other.
I have the following code on the puck.js. I can see and connect to the Arduino Adafruit Feather board with the puck on a button push.
// Initialize the UART connection on Puck.js Serial1.setup(9600, { tx: D29, rx: D28 }); // Function to send a message function sendMessage(message) { NRF.connect("ff:8d:05:ae:17:64 random").then(function(d) { device = d; console.log("Device ",device); Serial1.print(message); }); } // Send a message when the button is pressed setWatch(function() { sendMessage("Hello, Arduino!"); }, BTN, { edge: "rising", debounce: 50, repeat: true });
The code on the Arduino Feather is below. In the Serial output, when I click the puck button it shows the Device Connected in the output - but I can not for some reason get the UART message to be passed between the puck and the Arduino board. I'm sure it's something simple I'm missing - so sorry if this is an easy one.
[#include](https://forum.espruino.com/search/?q=%23include) <Arduino.h> [#include](https://forum.espruino.com/search/?q=%23include) <SPI.h> [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BLE.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_SPI.h" [#include](https://forum.espruino.com/search/?q=%23include) "Adafruit_BluefruitLE_UART.h" [#include](https://forum.espruino.com/search/?q=%23include) "BluefruitConfig.h" [#if](https://forum.espruino.com/search/?q=%23if) SOFTWARE_SERIAL_AVAILABLE [#include](https://forum.espruino.com/search/?q=%23include) <SoftwareSerial.h> [#endif](https://forum.espruino.com/search/?q=%23endif) [#define](https://forum.espruino.com/search/?q=%23define) FACTORYRESET_ENABLE 1 [#define](https://forum.espruino.com/search/?q=%23define) MINIMUM_FIRMWARE_VERSION "0.6.6" [#define](https://forum.espruino.com/search/?q=%23define) MODE_LED_BEHAVIOUR "MODE" [#define](https://forum.espruino.com/search/?q=%23define) LED_BUILTIN 13 /*========================================================================= Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN, BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN); // A small helper void error(const __FlashStringHelper*err) { Serial.println(err); while (1); } /**************************************************************************/ /*! @brief Sets up the HW an the BLE module (this function is called automatically on startup) */ /**************************************************************************/ void setup() { // Start the hardware serial communication at 9600 baud rate Serial.begin(9600); // Serial Monitor Serial1.begin(9600); // UART Communication (Replace Serial1 with appropriate Serial for your Feather) Serial.println(F("Adafruit Bluefruit Command Mode Example")); Serial.println(F("---------------------------------------")); /* Initialise the module */ Serial.print(F("Initialising the Bluefruit LE module: ")); if ( !ble.begin(VERBOSE_MODE) ){ error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?")); } Serial.println( F("OK!") ); if ( FACTORYRESET_ENABLE ){ /* Perform a factory reset to make sure everything is in a known state */ Serial.println(F("Performing a factory reset: ")); if ( ! ble.factoryReset() ){ error(F("Couldn't factory reset")); } } /* Disable command echo from Bluefruit */ ble.echo(false); Serial.println("Requesting Bluefruit info:"); /* Print Bluefruit information */ ble.info(); Serial.println(F("Please use Adafruit Bluefruit LE app to connect in UART mode")); Serial.println(F("Then Enter characters to send to Bluefruit")); Serial.println(); ble.verbose(false); // debug info is a little annoying after this point! /* Wait for connection */ while (! ble.isConnected()) { delay(500); } while(ble.isConnected()){ Serial.println(F("Device is connected.")); delay(500); } pinMode(LED_BUILTIN, OUTPUT); // Optional: Use the built-in LED to indicate received data } void loop() { // Check if there is any data available on Serial1 if (Serial.available()) { // Read the incoming byte String incomingMessage = ""; while (Serial.available()) { char incomingByte = Serial.read(); incomingMessage += incomingByte; } // Print the incoming message to the Serial Monitor Serial.println("Received: " + incomingMessage); // Optional: Blink LED to indicate message received digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); } }
-
Thank you for the response - I've updated the puck.js code to include the "active:true" below, and I've included a full list of the devices that are seen by the puck.
setWatch(function(e) { NRF.findDevices(function(devices) { print(devices); }, {timeout : 2000, active : true, filters : [ { manufacturerData:{0x00D6:{}}} ] }); }, BTN, { edge: "falling", repeat: true, debounce: 50 });
[ BluetoothDevice: { "id": "2d:3b:c7:59:79:b0 private-nonresolvable", "rssi": -50, "data": new Uint8Array([2, 1, 26, 11, 255, 76, 0, 9, 6, 3, 191, 192, 168, 0, 10]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([9, 6, 3, 191, 192, 168, 0, 10]).buffer }, BluetoothDevice: { "id": "47:b8:c7:f3:29:b4 private-resolvable", "rssi": -69, "data": new Uint8Array([3, 3, 159, 254, 23, 22, 159, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).buffer, "services": [ "fe9f" ], "serviceData": { "fe9f": new ArrayBuffer(20) } }, BluetoothDevice: { "id": "70:10:8f:e4:08:a5 private-resolvable", "rssi": -49, "data": new Uint8Array([2, 1, 26, 2, 10, 12, 10, 255, 76, 0, 16, 5, 78, 28, 90, 249, 167]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([16, 5, 78, 28, 90, 249, 167]).buffer }, BluetoothDevice: { "id": "7f:bb:91:1f:68:11 private-resolvable", "rssi": -50, "data": new Uint8Array([2, 1, 26, 2, 10, 12, 11, 255, 76, 0, 16, 6, 61, 30, 200, 213, 243, 249]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([16, 6, 61, 30, 200, 213, 243, 249]).buffer }, BluetoothDevice: { "id": "ff:8d:05:ae:17:64 random", "rssi": -45, "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" ] }, BluetoothDevice: { "id": "68:6b:cd:8a:7a:e2 private-resolvable", "rssi": -76, "data": new Uint8Array([2, 1, 26, 2, 10, 7, 10, 255, 76, 0, 16, 5, 114, 28, 211, 224, 196]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([16, 5, 114, 28, 211, 224, 196]).buffer }, BluetoothDevice: { "id": "df:f6:01:75:33:e8 random", "rssi": -75, "data": new Uint8Array([7, 255, 76, 0, 18, 2, 0, 0]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([18, 2, 0, 0]).buffer } ]
-
Hi! I am new to Arduino and Puck and Bluetooth programming. This is probably a very simple thing - but I am really struggling to make this work.
I have a Puck and an Adafruit Feather BLE board that I am jut trying to send signals between. I have the Arduino board setup and I know it is broadcasting. I have the Puck setup and I can run the findDevice() to search for devices (and it creates a list of available devices).
I have the board renamed - say to "Splitz" - and my phone and Mac see the board as renamed as "Splitz" if I connect to it. But I can not for the life of me get the Puck to "see" the board.
This is what I am using to scan for devices on a Puck button push.
setWatch(function(e) { NRF.findDevices(function(devices) { print(devices); }); }, BTN, { edge: "falling", repeat: true, debounce: 50 });
The below is some of what returns. I know I just don't know what I am looking for in the returned data to parse out which one is the Feather board. The code says it is 0x00D6 hardware? I can see both devices on the Bluefruit App as well and can connect and UART to them both. I'd like to be able to send signals from the puck to the Board and vice versa.
[ BluetoothDevice: { "id": "d9:c7:44:31:02:87 random", "rssi": -79, "data": new Uint8Array([26, 255, 76, 0, 18, 2, 238, 1, 7, 17, 6, 125, 223, 234, 190, 158, 8, 80, 62, 43, 210, 193, 95, 101, 14, 224, 65]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([18, 2, 238, 1, 7, 17, 6, 125, 223, 234, 190, 158, 8, 80, 62, 43, 210, 193, 95, 101, 14, 224, 65]).buffer }, BluetoothDevice: { "id": "65:40:40:bb:4d:7f private-resolvable", "rssi": -66, "data": new Uint8Array([2, 1, 26, 13, 255, 76, 0, 22, 8, 0, 108, 189, 35, 11, 170, 240, 33]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([22, 8, 0, 108, 189, 35, 11, 170, 240, 33]).buffer }, BluetoothDevice: { "id": "6d:67:7b:97:ef:28 private-resolvable", "rssi": -48, "data": new Uint8Array([2, 1, 26, 13, 255, 76, 0, 22, 8, 0, 172, 3, 209, 26, 155, 13, 167]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([22, 8, 0, 172, 3, 209, 26, 155, 13, 167]).buffer }, BluetoothDevice: { "id": "cf:1b:24:db:c7:86 random", "rssi": -49, "data": new Uint8Array([7, 255, 76, 0, 18, 2, 0, 3]).buffer, "manufacturer": 76, "manufacturerData": new Uint8Array([18, 2, 0, 3]).buffer } ]
Any help in the right direction would be amazing!!
-
Just wondering if a solution was found for this? I am in the same situation. I have a Puck.js that I am trying to connect to an Adafruit Feather. I can see a lot of devices on a scan - but can not tell which is which based on the returned data from Puck (which looks like the screen shot above of the original poster).
Were you able to filter to find the device?
Hi Gordon,
For sure, happy to try it. Let me know what you need.