Hello
I'm Strangistra and I work on a Adafruit Feather nrf52832.
I have the Arduino IDE 1.8.13 and I use the FastLed library 3.3.3.
I have a strange behavior with the Bluetooth connection.
I have a code to drive 4 RGB leds strips. For this I used the FastLed library and the MultiArray exemple.
#include <FastLED.h>
#define NUM_LEDS_PER_STRIP 12
CRGB redLeds[NUM_LEDS_PER_STRIP];
CRGB greenLeds[NUM_LEDS_PER_STRIP];
CRGB blueLeds[NUM_LEDS_PER_STRIP];
// For mirroring strips, all the "special" stuff happens just in setup. We
// just addLeds multiple times, once for each strip
void setup() {
Serial.begin(115200);
FastLED.addLeds<SK6812,A0,GRB>(redLeds,NUM_LEDS_PER_STRIP);
FastLED.addLeds<SK6812,A1,GRB>(greenLeds, NUM_LEDS_PER_STRIP);
FastLED.addLeds<SK6812,A2,GRB>(blueLeds, NUM_LEDS_PER_STRIP);
FastLED.addLeds<SK6812,A3,GRB>(blueLeds, NUM_LEDS_PER_STRIP);
}
void loop() {
for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
// set our current dot to red, green, and blue
redLeds[i] = CRGB::Red;
greenLeds[i] = CRGB::Green;
blueLeds[i] = CRGB::Blue;
FastLED.show();
// clear our current dot before we move on
redLeds[i] = CRGB::Black;
greenLeds[i] = CRGB::Black;
blueLeds[i] = CRGB::Black;
delay(100);
}
for(int i = NUM_LEDS_PER_STRIP-1; i >= 0; i--) {
// set our current dot to red, green, and blue
redLeds[i] = CRGB::Red;
greenLeds[i] = CRGB::Green;
blueLeds[i] = CRGB::Blue;
FastLED.show();
// clear our current dot before we move on
redLeds[i] = CRGB::Black;
greenLeds[i] = CRGB::Black;
blueLeds[i] = CRGB::Black;
delay(100);
}
}
This code work correcly.
Now I add this code on the Adafruit Dual_Bleuart exemple :
#include <bluefruit.h>
#include <FastLED.h>
#define NUM_LEDS_PER_STRIP 12
CRGB redLeds[NUM_LEDS_PER_STRIP];
CRGB greenLeds[NUM_LEDS_PER_STRIP];
CRGB blueLeds[NUM_LEDS_PER_STRIP];
// 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(-12); // Check bluefruit.h for supported values
Bluefruit.setName("Bluefruit52 duo");
// 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(true);
Bluefruit.Scanner.start(0); // 0 = Don't stop scanning after n seconds
// Set up and start advertising
startAdv();
FastLED.addLeds<SK6812,A0,GRB>(redLeds,NUM_LEDS_PER_STRIP);
FastLED.addLeds<SK6812,A1,GRB>(greenLeds, NUM_LEDS_PER_STRIP);
FastLED.addLeds<SK6812,A2,GRB>(blueLeds, NUM_LEDS_PER_STRIP);
FastLED.addLeds<SK6812,A3,GRB>(blueLeds, NUM_LEDS_PER_STRIP);
}
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()
{
for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
// set our current dot to red, green, and blue
redLeds[i] = CRGB::Red;
greenLeds[i] = CRGB::Green;
blueLeds[i] = CRGB::Blue;
FastLED.show();
// clear our current dot before we move on
redLeds[i] = CRGB::Black;
greenLeds[i] = CRGB::Black;
blueLeds[i] = CRGB::Black;
delay(100);
}
for(int i = NUM_LEDS_PER_STRIP-1; i >= 0; i--) {
// set our current dot to red, green, and blue
redLeds[i] = CRGB::Red;
greenLeds[i] = CRGB::Green;
blueLeds[i] = CRGB::Blue;
FastLED.show();
// clear our current dot before we move on
redLeds[i] = CRGB::Black;
greenLeds[i] = CRGB::Black;
blueLeds[i] = CRGB::Black;
delay(100);
}
}
/*------------------------------------------------------------------*/
/* 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");
}
}
The Bluetooth connection don't work with this code. And the strange behavior is when I deactivate one strip led initialization, after this manipulation the Bluetooth function work correctly.
//FastLED.addLeds<SK6812,A0,GRB>(redLeds,NUM_LEDS_PER_STRIP);
I don't understand why the Bluetooth connection don't work when I have 4 RGB leds strips initialized?
I tested multiple pins(A5, 7, 30) and the result is same. When I define 3 RGB leds strips, the code and the Bluetooth connection work correctly but if I define one other led strip in this case the Bluetooth connection don't work.
I give a precision. I find the feather with Adafruit Bluefruit connect application but when I select Connect, after I have the message "Connecting..." and the result finish by a error message "Error to connecting to peripheral".
I tested to write a similar code without FastLed but with NeoPixel and in this case the code and the Bluetooth connection work correctly :
/*********************************************************************
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;
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 6 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 12 // Popular NeoPixel ring size
// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels1(NUMPIXELS, A0, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels2(NUMPIXELS, A1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels3(NUMPIXELS, A2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels4(NUMPIXELS, A3, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
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
Bluefruit.setName("Bluefruit52 duo");
// 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();
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels1.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels2.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels3.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels4.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}
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()
{
pixels1.clear(); // Set all pixel colors to 'off'
pixels2.clear(); // Set all pixel colors to 'off'
pixels3.clear(); // Set all pixel colors to 'off'
pixels4.clear(); // Set all pixel colors to 'off'
// The first NeoPixel in a strand is #0, second is 1, all the way up
// to the count of pixels minus one.
for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
// Here we're using a moderately bright green color:
pixels1.setPixelColor(i, pixels1.Color(255, 255, 0));
pixels2.setPixelColor(i, pixels2.Color(0, 255, 0));
pixels3.setPixelColor(i, pixels3.Color(255, 0, 0));
pixels4.setPixelColor(i, pixels4.Color(0, 0, 255));
pixels1.show(); // Send the updated pixel colors to the hardware.
pixels2.show(); // Send the updated pixel colors to the hardware.
pixels3.show(); // Send the updated pixel colors to the hardware.
pixels4.show(); // Send the updated pixel colors to the hardware.
delay(DELAYVAL); // Pause before next pass through loop
}
}
/*------------------------------------------------------------------*/
/* 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");
}
}
Have you already see this strange issue?