Connecting Arduino nano 33 IOT and arduino uno wifi rev 2

The goal of this project is to control a robotic hand wirelessly using sensor data from another device. The robotic hand has five fingers, each actuated by a servo motor, and the finger positions are determined by sensor readings.

We believe we have correctly connected the two Arduinos via BLE. The values appear correct when printed from the peripheral; however, when sent to the central, they are always read as 0. We are not exactly sure where the problem occurs. Any advice would be great!

#include <ArduinoBLE.h>

BLEService sensorService("180C");                     
BLECharacteristic sensorCharacteristic("2A56", BLERead | BLENotify, 20); 

uint8_t rawData[5];

const int littlef = A0; //little finger pin
const int ringf = A1; //ring finger pin
const int longf = A2; //long finger pin
const int indexf = A3; //index finger pin
const int thumb = A4; //thumb finger pin

int little_value;
int ring_value;
int long_value;
int index_value;
int thumb_value;
int Sa;
int Sb;
int Sc;
int Sd;
int Se;

float smooth_little;
float smooth_ring;
float smooth_long;
float smooth_index;
float smooth_thumb;

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

  if (!BLE.begin()) {
    Serial.println("BLE failed to start!");
    while (1);
  }

  BLE.setLocalName("test4");
  
  sensorService.addCharacteristic(sensorCharacteristic);
  BLE.addService(sensorService);
  BLE.advertise();
  Serial.println("Advertising...");
  BLE.scan();
}

void loop() {
  
  BLEDevice central = BLE.available();
  Serial.println("51");
  Serial.println(central.address());
  //BLE.address();
  
  if (central) {
    Serial.print("Connected to central: ");
    Serial.println(central.address());

    // if (central.connect()) {
    //   Serial.println("lin 62");
    // }

    while (central) {
      //BLE.poll();
      delay(20);
    

      // readSensors(sensorData);
      smooth_little = 0.85 * smooth_little + 0.15 * analogRead(littlef); //little finger;
      smooth_ring = 0.85 * smooth_ring + 0.15 * analogRead(ringf); //ring finger 
      smooth_long = 0.85 * smooth_long + 0.15 * analogRead(longf);
      smooth_index = 0.85 * smooth_index + 0.15 * analogRead(indexf);
      smooth_thumb = 0.85 * smooth_thumb + 0.15 * analogRead(thumb);

      Sa = map(smooth_little, 520, 640, 50, 120); //little finger
      Sb = map(smooth_ring, 520, 680, 50, 120); //ring finger 
      Sc = map(smooth_long, 620, 770, 50, 120); //long finger
      Sd = map(smooth_index, 530, 730, 50, 120); //index finger
      Se = map(smooth_thumb, 520, 630, 50, 120); //thumb finger

      rawData[0] = constrain(Sa, 0, 255);
      rawData[1] = constrain(Sb, 0, 255);
      rawData[2] = constrain(Sc, 0, 255);
      rawData[3] = constrain(Sd, 0, 255);
      rawData[4] = constrain(Se, 0, 255);
      Serial.print(rawData[4]); Serial.print(", ");

      sensorCharacteristic.writeValue(rawData, sizeof(rawData));

      delay(200);
      } 
  }
  Serial.println("disconnected");
  delay(2000);
}
      
#include <ArduinoBLE.h>
#include <Servo.h>

BLECharacteristic sensorCharacteristic;

Servo Saservo; // tumme
Servo Sbservo; // index
Servo Scservo; // middle
Servo Sdservo; // ring
Servo Seservo;// little
uint8_t angle[5];

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

  Saservo.attach(8);  // thumb servo
  Sbservo.attach(9);  // index finger servo
  Scservo.attach(10); // middle finger servo
  Sdservo.attach(11); // ring finger servo
  Seservo.attach(12); // little finger servo

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

void loop() {
  BLEDevice peripheral = BLE.available();

  if (peripheral) {
    if (peripheral.hasLocalName() && peripheral.localName() == "test4") {
      Serial.println("Discovered a peripheral");
      Serial.println("-----------------------");
      Serial.print("Address: ");
      Serial.println(peripheral.address());
      Serial.print("Local Name: ");
      Serial.println(peripheral.localName());
      Serial.println(" ");

      if (peripheral.connect()) {
        Serial.println("55")
        peripheral.discoverAttributes();
        sensorCharacteristic = peripheral.characteristic("2A56");

        sensorCharacteristic.subscribe();
 
        while (peripheral.connected()) {
          //if (sensorCharacteristic.canRead()) {
          
          // Reads angles sent via BLE
          sensorCharacteristic.readValue(angle, sizeof(angle));
          Serial.println(angle[4]);

          // Write angles to the robotic hand (with range checks)
          if (0 <= angle[4] && angle[4] <= 170) {
            Saservo.write(angle[4]);
          }
          if (0 <= angle[3] && angle[3] <= 170) {
            Sbservo.write(angle[3]);
          }
          if (0 <= angle[2] && angle[2] <= 170) {
            Scservo.write(angle[2]);
          }
          if (0 <= angle[1] && angle[1] <= 170) {
            Sdservo.write(angle[1]);
          }
          if (0 <= angle[0] && angle[0] <= 140) {
            // little finger offset by +40
            int degree = angle[0] + 40;
            Seservo.write(degree);
          }
          delay(300);
        }   
      }
    }
  }
}  

Although not the problem, you should name thumb as thumbf (analog input A4) to follow the naming of the other (f)ingers.

This is the only data you print on the remote (hand control) and send to the host. Does the little finger move?

... which means to me "only print/send the fifth element of `rawData[]`" Disregard... it loads the array of five elements.

When we print the raw data from the peripheral we get various values that seem correct but nothing happens on the central side becuase it never enters this part of the code (it never prints 55):

if (peripheral.connect()) {
        Serial.println("55")
        peripheral.discoverAttributes();
        sensorCharacteristic = peripheral.characteristic("2A56");

One thing I tried was to write the code as below instead. This was the only way to get to the point of the central code that prints the raw data but in this case the problem was that raw data was just 0.

void loop() {
  BLEDevice peripheral = BLE.available();

  if (peripheral) {
    if (peripheral.hasLocalName() && peripheral.localName() == "test4") {
      Serial.println("Discovered a peripheral");
      Serial.println("-----------------------");
      Serial.print("Address: ");
      Serial.println(peripheral.address());
      Serial.print("Local Name: ");
      Serial.println(peripheral.localName());
      Serial.println(" ");

      // Chaned from if (peripheral.connect()) to if (peripheral)
      if (peripheral) {
        Serial.println("55")
        peripheral.discoverAttributes();
        sensorCharacteristic = peripheral.characteristic("2A56");

        sensorCharacteristic.subscribe();

        // Chaned from while (peripheral.connected()) to while (peripheral)
        while (peripheral) {
          
          sensorCharacteristic.readValue(angle, sizeof(angle));
          Serial.println(angle[4]);

          // Write angles to the robotic hand (with range checks)
          if (0 <= angle[4] && angle[4] <= 170) {
            Saservo.write(angle[4]);
          }
          if (0 <= angle[3] && angle[3] <= 170) {
            Sbservo.write(angle[3]);
          }
          if (0 <= angle[2] && angle[2] <= 170) {
            Scservo.write(angle[2]);
          }
          if (0 <= angle[1] && angle[1] <= 170) {
            Sdservo.write(angle[1]);
          }
          if (0 <= angle[0] && angle[0] <= 140) {
            // little finger offset by +40
            int degree = angle[0] + 40;
            Seservo.write(degree);
          }
          delay(300);
        }   
      }
    }
  }
} 

Another thing I do not really understand is if "if (sensorCharacteristic.canRead()) {" needs to be used and if so where?

Thank you!

Have you verified the peripheral with a standard app like LightBlue or nrfConnect?