UNO R4 WiFi disconnecting/reconnecting continuously when running sketch w/ "LED_Matrix" and "ArduinoBLE" libraries

I have successfully flashed the firmware 0.2.0 and got bluetoothLE working on the Uno R4 WiFi. I have got the Uno R4 WiFi working as a peripheral and an Nano BLE Sense as a central sending gesture info to the Uno R4 WiFi. via BluetoothLE Everything works as it should.

I decided to use the LED Matrix on the Uno R4 WiFi to show the gesture as an arrow but as soon as I include the matrix in the sketch the Uno R4 WiFi keeps disconnecting and reconnecting continuously. Could it be that there is a conflict between your ArduinoBLE.h and the library Arduino_LED_Matrix.h ?

Hi @steveinaustria. Thanks for beta testing the WIP "ArduinoBLE" library support for the UNO R4 WiFi and for your report!

Which connection are you referring to? Is it the USB connection between the UNO R4 WiFi board and your computer, or is it the BLE connection between the UNO R4 WiFi board and the Nano 33 BLE Sense board?

Please post the full sketch that is producing this disconnecting and reconnecting continuously behavior.

I'll provide instructions you can follow to do that:

  1. Select Tools > Auto Format from the Arduino IDE menus.
    This is done to make the code easier for us to read.
  2. Select Edit > Copy for Forum (Markdown) from the Arduino IDE menus.
  3. In a forum reply here, click on the post composer field.
  4. Press Ctrl+V.
    This will paste the sketch to the post composer.
  5. Move the cursor outside of the code tags before you add any additional text to your reply.
  6. Repeat the above process if your sketch has multiple tabs.
  7. Click the Reply button to post your reply.

When your code requires a library that's not included with the Arduino IDE please post a link to where you downloaded that library from, or if you installed it using Library Manager (Sketch > Include Library > Manage Libraries in Arduino IDE) then say so and state the full name of the library.

I have only just discovered where this post was moved to. I didn't post it as a new topic (afraid I'd be reprimanded for duplicate posting) and it has been given a new title too.

Thanks for your offer of help, please bear with me as I have been working on my script since I first posted the question and I will have to go back and re write it as it was, this will take a few hours. In the meantime I can tell you that the disconnection I was refering to was the BLE connection between the UNO R4 WiFi board and the Nano 33 BLE Sense board. And the libraries used were the "Arduino_LED_Matrix.h" and the Beta verion of the ArduinoBLE library downloaded from https://github.com/facchinm/ArduinoBLE/archive/refs/heads/uno_r4_wifi.zip as recommended by ptillisch here

My posts regarding my experience with the Uno R4 WiFi board are being continually merged, split and reposted under diffent titles, so that even I find them difficult to find now.

I will post the code here later.

Edit: The library "Arduino_LED_Matrix.h" must have been installed with the UNO R4 WiFi board because before I installed the board it wasn't there but afterwards I could call it in the example scripts.

Yes, please start being more careful to use the forum responsibly. You can learn about that subject from this guide:

All your posts are listed under the "Activity" section of your profile:

https://forum.arduino.cc/my/activity

/*
  BLE_Peripheral.ino

  This program uses the ArduinoBLE library to set-up an Arduino Uno R4 Wifi
  as a peripheral device and specifies a service and a characteristic. Depending
  of the value of the specified characteristic, an on-board LED gets on.
*/

#include <ArduinoBLE.h>
#include "Arduino_LED_Matrix.h"


ArduinoLEDMatrix matrix;

enum {
  GESTURE_NONE  = -1,
  GESTURE_UP    = 0,
  GESTURE_DOWN  = 1,
  GESTURE_LEFT  = 2,
  GESTURE_RIGHT = 3
};

const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";

int gesture = -1;

BLEService gestureService(deviceServiceUuid);
BLEByteCharacteristic gestureCharacteristic(deviceServiceCharacteristicUuid, BLERead | BLEWrite);

void setup() {
  Serial.begin(9600);
  matrix.begin();
  //while (!Serial);


  pinMode(LED_BUILTIN, OUTPUT);


  digitalWrite(LED_BUILTIN, LOW);


  if (!BLE.begin()) {
    Serial.println("- Starting Bluetooth® Low Energy module failed!");
    while (1);
  }

  BLE.setLocalName("Arduino Uno R4 WiFi (Peripheral)");
  BLE.setAdvertisedService(gestureService);
  gestureService.addCharacteristic(gestureCharacteristic);
  BLE.addService(gestureService);
  gestureCharacteristic.writeValue(-1);
  BLE.advertise();

  Serial.println("Arduino Uno R4 WiFi (Peripheral Device)");
  Serial.println(" ");
}

void loop() {
  BLEDevice central = BLE.central();
  Serial.println("- Discovering central device...");
  delay(500);

  if (central) {
    Serial.println("* Connected to central device!");
    Serial.print("* Device MAC address: ");
    Serial.println(central.address());
    Serial.println(" ");

    while (central.connected()) {
      if (gestureCharacteristic.written()) {
        gesture = gestureCharacteristic.value();
        writeGesture(gesture);
      }
    }

    Serial.println("* Disconnected to central device!");
  }
}

void writeGesture(int gesture) {
  Serial.println("- Characteristic <gesture_type> has changed!");

  switch (gesture) {
    case 0:
      Serial.println("* Actual value: UP (red LED on)");
      Serial.println(" ");
      digitalWrite(LED_BUILTIN, HIGH);
      break;

    case 1:
      Serial.println("* Actual value: DOWN (green LED on)");
      Serial.println(" ");
      digitalWrite(LED_BUILTIN, LOW);
      break;

    case 2:
      Serial.println("* Actual value: LEFT (blue LED on)");
      Serial.println(" ");
      digitalWrite(LED_BUILTIN, LOW);
      break;

    case 3:
      Serial.println("* Actual value: RIGHT (built-in LED on)");
      Serial.println(" ");
      digitalWrite(LED_BUILTIN, HIGH);
      break;

    default:

      digitalWrite(LED_BUILTIN, LOW);
      break;
  }
}

The above code works and remains connected with the lines ArduinoLEDMatrix matrix; and matrix.begin(); commented out but keeps disconnecting with the lines uncommented.

Hi @steveinaustria - In that example code I don't see any line of code dealing with the LED matrix, maybe you forgot to include them? You said "keeps disconnecting with the lines uncommented" but which lines are you referring to?
We'd need the complete code to be able to reproduce the issue. Thank you!

Please read the comment above made 8 minutes befor your comment. It mentions the the lines which affect the connection which are both to do with the LED matrix. The complete code was posted above my previous comment. I didn't include any calls to the LED matrix as the two lines mentioned were enough to create the problem. Keep it simple is my motto.

For completeness here is the sketch on the NanoBLE Sense:

/*
  BLE_Central_Device.ino

  This program uses the ArduinoBLE library to set-up an Arduino Nano 33 BLE Sense
  as a central device and looks for a specified service and characteristic in a
  peripheral device. If the specified service and characteristic is found in a
  peripheral device, the last detected value of the on-board gesture sensor of
  the Nano 33 BLE Sense, the APDS9960, is written in the specified characteristic.

  The circuit:
  - Arduino Nano 33 BLE Sense.

  This example code is in the public domain.
*/

#include <ArduinoBLE.h>
#include <Arduino_APDS9960.h>



const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";

int gesture = -1;
int oldGestureValue = -1;

void setup() {
  Serial.begin(9600);
  //while (!Serial);
  //pinMode(ledPin, OUTPUT);
  // set the LEDs pins as outputs
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);

  // turn all the LEDs off
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, HIGH);
  if (!APDS.begin()) {
    Serial.println("* Error initializing APDS9960 sensor!");
  }

  APDS.setGestureSensitivity(80);

  if (!BLE.begin()) {
    Serial.println("* Starting Bluetooth® Low Energy module failed!");
    while (1);
  }

  BLE.setLocalName("Nano 33 BLE (Central)");
  BLE.advertise();

  Serial.println("Arduino Nano 33 BLE Sense (Central Device)");
  Serial.println(" ");
}

void loop() {
  connectToPeripheral();
}

void connectToPeripheral() {
  BLEDevice peripheral;

  Serial.println("- Discovering peripheral device...");

  do
  {
    BLE.scanForUuid(deviceServiceUuid);
    peripheral = BLE.available();
  } while (!peripheral);

  if (peripheral) {

    digitalWrite(LEDR, HIGH);
    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDB, LOW);
    Serial.println("* Peripheral device found!");
    Serial.print("* Device MAC address: ");
    Serial.println(peripheral.address());
    Serial.print("* Device name: ");
    Serial.println(peripheral.localName());
    Serial.print("* Advertised service UUID: ");
    Serial.println(peripheral.advertisedServiceUuid());
    Serial.println(" ");
    BLE.stopScan();
    controlPeripheral(peripheral);
  }
}

void controlPeripheral(BLEDevice peripheral) {
  Serial.println("- Connecting to peripheral device...");

  if (peripheral.connect()) {
    Serial.println("* Connected to peripheral device!");
    Serial.println(" ");
  } else {
    Serial.println("* Connection to peripheral device failed!");
    Serial.println(" ");
    return;
  }

  Serial.println("- Discovering peripheral device attributes...");
  if (peripheral.discoverAttributes()) {
    Serial.println("* Peripheral device attributes discovered!");
    Serial.println(" ");
  } else {
    Serial.println("* Peripheral device attributes discovery failed!");
    Serial.println(" ");
    peripheral.disconnect();
    return;
  }

  BLECharacteristic gestureCharacteristic = peripheral.characteristic(deviceServiceCharacteristicUuid);

  if (!gestureCharacteristic) {
    Serial.println("* Peripheral device does not have gesture_type characteristic!");
    peripheral.disconnect();
    return;
  } else if (!gestureCharacteristic.canWrite()) {
    Serial.println("* Peripheral does not have a writable gesture_type characteristic!");
    peripheral.disconnect();
    return;
  }

  while (peripheral.connected()) {
    gesture = gestureDetectection();

    if (oldGestureValue != gesture) {
      oldGestureValue = gesture;
      Serial.print("* Writing value to gesture_type characteristic: ");
      Serial.println(gesture);
      gestureCharacteristic.writeValue((byte)gesture);
      Serial.println("* Writing value to gesture_type characteristic done!");
      Serial.println(" ");
    }

  }
  Serial.println("- Peripheral device disconnected!");
}

int gestureDetectection() {
  if (APDS.gestureAvailable()) {
    gesture = APDS.readGesture();

    switch (gesture) {
      case GESTURE_UP:
        Serial.println("- UP gesture detected");
        break;
      case GESTURE_DOWN:
        Serial.println("- DOWN gesture detected");
        break;
      case GESTURE_LEFT:
        Serial.println("- LEFT gesture detected");
        break;
      case GESTURE_RIGHT:
        Serial.println("- RIGHT gesture detected");
        break;
      default:
        Serial.println("- No gesture detected");
        break;
    }
  }
  return gesture;
}

Hi ptillisch, I have provided everything you requested in your post (auto-formated code for both the peripheral and central devices, library versions, clarification on what is disconnecting etc.) but after 3 days you haven't replied. Sorry if I am being impatient but your asking to see the code etc. gave me hope that their might be a a solution to this problem.

Hi @steveinaustria. I requested this information in order that your feedback as a beta tester will be sufficient to allow the developer who is working on adding the UNO R4 WiFi support to the ArduinoBLE library and those doing code review to make an investigation of your report. I have already notified the developer of your report so no further action is needed for now. The developer might end up needing additional information so please do continue to monitor this forum topic.

Please note that beta phase software is offered solely in order to allow the community the opportunity to participate in the development of this free open source software. If you want to contribute in this manner, that is very welcome, but you should do so only for those purposes. You should not have any expectation that beta phase software is suitable for use in an actual project and you should also not expect us to provide support for use of beta phase software in this manner.

Hi @ptillisch ,
I am seeing the same issue of there being interference between the LEDMatrix library and the ArduinoBLE library.
Both are up-to-date as of a few days ago. BLE is the beta. Arduino radio module firmware was updated a few days ago.
I'm using LightBlue on iOS for testing. Arduino IDE 2.1.1 on MacOS Ventura 13.5

The result is that the characteristic does not show up when LEDMatrix is being used.

There is a very easy repro-case:

  1. Start with the built-in example: ArduinoBLE - Peripheral - LED
  2. Add these 2 lines from the LED_Matrix - DisplaySingleFrame example:
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;

At this point, the characteristic does not show up.
If you then comment out the definition of matrix, the BLE example works properly again.

(I added those 2 lines just after the line that includes ArduinoBLE.h)

I hope that helps.

Thanks,
-Nico

Thanks @ntewinkel! I have notified the developer of your feedback.

1 Like

@ptillisch I am sort of surprised with this:

Its constructor does nothing, although I have not checked yet to see if there are any contained objects that whose constructor does anything.

Now I would not be surprised if started failing if the begin() method was called.
As this starts up timer:
_ledTimer.begin(TIMER_MODE_PERIODIC, type, ch, 10000.0, 50.0, turnOnLedISR, this);
That generates a lot of interrupts per second. Which could be impacting any Serial communications going on between the processor and the ESP32.

I will try to run something like the above test soon, with my updated Serial code to see if it by chance helps or not. On of my current Serial tests has the LED matrix code in it, but only the two lines mentioned, plus simply rotating through each of the LEDS. Did this to let me know if the code was hung or something else wrong with the Serial objects...
Like:

  static uint8_t matrix_led = 0;
  static uint32_t matrix_change_time = 0;
  if ((millis() - matrix_change_time) > 250) {
    matrix.off(matrix_led);
    matrix_led++;
    if (matrix_led == 96) matrix_led = 0;
    matrix.on(matrix_led);
    matrix_change_time = millis();
  }

The other thing with the Arduino_LED_Matrix code, that I wonder about, in an Issue I closed out after... LED_Matrix: possible race condition. · Issue #43 · arduino/ArduinoCore-renesas (github.com)

Specifically these two lines in static void turnLed(int idx, bool on) {

  R_PORT0->PCNTR1 &= ~((uint32_t) LED_MATRIX_PORT0_MASK);
  R_PORT2->PCNTR1 &= ~((uint32_t) LED_MATRIX_PORT2_MASK);

If an interrupt (or higher priority interrupt happens) in between the fetch operation and the store operation, that changes the state of others pins on Port 0 or Port 2, these changes would be stomped on by the store...

I believe additional pins on Port 0 are : A0-A3
On Port 2, there is a pin labeled MD, which goes to the level shifter that communicates with the ESP32.

Not sure if that will give them any more hints on where to look or not, but thought I would mention it.

The issue is most likely with the BLE library, as the same result (missing characteristic) happens with another randomly selected library:

#include "analogWave.h"
analogWave wave(DAC);

@ptillisch @KurtE

1 Like

@ntewinkel you are probably correct, that it is the BLE library, or on things that it depends on. Which why I mentioned Serial in the previous post.

As for analogWave, I have never tried it. I took a quick look, and it's constructor does stuff, but I don't think does anything to throw off timings and the like. Now if you had called some other method that called begin, it creates a timer, uses new for buffers...

But without calling something else in these libraries, that impact timing or use system resources, that BLE needs, it feels like it might be something else, like where things are in memory or potentially memory corruption issue.

But it does add a new top-level object, whose constructor is called by initialization code. Which brings up, a slight possibility.

In the forum thread:
Why does the compiler overwrite 4 bytes with $00 when a string array is initialized? - UNO R4 / UNO R4 WiFi - Arduino Forum

It turned out that there is a memory corruption bug that happens during startup, that did strange things, which may manifest differently depending on what objects are initialized curing startup...

There was a recent PR pulled into the core, to fix this issue.
Merge pull request #86 from facchinm/analog_fix_heap_corruption · arduino/ArduinoCore-renesas@e989e72 (github.com)

Maybe a long shot, but wonder if you use the current cores/analog.cpp that is currently
up on github, does that make any differences to your failure cases using these two libraries?

@KurtE

Maybe a long shot , but wonder if you use the current cores/analog.cpp that is currently
up on github, does that make any differences to your failure cases using these two libraries?

That works!

What are the chances I would randomly pick a library with memory corruption issues as my second test :thinking: :man_facepalming:

I also tried with an Adafruit BMP library, and that's fine too.

So maybe the corruption is not with the BLE library, but with the LED Matrix one?

(I used the latest analog.cpp from Github, and replaced the one in arduino/hardware/renesas_uno/1.0.2/cores/arduino/ )

As a workaround, is it possible to address the matrix LEDs without a library?

Yes - you can address the matrix LED without a library. For example there is the sketch:

Arduino-UNO-R4/R4WiFi_led_matrix/R4WiFi_led_matrix.ino at main · ClemensAtElektor/Arduino-UNO-R4 (github.com)

Where he displays text on the screen, does not use the library.

But I am not sure if that will help with this issue or not. The heap corruption bug, that was recently fixed in analog.cpp, mentioned in the previous post, may be the primary issue.

But as an experiment, if you tried to not create the object at the c++ initialization timeframe it might make a difference. That is instead of:

you have something like:

#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix *matrix;
...
setup() {
   ... 
   matrix = new ArduinoLEDMatrix;
   matrix->begin();
...

It may or may not act differently. Note, all calls to matrix functions would use the -> instead of the . as you are going through a pointer.

Unfortunately your experiment didn't work :frowning: and made no difference to my sketches.