Interfacing an HC-08 BLE module with an Arduino Nano 33 IOT

Hi
I'm working on an arduino mega 2560 based robot car with a 5 axis (dof) claw, that i want to control wirelessly using an HC-08 BLE module on the side of the car, and an arduino nano 33 iot based controller glove.

I am currently using the BLEserial library to try to interface with the HC08 module, but i'm not sure how much it's actually doing.

Using the codes below, i'm able to connect to the hc-08 module but i'm not sure what method i'd use to send and receive the data on the respective sides.

For example, would i send the data by creating a service and writing the values read from the pins as a characteristics, (using the write value function) and how would i code to receive it properly on the mega, or is there a different way to send my values, and is there a different library i should be using to read the data being sent to the hc-08 on the arduino mega.

I would really appreciate any help and conversation at all with this.

The codes would be in the comments.

/* Arduino robot car and claw bot control using Hc-08 bluetooth low energy module and arduino Nano 33 IOT
 *  
 *              == SLAVE DEVICE - ARDUINO ROBOT CAR WITH MEGA 2560 BOARD ==
 *              
 * This program sets the hc-08 module connected to serial pins (0,1) or rx, tx on the arduino mega board to a name that the Nano 33 IOT central/master controller searches for and connects to. 
 * Then reads / receives the (Sent/advertiesed) characteristics from the joystick and IMU readings on the Nano 33 IOT             
 * and operates the robot car based on received data.
 * by Saheed Quadri, Dec , 23 2021
 */

#include <AccelStepper.h> //To control the three stepper motors that make up 3 axis of the robot car's arm
#include <Servo.h> // To control the servos that make up the remaining two axis, and the claw of the robot arm
#include <SPI.h> //To use the on board 128 X 32 oled display
#include <Wire.h> //To use the on board 128 X 32 oled display
#include <Adafruit_GFX.h> //To use the on board 128 X 32 oled display
#include <Adafruit_SSD1306.h> //To use the on board 128 X 32 oled display
#include <IRremote.h> // For the on board IR receiver (Not used in this sketch)
#include "BLESerial.h" // To use the hc-08 module as a BLE device and receive data sent by the nano 33 IOT central/master controller (Not Sure how to code this part or if this is the right library to do so)

BLESerial ble(0, 1); //defining the serial pins for the bluetooth serial library (Not entirely sure if it's needed)

//Declare all accesory Pins

const int PWMA = 10; // declare control pins for car motors
const int PWMB = 11;
const int DIRA = 12;
const int DIRB = 13;

// Define step constants
#define FULLSTEP 4
#define HALFSTEP 8

Servo servo1, servo2, servo3; // declare servo pins

AccelStepper stepper1(FULLSTEP, 28, 24, 26, 22); // declare stepper pins and step amount using step constants
AccelStepper stepper2(FULLSTEP, 46, 50, 48, 52);
AccelStepper stepper3(FULLSTEP, 29, 25, 27, 23);

const int Trig = 8; // declare pins for the onboard ultrasonic sensor (not used in this sketch);
const int Echo = 7;

const int BuzzerPin =4; // declare onboard buzzer pin
const int RECV_PIN = 5; // declare onboard IR Receiver pin (Not used in this sketch)


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
#define OLED_RESET   -1 // Reset pin # (sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //For the onboard 128 X 32 OLED display

IRrecv irrecv(RECV_PIN);// for the onboard IR Receiver
decode_results results;

void setupRobotCar() // Void method for robot car and other accesory setup (To keep the code clean and understandable)
{
  // All pins should be setup as outputs:
  pinMode(PWMA, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(DIRA, OUTPUT);
  pinMode(DIRB, OUTPUT);
  pinMode(BuzzerPin, OUTPUT);

  // Initialize all motor pins as low (otherwise the car moves on it's own and never fully stops):
  digitalWrite(PWMA, LOW);
  digitalWrite(PWMB, LOW);
  digitalWrite(DIRA, LOW);
  digitalWrite(DIRB, LOW);

  //Attach servo to pins
   servo1.attach(2);
  servo2.attach(9);
  servo3.attach(6);
}

/*Void methods for moving the moto wheels in different directions
 * Please note that this is not the final form and i wish to map the values to one of the joystick data received from the nano master controller
 * Please note that the car is a four wheel drive, using one l298p hbrigde module sheild (with two motors assigned to one pair of pins)
 * Therefore, PWM values can not be below about 150, as the motors would draw too much current and end up frying the arduino
 * Please note that thge l298p hbridge module sheild use translates a digital LOW on the enable pins (DIRA, DIRB) as reverse, and a digital HIGH as foward
 * while an analog zero (0) or digital low stops the motors
 */
// Movement and directions
void Foward()
{
  analogWrite(PWMA, 250);
  analogWrite(PWMB, 250);
  digitalWrite(DIRA, HIGH);
  digitalWrite(DIRB, HIGH);
}

//Moving the card foward
void Left()
{
  analogWrite(PWMA, 200);
  analogWrite(PWMB, 200);
  digitalWrite(DIRA, HIGH);
  digitalWrite(DIRB, LOW);
}

void Right()
{ 
  analogWrite(PWMA, 200);
  analogWrite(PWMB, 200);
  digitalWrite(DIRA, LOW);
  digitalWrite(DIRB, HIGH);
}

void Back()
{
  analogWrite(PWMA, 250);
  analogWrite(PWMB, 250);
  digitalWrite(DIRA, LOW);
  digitalWrite(DIRB, LOW);
}

//To stop the motor
void Stop()
{
  analogWrite(PWMA, 0);
  analogWrite(PWMB, 0);
}

//Void method that currently shows an example of how the accel library is used, but would be modified to change the acceleration and move to values based on received data from the bluetooth module
void StepperControl(){

  stepper1.setMaxSpeed(1000.0);
  stepper1.setAcceleration(100.0);
  stepper1.setSpeed(600);
  stepper1.moveTo(100);

    // set the same for motor 2
  stepper2.setMaxSpeed(1000.0);
  stepper2.setAcceleration(100.0);
  stepper2.setSpeed(500);
  stepper2.moveTo(100);

    // set the same for motor 2
  stepper3.setMaxSpeed(1000.0);
  stepper3.setAcceleration(100.0);
  stepper3.setSpeed(600);
  stepper3.moveTo(100);

  stepper1.run();
  stepper2.run();
  stepper3.run();

  }

  

void setup() {
  //My current understanding of how the BLEserial library might work, need a lot of help figuring out it it its the right library, and if yes, how to receive characteristics advertised, or datat sent  by the nano 33 IOT
  ble.begin();
  ble.setName("SAHEED'S_ROBOT_CAR");
  ble.setSerialBaud(9600); // Set the Baud rate for Hardware serial console, defaults to 9600

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally for the OLED display
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
   Serial.println(F("SSD1306 allocation failed"));
   for(;;); // Don't proceed, loop forever
  }

  setupRobotCar(); // Set all pins as outputs
}

void loop() {

}

/* Arduino robot car control using Hc-08 bluetooth and arduino Nano 33 IOT
 *  
 *              == MASTER DEVICE - ARDUINO NANO IOT 33 WITH JOYSTICK ==
 *              
 * This program reads values from the inbuilt IMU sensors, and two attached joysticks, connects to the arduino robot carperipheral device, and sends this data for use by the robot car       
 * Not sure if i should write the values under a certain characteristics, or if there is an easier way to connect and send the data
 * The code only currently reads the values, searches for peripherals and connects to the one with a specified name (Saheed's robot car)
 * by Saheed Quadri, Dec , 18 2021
 */
#include <ArduinoBLE.h> // To use the ibuilt bluetooth function on the nano 33 IOT
#include <Arduino_LSM6DS3.h> // To use the inbuilt IMU sensor on the nano 33 IOT
#include <SPI.h> // For the onboard 128 X 32 OLED display
#include <Wire.h> // For the onboard 128 X 32 OLED display
#include <Adafruit_GFX.h> // For the onboard 128 X 32 OLED display
#include <Adafruit_SSD1306.h> // For the onboard 128 X 32 OLED display

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

#define OLED_RESET   -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //For the OLED display

void SetupPins(){ //Seperate void method to setup the pins (to make the code easily understandable) executed in the setup
  const int buzzerPin = 10;
  // configure joystick pins as input
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A6, INPUT);
  pinMode(A7, INPUT);

  //Onboard buzzer pin as output
  pinMode(buzzerPin, OUTPUT);
  
}

void Gyroscope(){ // Seperate void method to get gyroscope readings (executed in the loop)
float Xg, Yg, Zg; //define variables to assign readings to
    
if (IMU.gyroscopeAvailable())
{
  IMU.readGyroscope(Xg, Yg, Zg); //assign gyroscope readings to these defined floats
}

}

void Accelerometer(){ // Seperate void method to get accelerometer readings (executed in the loop)
float Xa, Ya, Za; //define variables to assign readings to

if (IMU.accelerationAvailable()) 
{
  IMU.readAcceleration(Xa, Ya, Za); //assign accelerometer readings to these defined floats
}

}

void ReadPinValues(){
int Car_x_axis_joystick, Car_y_axis_joystick, Claw_open_bottonPin, Claw_close_buttonPin, Arm_x_axis_joystick, Arm_y_axis_joystick; // define variables
// Two different joysticks onboard
Car_x_axis_joystick = analogRead(A3); //analog read each joystick axis's pos, returns a value between 0, 1023
Car_y_axis_joystick = analogRead(A6);
Claw_open_bottonPin = digitalRead(A7); //digital read a LOW or HIGH from the button pins
Claw_close_buttonPin = digitalRead(A0);
Arm_x_axis_joystick = analogRead(A2); //analog read each joystick axis's pos, returns a value between 0, 1023
Arm_y_axis_joystick = analogRead(A1);

}

void setup() {
Serial.begin(9600); // to use the serial motitor when wired
  while (!Serial);

// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally for the OLED display
 if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
   Serial.println(F("SSD1306 allocation failed"));
   for(;;); // Don't proceed, loop forever
  }

SetupPins();
 
if (!IMU.begin()) {
   Serial.println("Failed to initialize IMU!");
}

// begin initialization
if (!BLE.begin()) {
   Serial.println("starting BLE failed!");

   while (1);
  }

Serial.println("BLE Central - Peripheral Explorer");

  // start scanning for peripherals
BLE.scan();

}

void loop() {
Gyroscope();
Accelerometer();
ReadPinValues();

// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();

  if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service on the serial monitor when wired
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    // see if peripheral is the robot car
    if (peripheral.localName() == "SH-HC-08") {
      // stop scanning
      BLE.stopScan();
      if (peripheral.connect()) {
        Serial.println("Connected");
        } else {
        Serial.println("Failed to connect!");
       return;
        }

      // peripheral disconnected, we are done
      while (1) {
        // do nothing
      }
    }
  }

}