Nano 33 BLE Sense + ESP32 (smart glove)

Hello everybody! I found project of smart glove on instructables made by Matlek.
But I want to receive gesture "Stop" on ESP32 by getting high signal on pin D7 on Nano 33 BLE Sense.
As I understand value of object "ledCharacteristic" is transmitting to ESP32.
I added lines to the code, but it doesn't work so far. I commented out the added lines this way // ***** ADDED string/strings of code ****
I don't even see my added values in the com port monitor. Where am I going wrong?
This is changed code for Nano 33 BLE Sense:

/*
  Smartglove for cyclists: https://www.instructables.com/member/Matlek/
  This code is made for an Arduino Nano 33 BLE Sense board:
  it detects left hand gestures, and sends the gestures information through BLE (to another microcontroller with an LED matrix);
  It is a mix of the following codes, after a few modifications:
    -"LED" example from the "ArduinoBLE" library (Peripheral>LED).
    -"IMU_Classifier" found here: https://github.com/arduino/ArduinoTensorFlowLiteTutorials/blob/master/GestureToEmoji/ArduinoSketches/IMU_Classifier/IMU_Classifier.ino.
*/

#include <ArduinoBLE.h>
#include <Arduino_LSM9DS1.h>
#include <TensorFlowLite.h>
#include <tensorflow/lite/experimental/micro/kernels/all_ops_resolver.h>
#include <tensorflow/lite/experimental/micro/micro_error_reporter.h>
#include <tensorflow/lite/experimental/micro/micro_interpreter.h>
#include <tensorflow/lite/schema/schema_generated.h>
#include <tensorflow/lite/version.h>
#include "model.h"
const float gyroscopeThreshold = 300;
const int numSamples = 64;
int samplesRead = numSamples;
// global variables used for TensorFlow Lite (Micro)
tflite::MicroErrorReporter tflErrorReporter;
// pull in all the TFLM ops, you can remove this line and
// only pull in the TFLM ops you need, if would like to reduce
// the compiled size of the sketch.
tflite::ops::micro::AllOpsResolver tflOpsResolver;
const tflite::Model* tflModel = nullptr;
tflite::MicroInterpreter* tflInterpreter = nullptr;
TfLiteTensor* tflInputTensor = nullptr;
TfLiteTensor* tflOutputTensor = nullptr;
// Create a static memory buffer for TFLM, the size may need to
// be adjusted based on the model you are using
constexpr int tensorArenaSize = 8 * 1024;
byte tensorArena[tensorArenaSize];
// array to map gesture index to a name
const char* GESTURES[] = {
  "Left arm",
  "Brake",
  "Hand front rotation",
  "Hand back rotation",
  "Hand left",
  "Hand right"
};
#define NUM_GESTURES (sizeof(GESTURES) / sizeof(GESTURES[0]))
int nbGesture = 0;
int oldNbGesture = 0;
int gestureTriggered;

//******************** ADDED strings **************************
// variables for button 
const int buttonPin = 7; 
int oldButtonState = LOW;
//******************** ADDED strings **************************


void setup() {
  Serial.begin(115200);
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }
  // print out the samples rates of the IMUs
  Serial.print("Accelerometer sample rate = ");
  Serial.print(IMU.accelerationSampleRate());
  Serial.println(" Hz");
  Serial.print("Gyroscope sample rate = ");
  Serial.print(IMU.gyroscopeSampleRate());
  Serial.println(" Hz");
  Serial.println();
  // get the TFL representation of the model byte array
  tflModel = tflite::GetModel(model);
  if (tflModel->version() != TFLITE_SCHEMA_VERSION) {
    Serial.println("Model schema mismatch!");
    while (1);
  }
  // Create an interpreter to run the model
  tflInterpreter = new tflite::MicroInterpreter(tflModel, tflOpsResolver, tensorArena, tensorArenaSize, &tflErrorReporter);
  // Allocate memory for the model's input and output tensors
  tflInterpreter->AllocateTensors();
  // Get pointers for the model's input and output tensors
  tflInputTensor = tflInterpreter->input(0);
  tflOutputTensor = tflInterpreter->output(0);

  pinMode(22, OUTPUT);
  pinMode(23, OUTPUT);
  pinMode(24, OUTPUT);
  digitalWrite(22, HIGH);
  digitalWrite(23, HIGH);
  digitalWrite(24, HIGH);

//******************** ADDED strings **************************
  // configure the button pin as input
  pinMode(buttonPin, INPUT);
//******************** ADDED strings **************************

  // initialize the BLE hardware
  BLE.begin();
  Serial.println("BLE Central - LED control");

  // start scanning for peripherals
  //BLE.scanForUuid("e4297ee0-8c88-11ea-bc55-0242ac130003");
  BLE.scan();
}

void loop() {
  BLEDevice peripheral = BLE.available();
  if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();
    if (peripheral.localName() != "MySmartglove") {
      return;
    }
    BLE.stopScan();
    // connect to the peripheral
    Serial.println("Connecting ...");

    if (peripheral.connect()) {
      Serial.println("Connected");
    } else {
      Serial.println("Failed to connect!");
      return;
    }

    // discover peripheral attributes
    Serial.println("Discovering attributes ...");
    if (peripheral.discoverAttributes()) {
      Serial.println("Attributes discovered");
    } else {
      Serial.println("Attribute discovery failed!");
      peripheral.disconnect();
      return;
    }

    // retrieve the LED characteristic
    BLECharacteristic ledCharacteristic = peripheral.characteristic("e4297ee1-8c88-11ea-bc55-0242ac130003");

    if (!ledCharacteristic) {
      Serial.println("Peripheral does not have LED characteristic!");
      peripheral.disconnect();
      return;
    } else if (!ledCharacteristic.canWrite()) {
      Serial.println("Peripheral does not have a writable LED characteristic!");
      peripheral.disconnect();
      return;
    }

    while (peripheral.connected()) {
      float aX, aY, aZ, gX, gY, gZ;
      // wait for significant motion
      while (samplesRead == numSamples) {
        if (IMU.gyroscopeAvailable()) {
          IMU.readGyroscope(gX, gY, gZ);
          // sum up the absolutes
          float gSum = fabs(gX) + fabs(gY) + fabs(gZ);
          // check if it's above the threshold
          if (gSum >= gyroscopeThreshold) {
            // reset the sample read count
            samplesRead = 0;
            break;
          }
        }
      }

            
      // check if the all the required samples have been read since
      // the last time the significant motion was detected
      oldNbGesture = nbGesture;
      while (samplesRead < numSamples) {
        // check if new acceleration AND gyroscope data is available
        if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
          // read the acceleration and gyroscope data
          IMU.readAcceleration(aX, aY, aZ);
          IMU.readGyroscope(gX, gY, gZ);
          // normalize the IMU data between 0 to 1 and store in the model's
          // input tensor
          tflInputTensor->data.f[samplesRead * 6 + 0] = (aX + 4.0) / 8.0;
          tflInputTensor->data.f[samplesRead * 6 + 1] = (aY + 4.0) / 8.0;
          tflInputTensor->data.f[samplesRead * 6 + 2] = (aZ + 4.0) / 8.0;
          tflInputTensor->data.f[samplesRead * 6 + 3] = (gX + 2000.0) / 4000.0;
          tflInputTensor->data.f[samplesRead * 6 + 4] = (gY + 2000.0) / 4000.0;
          tflInputTensor->data.f[samplesRead * 6 + 5] = (gZ + 2000.0) / 4000.0;
          samplesRead++;
          if (samplesRead == numSamples) {
            // Run inferencing
            TfLiteStatus invokeStatus = tflInterpreter->Invoke();
            if (invokeStatus != kTfLiteOk) {
              while (1);
              return;
            }
            // Loop through the output tensor values from the model
            for (int i = 0; i < NUM_GESTURES; i++) {
              Serial.print(GESTURES[i]);
              Serial.print(": ");
              Serial.println(tflOutputTensor->data.f[i], 6);
              if ((tflOutputTensor->data.f[i]) > 0.6) {
                gestureTriggered = i;
                nbGesture++;
              }
            }
          }
        }
      }
      Serial.print("The gesture is :");
      Serial.println(GESTURES[gestureTriggered]);
      if (oldNbGesture != nbGesture) {
        if (gestureTriggered == 0) {
          ledCharacteristic.writeValue((byte)0x00);
          colors(0);
        }
        //        if (gestureTriggered == 1) {
        //          ledCharacteristic.writeValue((byte)0x01);
        //          colors(1);
        //        }
        if (gestureTriggered == 2) {
          ledCharacteristic.writeValue((byte)0x02);
          colors(2);
        }
        //********* ADDED string *************
        //comment out these lines of code
        /*
        if (gestureTriggered == 3) {
          ledCharacteristic.writeValue((byte)0x03);
          colors(3);
        }
        */
        if (gestureTriggered == 4) {
          ledCharacteristic.writeValue((byte)0x04);
          colors(4);
        }
        if (gestureTriggered == 5) {
          ledCharacteristic.writeValue((byte)0x05);
          colors(5);
        }
      }

      //******************** ADDED strings **************************
      // read the button pin
      int buttonState = digitalRead(buttonPin);

       if (oldButtonState != buttonState) {
      // button changed
      oldButtonState = buttonState;

      if (buttonState) {
        Serial.println("button pressed");

        // button is pressed, write 0x03 to turn the LED on
         ledCharacteristic.writeValue((byte)0x03);
      } else {
        Serial.println("button released");        
      }
    }
    //******************** ADDED strings **************************

      
    }
    // peripheral disconnected, start scanning again
    //BLE.scanForUuid("e4297ee0-8c88-11ea-bc55-0242ac130003");
    BLE.scan();
  }
}

int colors (int i) {
  if (i == 0) {
    for (int it1 = 0; it1 <= 1; it1++) {
      digitalWrite(22, LOW);
      digitalWrite(23, LOW);
      delay(500);
      digitalWrite(22, HIGH);
      digitalWrite(23, HIGH);
      delay(500);
    }
  }
  if (i == 1) {
    for (int it1 = 0; it1 <= 1; it1++) {
      digitalWrite(22, LOW);
      delay(500);
      digitalWrite(22, HIGH);
      delay(500);
    }
  }
  if (i == 2) {
    digitalWrite(23, LOW);
    delay(500);
    digitalWrite(23, HIGH);
    delay(500);
  }
  if (i == 3) {
    digitalWrite(22, LOW);
    delay(500);
    digitalWrite(22, HIGH);
  }
  if (i == 4) {
    digitalWrite(22, LOW);
    delay(500);
    digitalWrite(23, LOW);
    delay(500);
    digitalWrite(22, HIGH);
    digitalWrite(23, HIGH);
  }
  if (i == 5) {
    digitalWrite(23, LOW);
    delay(500);
    digitalWrite(22, LOW);
    delay(500);
    digitalWrite(22, HIGH);
    digitalWrite(23, HIGH);
  }
}

This is original (unmodified) code for ESP32:

/*
    Smartglove for cyclists: https://www.instructables.com/member/Matlek/
    This code is made for an ESP32 microcontroller, to control an LED matrix through BLE.
    It is a mix of the following codes, after a few modifications:
    -"BLE_Write" example from the "BLE ESP32 ARDUINO" library.
    -"MatrixGFXDemo64" example from the "FastLED NeoMatrix" library.
*/

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
String gestureValue = "0";
int gestureNb = 0;
int old_gestureNb = 0;
BLEServer *pServer = NULL;
bool deviceConnected = false;
unsigned long previousMillis = 0;
const long interval = 1000;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID        "e4297ee0-8c88-11ea-bc55-0242ac130003"
#define CHARACTERISTIC_UUID "e4297ee1-8c88-11ea-bc55-0242ac130003"
#define DISABLE_WHITE
#include <Adafruit_GFX.h>
#include <FastLED_NeoMatrix.h>
#include <FastLED.h>
// Allow temporaly dithering, does not work with ESP32 right now
#ifndef ESP32
#define delay FastLED.delay
#endif
#define PIN 33
#define BRIGHTNESS 64
#define mw 20
#define mh 8
#define NUMMATRIX (mw*mh)
CRGB leds[NUMMATRIX];
// Define matrix width and height.
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, mw, mh,
    NEO_MATRIX_BOTTOM     + NEO_MATRIX_RIGHT +
    NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG);

void matrix_show() {
  matrix->show();
}

// This could also be defined as matrix->color(255,0,0) but those defines
// are meant to work for adafruit_gfx backends that are lacking color()
#define LED_BLACK    0

#define LED_RED_VERYLOW   (3 <<  11)
#define LED_RED_LOW     (7 <<  11)
#define LED_RED_MEDIUM    (15 << 11)
#define LED_RED_HIGH    (31 << 11)

#define LED_GREEN_VERYLOW (1 <<  5)
#define LED_GREEN_LOW     (15 << 5)
#define LED_GREEN_MEDIUM  (31 << 5)
#define LED_GREEN_HIGH    (63 << 5)

#define LED_BLUE_VERYLOW  3
#define LED_BLUE_LOW    7
#define LED_BLUE_MEDIUM   15
#define LED_BLUE_HIGH     31

#define LED_ORANGE_VERYLOW  (LED_RED_VERYLOW + LED_GREEN_VERYLOW)
#define LED_ORANGE_LOW    (LED_RED_LOW     + LED_GREEN_LOW)
#define LED_ORANGE_MEDIUM (LED_RED_MEDIUM  + LED_GREEN_MEDIUM)
#define LED_ORANGE_HIGH   (LED_RED_HIGH    + LED_GREEN_HIGH)

#define LED_PURPLE_VERYLOW  (LED_RED_VERYLOW + LED_BLUE_VERYLOW)
#define LED_PURPLE_LOW    (LED_RED_LOW     + LED_BLUE_LOW)
#define LED_PURPLE_MEDIUM (LED_RED_MEDIUM  + LED_BLUE_MEDIUM)
#define LED_PURPLE_HIGH   (LED_RED_HIGH    + LED_BLUE_HIGH)

#define LED_CYAN_VERYLOW  (LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_CYAN_LOW    (LED_GREEN_LOW     + LED_BLUE_LOW)
#define LED_CYAN_MEDIUM   (LED_GREEN_MEDIUM  + LED_BLUE_MEDIUM)
#define LED_CYAN_HIGH   (LED_GREEN_HIGH    + LED_BLUE_HIGH)

#define LED_WHITE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_WHITE_LOW   (LED_RED_LOW     + LED_GREEN_LOW     + LED_BLUE_LOW)
#define LED_WHITE_MEDIUM  (LED_RED_MEDIUM  + LED_GREEN_MEDIUM  + LED_BLUE_MEDIUM)
#define LED_WHITE_HIGH    (LED_RED_HIGH    + LED_GREEN_HIGH    + LED_BLUE_HIGH)

void matrix_clear() {
  // clear does not work properly with multiple matrices connected via parallel inputs
  memset(leds, 0, sizeof(leds));
}

void ScrollText_Left() {
  matrix_clear();
  matrix->setTextWrap(false);  // we don't wrap text so it scrolls nicely
  matrix->setTextSize(1);
  matrix->setRotation(0);
  for (int8_t x = 0; x >= -60; x--) {
    yield();
    matrix_clear();
    matrix->setCursor(x, 0);
    matrix->setTextColor(LED_ORANGE_HIGH);
    matrix->print("<<<<<<<<<<<<<<");
    matrix_show();
    delay(50);
  }
  matrix->setCursor(0, 0);
}

void ScrollText_Merci() {
  matrix_clear();
  matrix->setTextWrap(false);  // we don't wrap text so it scrolls nicely
  matrix->setTextSize(1);
  matrix->setRotation(0);
  for (int8_t x = 20; x >= -30; x--) {
    yield();
    matrix_clear();
    matrix->setCursor(x, 0);
    matrix->setTextColor(LED_PURPLE_HIGH);
    matrix->print("Merci");
    matrix_show();
    delay(70);
  }
  matrix->setCursor(0, 0);
}

void ScrollText_Hello() {
  matrix_clear();
  matrix->setTextWrap(false);  // we don't wrap text so it scrolls nicely
  matrix->setTextSize(1);
  matrix->setRotation(0);
  for (int8_t x = 20; x >= -30; x--) {
    yield();
    matrix_clear();
    matrix->setCursor(x, 0);
    matrix->setTextColor(LED_CYAN_HIGH);
    matrix->print("Hello!");
    matrix_show();
    delay(70);
  }
  matrix->setCursor(0, 0);
}

void ScrollText_Right() {
  matrix_clear();
  matrix->setTextWrap(false);  // we don't wrap text so it scrolls nicely
  matrix->setTextSize(1);
  matrix->setRotation(0);
  for (int8_t x = -60; x <= 0 ; x++) {
    yield();
    matrix_clear();
    matrix->setCursor(x, 0);
    matrix->setTextColor(LED_ORANGE_HIGH);
    matrix->print(">>>>>>>>>>>>>>");
    matrix_show();
    delay(50);
  }
  matrix->setCursor(0, 0);
}

void ScrollText_Wait() {
  matrix_clear();
  matrix->setTextWrap(false);  // we don't wrap text so it scrolls nicely
  matrix->setTextSize(1);
  matrix->setRotation(0);
  yield();
  matrix_clear();
  matrix->setCursor(2, 0);
  matrix->setTextColor(LED_ORANGE_HIGH);
  matrix->print("o");
  matrix_show();
  delay(500);
  yield();
  matrix_clear();
  matrix->setCursor(2, 0);
  matrix->setTextColor(LED_ORANGE_HIGH);
  matrix->print("oo");
  matrix_show();
  delay(500);
  yield();
  matrix_clear();
  matrix->setCursor(2, 0);
  matrix->setTextColor(LED_ORANGE_HIGH);
  matrix->print("ooo");
  matrix_show();
  delay(500);
  yield();
  matrix_clear();
  matrix->setCursor(0, 0);
  matrix->setTextColor(LED_BLACK);
  matrix_show();
  delay(500);
}

void ScrollText_Stop() {
  matrix_clear();
  matrix->setTextWrap(false);  // we don't wrap text so it scrolls nicely
  matrix->setTextSize(1);
  matrix->setRotation(0);
  yield();
  matrix_clear();
  matrix->setCursor(2, 0);
  matrix->setTextColor(LED_RED_HIGH);
  matrix->print("!!!");
  matrix_show();
  delay(1000);
  yield();
  matrix_clear();
  matrix->setCursor(0, 0);
  matrix->setTextColor(LED_BLACK);
  matrix->print("STOP");
  matrix_show();
  delay(500);
}

void ScrollText_Straight() {
  uint8_t size = max(int(mw / 8), 1);
  matrix->setRotation(3);
  matrix->setTextSize(size);
  matrix->setTextColor(LED_GREEN_HIGH);
  for (int16_t x = -10; x <= 6; x++) {
    yield();
    matrix_clear();
    matrix->setCursor(x, ((mw / 2 - size * 4) + 1));
    matrix->print(">");
    matrix_show();
    delay(100 / size);
  }
  matrix->setRotation(0);
  matrix->setCursor(0, 0);
  matrix_show();
}

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("      deviceConnected = true;");
    };
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("      deviceConnected = false;");
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    //public:
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      if (value.length() > 0) {
          gestureValue = int(value[0]);
        gestureNb++;
      }
    }
};

void setup() {
  Serial.begin(115200);
  FastLED.addLeds<NEOPIXEL, PIN>(  leds, NUMMATRIX  ).setCorrection(TypicalLEDStrip);
  delay(1000);
  matrix->begin();
  matrix->setTextWrap(false);
  matrix->setBrightness(BRIGHTNESS);
#ifndef DISABLE_WHITE
  matrix->fillScreen(LED_WHITE_HIGH);
  matrix_show();
  delay(5000);
  matrix_clear();
#endif
  BLEDevice::init("MySmartglove");
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setCallbacks(new MyCallbacks());
  //pCharacteristic->setValue("Hello World");
  pService->start();
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {

  if (deviceConnected) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      ScrollText_Straight();
    }
      Serial.print("gestureValue : ");
      Serial.println(gestureValue);
    if (gestureNb != old_gestureNb)
    {

      if (gestureValue == "0" || gestureValue == "4") {
        ScrollText_Left();
      }
      if (gestureValue == "5") {
        ScrollText_Right();
      }
      if (gestureValue == "3") {
        ScrollText_Stop();
      }
      if (gestureValue == "2") {
        ScrollText_Merci();
      }
      old_gestureNb = gestureNb;
    }
  }
  if (!deviceConnected) {
    ScrollText_Wait();
    pServer->startAdvertising(); // restart advertising
  }
}

This is photo of connection tact switch to Nano 33 BLE Sense.