Connecting two Arduino Nano 33 IoTs via BLE to send Accelerometer Z data

Hello,

I am attempting to connect two nano 33 IoT devices, with the peripheral sending the Z accelerometer data from the nano's built-in accelerometer to the central device. However, the devices aren't connecting to each other at all. I've looked at a lot of forums and can't seem to find what I'm doing wrong. This is my first project with Arduino, so apologies for whatever dumb mistake I'm making.

Peripheral:

/*
 * Device: Arduino Nano 33 BLE Sense
 * Peripheral
 * The values of the integrated temperature sensor and 
 * accelerometer are sent using BLE.
 */

#include <ArduinoBLE.h>
#include <Arduino_LSM6DS3.h> //accelerometer sensor

int const d_a=2; //number of decimal to keep for the accelerometer

float xSensor=0;
float ySensor=0;
float zSensor=0;

//integer variable to send via BLE

int zBLE=zSensor*pow(10,d_a);

BLEService SensorService("1101");

BLEUnsignedIntCharacteristic ZChar("2103", BLERead | BLENotify);

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

//  if (!HTS.begin()){
//    Serial.println("Failed to start the HTS221 sensor.");
//    while(1);
//
//  if (!IMU.begin()) {
//    Serial.println("Failed to start the LSM9DS sensor.");
//    while (1);

pinMode(LED_BUILTIN, OUTPUT);

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

BLE.setLocalName("Arduino Z (peripheral)");
BLE.setAdvertisedService(SensorService);
SensorService.addCharacteristic(ZChar);
BLE.addService(SensorService);

ZChar.writeValue(zBLE);

BLE.advertise();

Serial.println("Arduino Z peripheral device is now active, waiting for connections...");
}


void loop() {

BLEDevice central = BLE.central();
if (central) {
Serial.print("Connected to central: ");
Serial.print("* Device MAC address: ");
Serial.println(central.address());
Serial.println(" ");

digitalWrite(LED_BUILTIN, HIGH);

while (central.connected()) {
//delay(200);
//read_sensor();
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(xSensor, ySensor, zSensor);
}


Serial.print("xSensor ");
Serial.print(xSensor);
Serial.print(" - ySensor ");
Serial.print(ySensor);
Serial.print(" - zSensor ");
Serial.print(zSensor);



zBLE=zSensor*pow(10,d_a);

//int t_i=t_f*100;
//int x_i=x_f*100;
//int y_i=y_f*100;
//int z_i=z_f*100;

//writeCharacteristicValue (Tchar, Xchar, Ychar, Zchar);


ZChar.writeValue(zBLE);
//Serial.println("At Main Function");

Serial.print(" - ZChar ");
Serial.print(ZChar);

Serial.println("");
Serial.println("");
//Serial.println("");
//Serial.println("");

delay(1000);

}
}
//else {
delay(800);
//}
digitalWrite(LED_BUILTIN, LOW);
delay(100);
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);

Serial.print("Disconnected from central: ");
Serial.println(central.address());
BLE.advertise();
}

//void read_sensor(){
//if (IMU.accelerationAvailable()) {
//IMU.readAcceleration(x_f, y_f, z_f);
//}
//t_f=HTS.readTemperature();
//
//Serial.print("x_f ");
//Serial.print(x_f);
//Serial.print(" - y_f ");
//Serial.print(y_f);
//Serial.print(" - z_f ");
//Serial.print(z_f);
//Serial.print(" - t_f ");
//Serial.println(t_f);
//Serial.println("");
////x_i=x_f*pow(10,d);
////y_i=y_f*pow(10,d);
////z_i=z_f*pow(10,d);
////t_i=t_f*pow(10,d);
//
//int t_i=t_f;
//int x_i=x_f;
//int y_i=y_f;
//int z_i=z_f;
//
//Serial.print("x_i ");
//Serial.print(x_i);
//Serial.print(" - y_i ");
//Serial.print(y_i);
//Serial.print(" - z_i ");
//Serial.print(z_i);
//Serial.print(" - t_i ");
//Serial.println(t_i);
//Serial.println("");
//}

Central:

/*
  BLE_Central_Device.ino

 /*
 * Device: Arduino Nano 33 BLE Sense
 * Central
 * The values of the integrated temperature sensor and 
 * accelerometer of another Nano 33 BLE are received using BLE.
 */

#include <ArduinoBLE.h>

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

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

  BLE.setLocalName("Arduino Z (Central)"); 
  Serial.println("Arduino Z (Central)");
  Serial.println(" ");

  pinMode(LED_BUILTIN, OUTPUT);

  //BLE.advertise();
  
}

void loop() {
 // BLE.scan();
 BLEDevice peripheral;

 Serial.println("- Discovering peripheral device...");
digitalWrite(LED_BUILTIN, HIGH);
  do
  {
    BLE.scanForUuid("1101");
    peripheral = BLE.available();
  } while (!peripheral);

  if (peripheral) {
    digitalWrite(LED_BUILTIN, LOW);

    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();
    
//    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();

    if (peripheral.localName() == "Arduino Z (peripheral)") {
      // stop scanning
      BLE.stopScan();
      
      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;
      }
      
     // read and print device name of peripheral
     Serial.println();
     Serial.print("Device name: ");
     Serial.println(peripheral.deviceName());
     Serial.print("Appearance: 0x");
     Serial.println(peripheral.appearance(), HEX);
     Serial.println();
     }

  while (peripheral.connect()) {
  
    //BLECharacteristic TChar = peripheral.characteristic( "2104" );
      BLEService service = peripheral.service("1101");
    Serial.print("Service ");
    Serial.print(service.uuid());
    
    BLECharacteristic Zchar = service.characteristic("2103");
    //readCharacteristicValue(characteristic);
    Serial.print("\tZ characteristic ");
    Serial.print(Zchar.uuid());
    // check if the characteristic is readable
    if (Zchar.canRead()) {
      //read the characteristic value
      int32_t z = 0;
      Zchar.readValue(&z,4);
      Serial.print(", z = ");
      Serial.println((float)z/100.0);
    }

    
    delay(1000);
    }


    
//    } else {
//    Serial.println("* Connection to peripheral device failed!");
//    Serial.println(" ");
//    return;
    }
   // Serial.println("Disconnected from peripheral: ");
}

void readCharacteristicValue(BLECharacteristic characteristic) {
  // print the UUID and properties of the characteristic
  Serial.print("\tCharacteristic ");
  Serial.print(characteristic.uuid());
  // check if the characteristic is readable
  if (characteristic.canRead()) {
    // read the characteristic value
    characteristic.read();

    if (characteristic.valueLength() > 0) {
      Serial.print(", value = ");
      //characteristic.value() returns byte array
      unsigned long bitShiftData = 0;
      bitShiftData = (uint32_t)characteristic.value()[3] << 24 | (uint32_t)characteristic.value()[2] << 16 | (uint32_t)characteristic.value()[1] << 8 | characteristic.value()[0];
      Serial.println(bitShiftData, DEC);
      Serial.print(bitShiftData / 100);
      Serial.print('.');
      if (bitShiftData % 100 < 10)
        Serial.print('0');
      Serial.println(bitShiftData % 100);
    }
  }
}

The framework for this code I took from this forum:

Any help is appreciated. Thank you.

The best way to start when you are new is to work through some of the example sketches included with the library you are working with, in your case the BLE and LSM6DS3. I would learn BLE first, then add in the closest matching sensor code.

I can not confirm your findings. I have Nano33 BLE's, so I changed the peripheral code to use the LSM9DS1 which is on my device.

When I just test the peripheral with LightBlue or nrfConnect phone apps, I can connect with the peripheral and given my orientation, read a Z axis data of .98.

When I load the central sketch onto another Nano BLE33 and restart both units, I can see this on the central

- Discovering peripheral device...
Found 2a:c1:f3:8f:19:fb 'Arduino Z (peripheral)' 1101
Connected
Discovering attributes ...
Attributes discovered

Device name: Arduino
Appearance: 0x0

Service 1101	Z characteristic 2103, z = 0.98
Service 1101	Z characteristic 2103, z = 0.98
Service 1101	Z characteristic 2103, z = 0.98

Whatever issues you are having, I don't think relate to the underlying BLE code. Your first piece of trouble shooting is to get the peripheral working with a standard phone app like LightBlue or nrfConnect.

Data is sent from remote to the PC-connected receiver - more could be done with the data than knocking it out on Serial Monitor (I guess).

The best way to start when you are new is to work through some of the example sketches included with the library you are working with

Yes this would have been the most effective method. I was able to play with the accelerometer library a bit, but have little experience with BLE. However, I'm already in the heat of this now and I'm learning a lot by working on this. For future projects I will be applying this method of learning though.

Upon using Lightblue, I was able to successfully connect the devices.

0x2103
Device:  Arduino
Service UUID: 1101

Read/Notified Values:
0x69000000
0x6A000000
0x59000000
0x64000000
...

The only thing that confused me here was why my data was being converted into hexadecimal, which I hope will not be a problem upon using this data on the central device.
Does this then mean that something is wrong in my central device code? Am I messing up with my UUID? What troubleshooting steps follow this?
Thank you for the response!

Light Blue has has a Data format selection just above the READ/INDICATED Values panel. You can change HEX to one of the other formats if you wish.

All data is fundamentally binary and is transmitted as such. How an app or your central program choses to display the binary data in a more human readable fashion is a matter of how the code is written.

All data is fundamentally binary and is transmitted as such.

Ah yes, thank you.

Whatever issues you are having, I don't think relate to the underlying BLE code.

If it isn't the BLE code itself, then what possibly could the problem be? Both my arduinos are Nano 33 IoT, do you think a different model such as the Nano BLE would be more successful?

I don't know. How much do you want to spend to find out :wink:

The architecture of the Nano33BLE is certainly more simple than the Nano33IOT but it does not have WiFi. What is your intended use

What do you see for acceleration data when you run the library examples.

The fact that LightBlue sees and reads the peripheral is a good sign.

Does the reported value for your orientation agree with the LightBlue value? I think that the library acceleration is reported as 100x the value so the LB reading is close to 1 so I think the IMU is working.

You might want to try place your two Arduino's closer or farther apart.

The architecture of the Nano33BLE is certainly more simple than the Nano33IOT but it does not have WiFi. What is your intended use

I do not need wifi for this, all I need is to get the Z acceleration data over to the other drive, in which the data will be processed there.

Does the reported value for your orientation agree with the LightBlue value?

I've coded a separate program utilizing the accelerometer to process the data as I intend to and it works great. Upon playing around with this a little more, I've found that it's reading acceleration but also the value changes based off the rotation which is a problem for another day I suppose. :person_facepalming:
The only possible problem that I see is the chip. You are clearly very intelligent with BLE so if you don't see anything wrong in my program then I don't see what more I could do to change it.
I'll probably try buying this chip later on:

I need to let my budget refresh first, though, so it might be a bit. I will keep posted with any findings, if you have any other ideas please let me know but your help to this point (and the help I received from you vicariously through other forums) is much appreciated.

What happens if you switch the two devices. It's the central which appears to have an issue, and if you program it as the peripheral, does it work correctly with LightBlue?

Another thing I can recommend is that you run the paired library examples for the peripheral (LED.ino) and central (LedControl.ino) and see if you can get an led to turn on and off with the two nano33 iot's that you have. If the library examples don't work, then one of the units is likely defective or somehow misconfigured.

Another thing I can recommend is that you run the paired library examples for the peripheral (LED.ino) and central (LedControl.ino) and see if you can get an led to turn on and off with the two nano33 iot's that you have.

Upon trying this example program, I was able to get the Arduinos to pair and send a binary signal to each other. With this, I've decided to modify my implementation so that the accelerometer data is processed on the peripheral device and then sends a signal to the central device when the awaited effect occurs (when the chip hits the ground). Thus, I don't need to send all the accelerometer data but just need to occasionally send a 0 or 1.

The advice that I've taken away from cattledog and sonofcy out of this is to first test the example implementations of a library that I'm unfamiliar with before diving into the project.