I am trying to communicate with the nRF Connect App on my iphone using the Nordic UART Service through the Bluefruit wrap developed by Adafruit.
The below pictures show:
- the device is being recognized by the app
- shows the Nordic UART Service present
At this point many tutorials show that you are able to send serial bytes from the app to the module through some sort of input menu however for myself this is not the case. (one example of a tutorial is here: https://how2electronics.com/send-receive-data-to-mobile-app-with-xiao-ble-nrf52840-sense/) I try to click on the Nordic uart service box and nothing happens.
The below is the basic code I am using to develop for the nodule in the Arduino IDE:
#include <bluefruit.h>
BLEUart bleuart; // BLE UART service
void setup() {
Serial.begin(115200);
Bluefruit.begin();
Bluefruit.setTxPower(4); // Check maximum power is compliant in your region
Bluefruit.setName("XIAO_BLE");
bleuart.begin();
// Start advertising BLE. It will start broadcasting so that we can connect from a phone app
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
Bluefruit.Advertising.addService(bleuart);
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after a connection
}
void loop() {
// Forward messages between Serial and BLE UART
while (bleuart.available()) {
char c = bleuart.read();
Serial.print(c);
}
while (Serial.available()) {
char c = Serial.read();
bleuart.write(c);
}
}
I have tried the premade examples that come with the bluefruit BLE library and the behavior is consistent.
Does anyone have an idea why the app is not allow me to communicate with the module as intended?
Hi there,
Which BSP are you using? and can you post the compiler OUTPUT?
It should work, You must be missing something.
The NUS LIB maybe?
HTH
GL PJ
Hi there,
Try this one first. I think it will show you whats wrong.
It works perfectly.
This code…
/*********************************************************************
This is an example for our nRF52 based Bluefruit LE modules
Pick one up today in the adafruit shop!
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
MIT license, check LICENSE for more information
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/
/*
* This sketch demonstrate how to run both Central and Peripheral roles
* at the same time. It will act as a relay between an central (mobile)
* to another peripheral using bleuart service.
*
* Mobile <--> DualRole <--> peripheral Ble Uart
*/
#include <bluefruit.h>
// OTA DFU service
BLEDfu bledfu;
// Peripheral uart service
BLEUart bleuart;
// Central uart client
BLEClientUart clientUart;
void setup()
{
Serial.begin(115200);
while ( !Serial ) delay(10); // for nrf52840 with native usb
Serial.println("Bluefruit52 Dual Role BLEUART Example");
Serial.println("-------------------------------------\n");
// Initialize Bluefruit with max concurrent connections as Peripheral = 1, Central = 1
// SRAM usage required by SoftDevice will increase with number of connections
Bluefruit.begin(1, 1);
Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
// Callbacks for Peripheral
Bluefruit.Periph.setConnectCallback(prph_connect_callback);
Bluefruit.Periph.setDisconnectCallback(prph_disconnect_callback);
// Callbacks for Central
Bluefruit.Central.setConnectCallback(cent_connect_callback);
Bluefruit.Central.setDisconnectCallback(cent_disconnect_callback);
// To be consistent OTA DFU should be added first if it exists
bledfu.begin();
// Configure and Start BLE Uart Service
bleuart.begin();
bleuart.setRxCallback(prph_bleuart_rx_callback);
// Init BLE Central Uart Serivce
clientUart.begin();
clientUart.setRxCallback(cent_bleuart_rx_callback);
/* Start Central Scanning
* - Enable auto scan if disconnected
* - Interval = 100 ms, window = 80 ms
* - Filter only accept bleuart service
* - Don't use active scan
* - Start(timeout) with timeout = 0 will scan forever (until connected)
*/
Bluefruit.Scanner.setRxCallback(scan_callback);
Bluefruit.Scanner.restartOnDisconnect(true);
Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms
Bluefruit.Scanner.filterUuid(bleuart.uuid);
Bluefruit.Scanner.useActiveScan(false);
Bluefruit.Scanner.start(0); // 0 = Don't stop scanning after n seconds
// Set up and start advertising
startAdv();
}
void startAdv(void)
{
// Advertising packet
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
// Include bleuart 128-bit uuid
Bluefruit.Advertising.addService(bleuart);
// Secondary Scan Response packet (optional)
// Since there is no room for 'Name' in Advertising packet
Bluefruit.ScanResponse.addName();
/* Start Advertising
* - Enable auto advertising if disconnected
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms
* - Timeout for fast mode is 30 seconds
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
*
* For recommended advertising interval
* https://developer.apple.com/library/content/qa/qa1931/_index.html
*/
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
}
void loop()
{
// do nothing, all the work is done in callback
}
/*------------------------------------------------------------------*/
/* Peripheral
*------------------------------------------------------------------*/
void prph_connect_callback(uint16_t conn_handle)
{
// Get the reference to current connection
BLEConnection* connection = Bluefruit.Connection(conn_handle);
char peer_name[32] = { 0 };
connection->getPeerName(peer_name, sizeof(peer_name));
Serial.print("[Prph] Connected to ");
Serial.println(peer_name);
}
void prph_disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void) conn_handle;
(void) reason;
Serial.println();
Serial.println("[Prph] Disconnected");
}
void prph_bleuart_rx_callback(uint16_t conn_handle)
{
(void) conn_handle;
// Forward data from Mobile to our peripheral
char str[20+1] = { 0 };
bleuart.read(str, 20);
Serial.print("[Prph] RX: ");
Serial.println(str);
if ( clientUart.discovered() )
{
clientUart.print(str);
}else
{
bleuart.println("[Prph] Central role not connected");
}
}
/*------------------------------------------------------------------*/
/* Central
*------------------------------------------------------------------*/
void scan_callback(ble_gap_evt_adv_report_t* report)
{
// Since we configure the scanner with filterUuid()
// Scan callback only invoked for device with bleuart service advertised
// Connect to the device with bleuart service in advertising packet
Bluefruit.Central.connect(report);
}
void cent_connect_callback(uint16_t conn_handle)
{
// Get the reference to current connection
BLEConnection* connection = Bluefruit.Connection(conn_handle);
char peer_name[32] = { 0 };
connection->getPeerName(peer_name, sizeof(peer_name));
Serial.print("[Cent] Connected to ");
Serial.println(peer_name);;
if ( clientUart.discover(conn_handle) )
{
// Enable TXD's notify
clientUart.enableTXD();
}else
{
// disconnect since we couldn't find bleuart service
Bluefruit.disconnect(conn_handle);
}
}
void cent_disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void) conn_handle;
(void) reason;
Serial.println("[Cent] Disconnected");
}
/**
* Callback invoked when uart received data
* @param cent_uart Reference object to the service where the data
* arrived. In this example it is clientUart
*/
void cent_bleuart_rx_callback(BLEClientUart& cent_uart)
{
char str[20+1] = { 0 };
cent_uart.read(str, 20);
Serial.print("[Cent] RX: ");
Serial.println(str);
if ( bleuart.notifyEnabled() )
{
// Forward data from our peripheral to Mobile
bleuart.print( str );
}else
{
// response with no prph message
clientUart.println("[Cent] Peripheral role not connected");
}
}
Looks like this
Pick you fav Hex to ascii converter
Upload and scan for the Xiao , Connect and get to the service.
Send it…
HTH
GL
PJ
compiler output…BTW
FQBN: Seeeduino:nrf52:xiaonRF52840Sense
Using board 'xiaonRF52840Sense' from platform in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1
Using core 'nRF5' from platform in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1
Detecting libraries used...
__Bedit__
Multiple libraries were found for "Adafruit_TinyUSB.h"
Used: D:\Arduino_projects\libraries\Adafruit_TinyUSB_Library
Not used: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\Adafruit_TinyUSB_Arduino
Using library Adafruit Bluefruit nRF52 Libraries at version 0.21.0 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\Bluefruit52Lib
Using library Adafruit nRFCrypto at version 0.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\Adafruit_nRFCrypto
Using library Adafruit TinyUSB Library at version 3.1.3 in folder: D:\Arduino_projects\libraries\Adafruit_TinyUSB_Library
Using library SPI at version 1.0 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\SPI
Using library Adafruit Little File System Libraries at version 0.11.0 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\Adafruit_LittleFS
Using library Adafruit Internal File System on Bluefruit nRF52 at version 0.11.0 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\InternalFileSytem
"C:\\Users\\Dude\\AppData\\Local\\Arduino15\\packages\\Seeeduino\\tools\\arm-none-eabi-gcc\\9-2019q4/bin/arm-none-eabi-size" -A "C:\\Users\\Dude\\AppData\\Local\\Temp\\arduino\\sketches\\4D606FEDB4977035F48109C0BBCF5BD9/sketch_may12b.ino.elf"
Sketch uses 129780 bytes (16%) of program storage space. Maximum is 811008 bytes.
Global variables use 14996 bytes (6%) of dynamic memory, leaving 222572 bytes for local variables. Maximum is 237568 bytes.
Performing 1200-bps touch reset on serial port COM18
Waiting for upload port...
No upload port found, using COM18 as fallback
"C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1/tools/adafruit-nrfutil/win32/adafruit-nrfutil.exe" --verbose dfu serial -pkg "C:\Users\Dude\AppData\Local\Temp\arduino\sketches\4D606FEDB4977035F48109C0BBCF5BD9/sketch_may12b.ino.zip" -p COM18 -b 115200 --singlebank
Upgrading target on COM18 with DFU package C:\Users\Dude\AppData\Local\Temp\arduino\sketches\4D606FEDB4977035F48109C0BBCF5BD9\sketch_may12b.ino.zip. Flow control is disabled, Single bank, Touch disabled
Opened serial port COM18
Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 129788
Sending DFU start packet
Sending DFU init packet
Sending firmware file
########################################
########################################
########################################
########################################
########################################
########################################
##############
Activating new firmware
Device programmed.
DFU upgrade took 8.139038324356079s