Slow BLE Connection

Hey yall,
I am trying to create an app that has Bluetooth using the Thunkable website. I am using the Arduino MKR Wifi 1010 which supports BLE. I am using Modbus to gather data from a battery charger, and I am trying to send it via Bluetooth to the app. My problem is that when I try and connect to my app via Bluetooth it takes 35-40 seconds to connect. After it connects, my data shows up but also takes 5-10 seconds to appear. Is there any way to make this faster? I will attach my code below. It is quite long but a majority of the code is just Modbus data collection. If there are any other pictures or documents you need me to attach, please let me know!

#include <ArduinoRS485.h> 
#include <ArduinoModbus.h>
#include <ArduinoBLE.h>

BLEService heliosService("180F"); // creating the service

BLECharacteristic batteryPercentageChar("00002A19-0000-1000-8000-00805F9B34FB", BLERead, 20);
BLECharacteristic batteryVoltageChar("00002A1C-0000-1000-8000-00805F9B34FB", BLERead, 20);
BLECharacteristic batteryTemperatureChar("00002A1B-0000-1000-8000-00805F9B34FB", BLERead, 20);
long previousMillis = 0;

// Variables
int batteryPercentage = 0;
float batteryVoltage = 0;
float batteryAmperage = 0;
float batteryTemperature = 0.00;
float batteryPower = 0;
float batteryCapacity = 0;
float batteryRuntime = 0;
int batteryType = 0;

float solarVoltage = 0;
float solarAmperage = 0;
float solarPower = 0;

float batteryMinVoltage = 0;
float batteryMaxVoltage = 0;

float inverterVoltage = 0;
float inverterAmperage = 0;
float inverterPower = 0;
float inverterInputAmperage = 0;
float inverterInputVoltage = 0;
float inverterInputPower = 0;


// Battery Registers 
const int modbusSlaveAddress = 1;  // Replace with the Modbus slave address of your DCC Charger Controller
const int modbusInverterAddress = 2;
const int batteryPercentageRegister = 0x0100;  // register address for battery percentage
const int batteryVoltageRegister = 0x0101;  // register address for battery voltage
const int batteryAmpsRegister = 0x0102;  // register address for battery charging current
const int batteryTempRegister = 0x0103;  // register address for battery temperature
const int batteryCapacityRegister = 0xE002; // register address for battery capacity
const int batteryTypeRegister = 0xE004; // register address for battery type

// Solar Panel Registers
const int solarVoltageRegister = 0x0107; // register addresss for solar panel voltage
const int solarAmpsRegister = 0x0108; // register address for solar panel current
const int solarPowerRegister = 0x0109; // register address for solar panel power

// Battery Check Registers
const int batteryMinVoltageRegister = 0x010B; // register address for minimum battery voltage for the day
const int batteryMaxVoltageRegister = 0x010C; // register address for maximum battery volatage for the day

// Inverter Registers
const int inverterVoltageRegister = 4002; // register address for inverter output voltage
const int inverterInputVoltageRegister = 4000; // register address for inverter output voltage
const int inverterInputAmpsRegister = 4001; // register address for inverter output voltage
const int inverterAmpsRegister = 4003; // register address for inverter output current


void setup() {
  // Start the serial ports
  Serial.begin(9600);
  Serial1.begin(9600);  // Start serial communication with the Nextion display

if (!BLE.begin()) {
    Serial.println("starting Bluetooth® Low Energy failed!");
  }


  // Start the Modbus client
  if (!ModbusRTUClient.begin(9600)) {
    Serial.println("Failed to start Modbus RTU Client!");
  }

  
  BLE.setLocalName("Helios"); //Setting a name that will appear when scanning for Bluetooth® devices
  BLE.setAdvertisedService(heliosService);

// Add characteristics to the service
  heliosService.addCharacteristic(batteryPercentageChar);
  heliosService.addCharacteristic(batteryVoltageChar);
  heliosService.addCharacteristic(batteryTemperatureChar);

  BLE.addService(heliosService);  // adding the service

  BLE.advertise(); //start advertising the service
  Serial.println(" Bluetooth® device active, waiting for connections...");
  }

void loop() {
BLEDevice central = BLE.central(); // wait for a Bluetooth® Low Energy central
  if (central) {  // if a central is connected to the peripheral
    Serial.print("Connected to central: ");
    Serial.println(central.address()); // print the central's BT address

    while (central.connected()) {
      long currentMillis = millis();
      if (currentMillis - previousMillis >= 200) { // if 200ms have passed, we check the battery level
        previousMillis = currentMillis;
        
        // Convert to strings
        String percentageStr = String(batteryPercentage);
        String voltageStr = String(batteryVoltage, 2); // Two decimal places
        String temperatureStr = String((batteryTemperature/1000),2);

        // Write data to characteristics
        batteryPercentageChar.writeValue(percentageStr.c_str());
        batteryVoltageChar.writeValue(voltageStr.c_str());
        batteryTemperatureChar.writeValue(temperatureStr.c_str());
      }
      readModbusData();
delay(100);
     }
    }
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
  readModbusData();

}

void readModbusData() {
  // Read Inverter Output Voltage
  if (!ModbusRTUClient.requestFrom(modbusInverterAddress, HOLDING_REGISTERS, inverterVoltageRegister, 1)) {
    Serial.print("Failed to read Inverter voltage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    inverterVoltage = ModbusRTUClient.read();
    Serial.print("Inverter Voltage: ");
    Serial.print(inverterVoltage * 0.1); // Assuming the value is in decivolts
    Serial.println("V");
  }

// Read Inverter Input Voltage
  if (!ModbusRTUClient.requestFrom(modbusInverterAddress, HOLDING_REGISTERS, inverterInputVoltageRegister, 1)) {
    Serial.print("Failed to read Inverter Input voltage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    inverterInputVoltage = ModbusRTUClient.read();
    Serial.print("Inverter Input Voltage: ");
    Serial.print(inverterInputVoltage * 0.1); // Assuming the value is in decivolts
    Serial.println("V");
  }

// Read Inverter Input Current
  if (!ModbusRTUClient.requestFrom(modbusInverterAddress, HOLDING_REGISTERS, inverterInputAmpsRegister, 1)) {
    Serial.print("Failed to read Inverter input amperage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    inverterInputAmperage = ModbusRTUClient.read();
    Serial.print("Inverter Amperage: ");
    Serial.print(inverterInputAmperage*0.01); // Assuming the value is in deciamps
    Serial.println("A");
  }

 // Read Inverter Output Current
  if (!ModbusRTUClient.requestFrom(modbusInverterAddress, HOLDING_REGISTERS, inverterAmpsRegister, 1)) {
    Serial.print("Failed to read Inverter amperage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    inverterAmperage = ModbusRTUClient.read();
    Serial.print("Inverter Amperage: ");
    Serial.print(inverterAmperage*0.01); // Assuming the value is in deciamps
    Serial.println("A");
  }

inverterPower = (inverterVoltage*0.1) * (inverterAmperage*0.01);
Serial.print("Inverter Output Power: ");
Serial.print(inverterPower);
Serial.println("W");

inverterInputPower = (inverterInputVoltage*0.1) * (inverterInputAmperage*0.01);
Serial.print("Inverter Input Power: ");
Serial.print(inverterInputPower);
Serial.println("W");

// For some reason the next sensor read after the Inverter readings fails!! This Sensor read is a place holder and will fail to read. This is good and will not show in the serial monitor
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, 0x0104, 1)) {
  } else {
    batteryVoltage = ModbusRTUClient.read();
  }


  //Read battery percentage
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryPercentageRegister, 1)) {
    Serial.print("Failed to read battery percentage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryPercentage = ModbusRTUClient.read();
    Serial.print("Battery Percentage: ");
    Serial.print(batteryPercentage);
    Serial.println("%");
  }

  // Read battery voltage
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryVoltageRegister, 1)) {
    Serial.print("Failed to read battery voltage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryVoltage = ModbusRTUClient.read();
    Serial.print("Battery Voltage: ");
    Serial.print(batteryVoltage * 0.1); // Assuming the value is in decivolts
    Serial.println("V");
  }

  // Read battery amperage
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryAmpsRegister, 1)) {
    Serial.print("Failed to read battery amperage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryAmperage = ModbusRTUClient.read();
    Serial.print("Battery Amperage: ");
    Serial.print(batteryAmperage*0.01); // Assuming the value is in deciamps
    Serial.println("A");
  }

  // Read battery temperature
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryTempRegister, 1)) {
    Serial.print("Failed to read battery temperature! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryTemperature = ((ModbusRTUClient.read()*1.8)+32);
    Serial.print("Battery Temperature: ");
    Serial.print(batteryTemperature/1000); // Assuming the value is in deci-degrees Celsius
    Serial.println("°F");
  }


  // Read Solar Panel Voltage
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, solarVoltageRegister, 1)) {
    Serial.print("Failed to read Solar voltage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    solarVoltage = ModbusRTUClient.read();
    Serial.print("Solar Voltage: ");
    Serial.print(solarVoltage * 0.1); // Assuming the value is in decivolts
    Serial.println("V");
  }
  // Read Solar Panel Current
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, solarAmpsRegister, 1)) {
    Serial.print("Failed to read Solar amperage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    solarAmperage = ModbusRTUClient.read();
    Serial.print("Solar Amperage: ");
    Serial.print(solarAmperage*0.01); // Assuming the value is in deciamps
    Serial.println("A");
  }
  // Read Solar Panel Power
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, solarPowerRegister, 1)) {
    Serial.print("Failed to read Solar Power! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    solarPower = ModbusRTUClient.read();
    Serial.print("Solar Power: ");
    Serial.print(solarPower); // Assuming the value is in deciamps
    Serial.println("W");
  }

  // Read Minimum Battery Voltage for the day
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryMinVoltageRegister, 1)) {
    Serial.print("Failed to read Minimum Battery Voltage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryMinVoltage = ModbusRTUClient.read();
    Serial.print("Min Battery Voltage: ");
    Serial.print(batteryMinVoltage); // Assuming the value is in deciamps
    Serial.println("V");
  }

// Read Maximum Battery Voltage for the day
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryMaxVoltageRegister, 1)) {
    Serial.print("Failed to read Maximum Battery Voltage! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryMaxVoltage = ModbusRTUClient.read();
    Serial.print("Max Battery Voltage: ");
    Serial.print(batteryMaxVoltage); // Assuming the value is in deciamps
    Serial.println("V");
  }

//Read battery type
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryTypeRegister, 1)) {
    Serial.print("Failed to read battery type! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryType = ModbusRTUClient.read();
    if (batteryType == 1) {
      Serial.print("Battery Type: ");
      Serial.println("FLD");
    } if (batteryType == 2) {
      Serial.print("Battery Type: ");
      Serial.println("SLA");
    } if (batteryType == 3) {
      Serial.print("Battery Type: ");
      Serial.println("GEL");
    } if (batteryType == 4) {
      Serial.print("Battery Type: ");
      Serial.println("Lithium");
    } if (batteryType == 5) {
      Serial.print("Battery Type: ");
      Serial.println("Custom");
    }
  }  

batteryPower = (batteryVoltage*0.1) * (batteryAmperage*0.01);
Serial.print("Battery Power:");
Serial.print(batteryPower);
Serial.println("W");


// Read Battery Capacity
  if (!ModbusRTUClient.requestFrom(modbusSlaveAddress, HOLDING_REGISTERS, batteryCapacityRegister, 1)) {
    Serial.print("Failed to read Battery Capacity! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    batteryCapacity = ModbusRTUClient.read();
    Serial.print("Battery Capacity: ");
    Serial.print(batteryCapacity); // Assuming the value is in deciamps
    Serial.println("AH");
  }

batteryRuntime = (batteryCapacity*batteryPercentage*batteryVoltage*0.5*0.9)/(10*100*(1 + inverterPower));
Serial.print("Battery Runtime: ");
Serial.print(batteryRuntime);
Serial.println("hours");
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.