Esp32 BLE Connect and disconnect issue

Embel.Tech
Posts: 13
Joined: Tue Mar 03, 2020 5:26 am

Esp32 BLE Connect and disconnect issue

Postby Embel.Tech » Tue Jun 16, 2020 10:52 am

Hello Forum,
I am having problem in BLE connect and disconnection.
I ave a server which runs sensor code and client receive data from it , then disconnect from server turning wifi on and push collected data to cloud.
Servers data collection is in loop means it first collect all data from sensors then BLE turns on, then sends to client, and turn off ble .
then again sarts collecting data and same procedure repeated.
Now problem is that, at first time it sends data but next time the client failed to connect server and pushes previous data on cloud.
Next itteration of loop in server it collects data and stucks in BLE activation.

This is my client code

Code: Select all

#include<stdio.h>
#include "esp_attr.h"
#include<stdlib.h>
#include <ArduinoJson.h>
#include <AWS_IOT.h>
AWS_IOT myiot;   // AWS_IOT instance
#include <WiFi.h>

#include "time.h"
#include <Wire.h>//I2C
#include <string.h> //string lib

#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include <math.h>
#include "ens210.h"// ENS210 library
ENS210 ens210;


//tsp data
#include <WiFiUdp.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
WiFiUDP udp;

unsigned long epoch;//String utime;
unsigned int localPort = 2390;      // local port to listen for UDP packets
IPAddress timeServerIP;
const char* ntpServerName = "time.nist.gov";
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[ NTP_PACKET_SIZE];

//*****************************************


//Broker Address: ahrcxnah0j2zm-ats.iot.us-east-1.amazonaws.com
//Broker Port: 8883


char WIFI_SSID[] = "XXX";
char WIFI_PASSWORD[] = "XX@1111";
char HOST_ADDRESS[] = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
char CLIENT_ID[] = "xxxxxxxxxxxxxxxxxxxxxxx";
char TOPIC_NAME[] = "monitor";

const int ledpin_4 = 4; // led status
int status = WL_IDLE_STATUS; //wifi status
int aws_status = 0;
int data_cnt = 0;

int tick = 0, msgCount = 0, msgReceived = 0;

//-------------------------------------------------------------------
// How many times we should attempt to connect to AWS
//-------------------------------------------------------------------
#define AWS_MAX_RECONNECT_TRIES 5

char payload[500]; //aws cloud data

String wifi_mac;
String type_str;
String tsp_str;
String temp_str;
String hum_str;
String heart_str;
String posx_str;
String posy_str;
String posz_str;
String bat_str;
String devid_str;
String spo2_str;
String data_packet_str; //watch value stored


//sleep an restart ESP32
#define uS_TO_S_FACTOR 1000000  // Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP  10        // Time ESP32 will go to sleep (in seconds)


/*
    BLE Advertised Device found:
    Name: BABY_WATCH,
    Address: 4c:11:ae:71:28:fe
*/

#include "BLEDevice.h"
#include <BLEUtils.h>
//#include <BLEServer.h>

// The remote service we wish to connect to.
static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
static BLEUUID    charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");

static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;

//Client device
BLEClient* pclient = NULL;
BLEClient*  pClient = NULL;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice = NULL;

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
  Serial.println("Notify callback for characteristic ");
  Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
  Serial.print(" of data length :: ");
  Serial.println(length);
  Serial.print(" data: ");
  Serial.println((char*)pData);
  delay(1000);
}

class MyClientCallback : public BLEClientCallbacks {
    void onConnect(BLEClient* pClient) {
      connected = true;
      Serial.println(" onConnect Connected to Server");
    }
    void onDisconnect(BLEClient* pClient)
    {
      connected = false;
      Serial.println("Disconnected from Server");
      exit;
    }
};

bool connectToServer() {
  BLERemoteService* pRemoteService = NULL;
  Serial.print(" - Forming a connection to ");
  if (myDevice != NULL)
  {
    Serial.println(myDevice->getAddress().toString().c_str());
    delay(1000);

    pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");
    //  delay(1000);

    pClient->setClientCallbacks(new MyClientCallback());
    //delay(1000);

    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    Serial.println(" - Connected to server");
    delay(1000);

    // Obtain a reference to the service we are after in the remote BLE server.
    pRemoteService = pClient->getService(serviceUUID);
  }
  if (pRemoteService == nullptr) {
    Serial.print(" - Failed to find our service UUID: ");

    Serial.println(serviceUUID.toString().c_str());
    pClient->disconnect();
    return false;
  }
  Serial.println(" - Found our service");
  delay(1000);

  // Obtain a reference to the characteristic in the service of the remote BLE server.
  pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
  delay(7000);

  if (pRemoteCharacteristic == nullptr)
  {
    Serial.print("Failed to find our characteristic UUID: ");
    Serial.println(charUUID.toString().c_str());
    pClient->disconnect();
    return false;
  }  else {
    Serial.println(" - Found our characteristic");
    delay(1000);
  }
  //********   READ DATA PACKET FROM BLE_WATCH *******************
  // Read the value of the characteristic.

  if (pRemoteCharacteristic->canRead())
  {
    Serial.println("Reading packet from watch");
    delay(2000);
    std::string value = pRemoteCharacteristic->readValue();
    Serial.print("BLE_data_packet:: "); //temp value RX
    Serial.println(value.c_str());
    delay(5000);

    data_packet_str = value.c_str(); //store "WATCH" data

    Serial.print("\nWATCH data:");
    Serial.println(data_packet_str);
    delay(1000);

    //*********  split string start  ************************
    float commaIndex = data_packet_str.indexOf(','); //temp
    unsigned long secondCommaIndex = data_packet_str.indexOf(',', commaIndex + 1); //hum
    float thirdCommaIndex = data_packet_str.indexOf(',', secondCommaIndex + 1);  // HRM
    float fourthCommaIndex = data_packet_str.indexOf(',', thirdCommaIndex + 1);  //spo2
    float fifthCommaIndex = data_packet_str.indexOf(',', fourthCommaIndex + 1);  //x-axis
    float sixthCommaIndex = data_packet_str.indexOf(',', fifthCommaIndex + 1);  //y-axis
    float seventhCommaIndex = data_packet_str.indexOf(',', sixthCommaIndex + 1); //z-axis

    //float eighthCommaIndex = data_packet_str.indexOf(',', seventhCommaIndex + 1);
    //float ninthCommaIndex = data_packet_str.indexOf(',', eighthCommaIndex + 1);
    // float tenthCommaIndex = data_packet_str.indexOf(',', ninthCommaIndex + 1);


    temp_str = data_packet_str.substring(0, commaIndex);
    hum_str = data_packet_str.substring(commaIndex + 1, secondCommaIndex);
    heart_str = data_packet_str.substring(secondCommaIndex + 1, thirdCommaIndex);
    spo2_str = data_packet_str.substring(thirdCommaIndex + 1, fourthCommaIndex);
    posx_str  = data_packet_str.substring(fourthCommaIndex + 1, fifthCommaIndex);
    posy_str = data_packet_str.substring(fifthCommaIndex + 1, sixthCommaIndex);
    posz_str = data_packet_str.substring(sixthCommaIndex + 1);

    //     = data_packet_str.substring(seventhCommaIndex + 1, eighthCommaIndex);
    //    bat_str = data_packet_str.substring(eighthCommaIndex + 1, ninthCommaIndex);
    //    spo2_str = data_packet_str.substring(ninthCommaIndex + 1);
    //    //par_str = data_packet_str.substring(tenthCommaIndex + 1 );


    Serial.println("-------------------------------------------");
    Serial.println("ble datapacket after split :");
    Serial.println(type_str); Serial.println(tsp_str);
    Serial.println(temp_str); Serial.println(hum_str);
    Serial.println(heart_str); Serial.println(posx_str);
    Serial.println(posy_str); Serial.println(posz_str);
    Serial.println(bat_str); Serial.println(spo2_str);
    Serial.println("-------------------------------------------");
    delay(1000);
    //****** split string end  *************************
  }
  pClient->disconnect();
}
/*
   Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
{
    /* Called for each advertising BLE server.*/

    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
      Serial.print("BLE Advertised Device found: ");
      Serial.println(advertisedDevice.toString().c_str());

      // We have found a device, let us now see if it contains the service we are looking for.

      if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID))
      {
        BLEDevice::getScan()->stop();
        myDevice = new BLEAdvertisedDevice(advertisedDevice);
        doConnect = true;
        doScan = true;

      } // Found our server
    } // onResult
}; // MyAdvertisedDeviceCallbacks


void setup()  // start of setup.
{
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

  Serial.begin(115200);

  pinMode(ledpin_4, OUTPUT);      //led out

  //for capacitive
  pinMode(15, INPUT);            //touch 2
  pinMode(14, INPUT);            //touch 3

  while (!Serial) continue;
  Serial.println("\nStarting Arduino BLE Client application...");
  delay(1000);
  ble_init();              // bluetooth ON
  //ble_reconnect();
  ble_deinit();
  Serial.println("\n----------------------------------------------------------------");
  Serial.print("::::End of Setup Function::::: ");
  Serial.println("\n----------------------------------------------------------------");
} // End of setup.

//******************************************************************************************************************************
//******************************** PLEASE SEE THIS FUNCTION  ********************************************************************
//*********************************************************************************************************************************

// This is the Arduino main loop function.
void loop()
{
  // bluetooth OFF

  Serial.println("\n----------------------------------------------------------------");
  Serial.print("wifi status :: ");
  Serial.println(status);
  //check if wifi connected or not.
  //if connected then execute if part otherwise it execute else part to connect with wifi and further process
  if (status == WL_CONNECTED)
  {
    wifi_mac = WiFi.macAddress();
    Serial.print("BRIDGE Device ID :: ");
    Serial.println(wifi_mac);
    delay(2000);
    //if connected then execute if part otherwise else part
    if (aws_status == 1)
    {
      JSON_PACKET();                // JSON_DATA_PACKET STORE AND APEND
      aws_data();                   //data ready to publish
    }
    else
    {
      aws();                        // AMAZON CLOUD connect
      JSON_PACKET();                // JSON_DATA_PACKET STORE AND APEND
      aws_data();                   //data ready to publish
    }


  }
  else                              // first of all connect to wifi and do  further process
  {
    wifi();                         // wifi reconnect

    if (aws_status == 1)            //if connected then execute if part otherwise else part
    {
      JSON_PACKET();                // JSON_DATA_PACKET STORE AND APEND

      aws_data();                   //data ready to publish
    }
    else                            // firstly create aws connection and then execute rest of like json packet and aws data
    {
      aws();                        // AMAZON CLOUD connect

      JSON_PACKET();                // JSON_DATA_PACKET STORE AND APEND

      aws_data();                   //data ready to publish
    }

  }
  delay(5000);
  Serial.println("\n########################################\n########################################");
  // sleep();  ////device sleep and wake up in next 10 sec
  setup();

}

//*****************************************************************************************************************************

void wifi()
{
  //************** wifi *********************************

  if (status == WL_CONNECTED)
  {
    Serial.print(" wifi is in connected STATE  :: ");
  }
  else
  {
    while (status != WL_CONNECTED)
    {
      Serial.print("Attempting to connect to SSID :: ");
      Serial.println(WIFI_SSID);
      WiFi.mode(WIFI_MODE_STA);
      status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
      delay(1500);
    }

    wifi_mac = WiFi.macAddress();
    Serial.print("BRIDGE Device ID :: ");
    Serial.println(wifi_mac);
    delay(100);

    Serial.println("------------------------------------------------\n");
    Serial.println("Connected to wifi");

    Serial.print("IP address :: ");
    Serial.println(WiFi.localIP());
    Serial.print("WIFI Strength :: ");
    Serial.println( WiFi.RSSI());
    Serial.print("WiFi MAC address :: ");
    Serial.println(WiFi.macAddress());
    Serial.println("------------------------------------------------\n");
    //  Serial.print("WIFI_data:"); Serial.println(data_packet_str);
  }
}

//**%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

//******************              AMAZON CLOUD CONNECTION                *********************************************************************************

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void aws()
{
  // Try to connect to AWS and count how many times we retried.
  int retries = 0;
  Serial.println("Checking connection for AWS IOT");
  delay(1000);// if return value = 0 successfully cloud connect
  while (myiot.connect(HOST_ADDRESS, CLIENT_ID) != 0 && retries < AWS_MAX_RECONNECT_TRIES) // Connect to AWS using Host Address and Cliend ID
  {
    Serial.println(" Connecting to AWS... ");
    delay(1500);
    retries++;
  }

  if (myiot.connect(HOST_ADDRESS, CLIENT_ID) == 0)
  {
    Serial.println(" AWS_cloud is  connected ");
    aws_status = 1;
    delay(1500);
    return;
  }
  delay(200);

}// aws(); end

//*************** BLE ***************************************
int k = 0;
void ble_init()
{
  if (k == 0) {
    BLEDevice::init("ESP32");
  }
  Serial.println("\n------------------------------------------------");
  Serial.println(" \t:::: Bluetooth ON :::: ");
  Serial.println("------------------------------------------------\n");
  delay(1000);
  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.

  BLEScan* pBLEScan = BLEDevice::getScan();
  Serial.print("pBLEScan ::");
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(100, false);
  delay(1000);

  //Trying to connect
  if (connectToServer())
  {
    k = 1;
    Serial.println("We have received DATA from Watch (Server)");

  }
  //  else
  //  {
  //    Serial.println("We have failed to connect to the Watch server; there is nothin more we will do.");
  //    }

}


void ble_deinit()

{
  connected = false;
  delay(2000);
  myDevice = NULL;
  delay(10000);
  pClient->disconnect();
  delay(2000);
  pclient = NULL;
  delay(2000);
  myDevice = NULL;

  BLEDevice::deinit(ESP.getFreeHeap());
  Serial.println("------------------------------------------------");
  Serial.println(" \t:::: Bluetooth OFF :::: ");
  Serial.println("------------------------------------------------");
  delay(100);
}



//************* data packet*************************************


void JSON_PACKET()
{
  // JSON memory allocation
  DynamicJsonDocument doc(350); //data packet buffer
  tsp();

  doc["type"] = "monitor";
  doc["tsp"] = "1584696179";
  doc["deviceID"] = wifi_mac;                 //wifi_mac;
  doc["temperature"] = temp_str;
  doc["humidity"] =  hum_str;
  doc["heart_rate"] = heart_str;
  doc["spo2_level"] = spo2_str;
  doc["pos_x"] =  posx_str ;
  doc["pos_Y"] = posy_str;
  doc["pos_Z"] = posz_str;
  //doc ["battery"] = "full";



  Serial.println("JSON DATA PACKET   :");
  serializeJsonPretty(doc, Serial);
  // serializeJson(doc, Serial); //show on serial
  serializeJson(doc, payload);//all obj stored from doc to playload

  /*
    // JSON PAYLOAD for TEMP_ALERT doc_1  ******************************

    doc_1["type"] = type_str;
    doc_1["param"] = "temp";
    doc_1["tsp"] = tsp_str;
    doc_1["deviceID"] = wifi_mac;
    JsonArray data_1 = doc_1.createNestedArray("temperature");
    data_1.add(temp_str); data_1.add(temp_str);
    data_1.add(temp_str); data_1.add(temp_str);
    data_1.add(temp_str); data_1.add(temp_str);
    data_1.add(temp_str); data_1.add(temp_str);
    data_1.add(temp_str); data_1.add(temp_str);

    //Serial.println(" TEMP_ALERT DATA PACKET");
    //  Serial.println("JSON payload for TEMP_ALERT is ready to upload :");
    // serializeJsonPretty(doc_1, Serial);
    //serializeJson(doc_1, Serial); //show on serial
    serializeJson(doc_1, payload_1);//all obj stored from doc to playload
    delay(10);
  */

}

void aws_data()
{
  if (myiot.publish(TOPIC_NAME, payload) == 0) // Publish the message(Temp and humidity)
  {
    Serial.println("\n------------------------------------------------");
    Serial.print("\nPublish Message :: ");
    Serial.println(payload);
    Serial.print("\nSize of monitor data packet after write :: ");
    Serial.print(sizeof(payload));
    Serial.println(" bytes");
    Serial.println("\n------------------------------------------------");
    Serial.println("Published monitor data packet to AWS_CLOUD successfully");
    Serial.println("------------------------------------------------");
    delay(1000);
    memset(payload, 0, 500 *  sizeof(payload[0]));
    Serial.println("\n------------------------------------------------");
    Serial.print("Size of payload after free ::");
    Serial.print(sizeof(payload));
    Serial.println(" bytes");
    delay(1000);
    led_status();
    data_cnt++;
  }

}


void led_status()
{
  //digitalWrite(ledpin_4, HIGH);   // turn the LED on (HIGH is the voltage level)
  //  Serial.println("led on");
  //delay(500);

  //digitalWrite(ledpin_4, LOW);    // turn the LED off by making the voltage LOW
  //Serial.println("led off");
  //delay(100);
}

void tsp()
{
  delay(500);
  //time unix ********* start  ***********************
  WiFi.hostByName(ntpServerName, timeServerIP);
  sendNTPpacket(timeServerIP);
  int cb = udp.parsePacket();

  if (!cb)
  {
    delay(1);
  }
  else
  {
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    const unsigned long seventyYears = 2208988800UL;
    epoch = secsSince1900 - seventyYears;
    Serial.print("UNX_TIME : ");
    Serial.println(epoch);
  }
  delay(2000);  // 10000

}//************ time end  ********************

unsigned long sendNTPpacket(IPAddress & address)
{
  Serial.println("\n");
  Serial.println("Sending NTP packet...");
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  udp.beginPacket(address, 123);
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();
}


void ble_reconnect()
{

  if (connected)
  {
    Serial.println("bluetooth is connected mode");
    delay(500);
  }
  else if (doScan)
  {
    connected = false; // added from 28/05 on 09/06
    BLEDevice::getScan()->start(0);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }



}
void sleep()
{
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  //   Serial.println("BLE_BRIDGE  sleep for every " + String(TIME_TO_SLEEP) +
  //              " Seconds");
  //Serial.println("BRIDGE is getting UPDATING now... ");
  delay(1000);
  Serial.flush();
  esp_deep_sleep_start();
}

This is my server code

Code: Select all


/************************************
        Libraries Include
***********************************/

/*Standered C libraries*/
#include <stdio.h>
#include <stdlib.h>

/*Brownout Detector removing using this lib's*/
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"


/* For INT_MIN */
#include <limits.h>

/*Accelerometer */
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>


/*****************************************************************
    function_Header.h file contains function declaration
*/
#include "function_Header.h"

/******************************************************************
    macro_define.h  contains some macros required for the functions
*/
#include "macro_define.h"

/********************************************************************
  This  micro definition include, when using MAX30100 sensor
  Which is used for detection of Heart rate and SpO2 measurment
*/
#include "MAX30100_PulseOximeter.h"

/********************************************************************
    PulseOximeter is the higher level interface to the sensor
    it offers:
            > beat detection reporting
            > heart rate calculation
            > SpO2 (oxidation level) calculation
*/
PulseOximeter pox;

uint32_t tsLastReport = 0;

/*---------------------------------------------------------------------------*/
/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

/******************************************************************
      ENS210 Library included for Temprature and Humidity recording
      Header for Temperature & Humidity
      ens210 is structer header for Temperature & Humidity
*/
#include <ens210.h>
ENS210 ens210;

/*Librarys included to use Bluetooth functionality of controller*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include"esp_gap_bt_api.h"
#include "esp_err.h"
#include "BluetoothSerial.h"
/*
    Pointer requirement for Initiating BLE Server.
    We have initialize all the pointer with NULL value.
      The design of creating the BLE server is:
   1. Create a BLE Server
   2. Create a BLE Service
   3. Create a BLE Characteristic on the Service
   4. Create a BLE Descriptor on the characteristic
   5. Start the service.
   6. Start advertising.
*/
BLEServer *pServer = NULL ;
BLEService *pService;
BLEAdvertising *pAdvertising = NULL;

bool deviceConnected = false;
bool oldDeviceConnected = false;


/* define the characteristic and it's propeties */
BLECharacteristic  pCharacteristic(
  CHARACTERISTIC_UUID,
  BLECharacteristic::PROPERTY_READ |
  BLECharacteristic::PROPERTY_NOTIFY
);

/* This function handles server callbacks */
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

int afs = 0;

int BLE_lock = 0;
/********************************************
          Setup Function
*********************************************/
void setup()
{
  delay(3000);
  /*Disable Brownout Detector*/
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  Wire.begin();         //TWI comunication starts

  Serial.begin(115200); //Console Starts

  /*************Temperature sensor Initialization*****************/
  ens210.begin();

  /*************Accelerometer sensor Initialization*****************/
  accel.begin();
  accel.setRange(ADXL345_RANGE_16_G);

  /*Push button to on/off*/
  pinMode(button, INPUT);

  /*GPIO 15 used for HRM Reset*/
  pinMode(Resetz, OUTPUT);

  /*GPIO 04 used to check ADC ready input from HRM*/
  pinMode(ADC_RDY, INPUT);

  Serial.print("\n\nInitializing device Please wait  ");
  int a = 0;
  DOTS;
  Serial.println("");

  /*
       Initialize the PulseOximeter instance and register a beat-detected callback.
       The parameter passed to the begin() method changes the samples flow that the library spews to the serial.
       Options:
          PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT : filtered samples and beat detection threshold
          PULSEOXIMETER_DEBUGGINGMODE_RAW_VALUES : sampled values coming from the sensor, with no processing
          PULSEOXIMETER_DEBUGGINGMODE_AC_VALUES : sampled values after the DC removal filter

       Initialize the PulseOximeter instance
       Failures are generally due to an improper I2C wiring, missing power supply or wrong target chip

  */
  /*      Uncomment below statements when MAX3010x sensor connected */
  //    if (!pox.begin(PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT)) {
  //        Serial.println("ERROR: Failed to initialize pulse oximeter");
  //        for(;;);
  //    }

  pox.setOnBeatDetectedCallback(onBeatDetected); //callbback function defined in function definiition

  delay(1000);
}  /*void setup() ends here*/

/************************************************
                    Loop Function
************************************************/
void loop()
{
  Serial.println("\nModified Date :: 12/06/2020");
  /* Variables to stores Data*/
  float Temp_Array[50], Humidity_Array[50], HRM_Array[50], SpO2_Array[50], ACC_X_Array[50], ACC_Y_Array[50], ACC_Z_Array[50];

  double HRM1_SpO2[2];

  float HRM, SpO2, Fahrenheit, Humidity, Acc_Mag[3], time_delay;

  int  sampling_unit = 0, processing_unit = 1;
  /* variable are used for running the loop for given sample unit
    to do this you can change the "processing_unit" manually
    calculation is given below,
    time_delay = (60 / processing_unit) * 1000;
    the time delay is the time to send data to bridge
  */

  char unx_str[100], heart_str[100], SPO2_str[100], far_str[100], hum_str[100], a_x[100], a_y[100], a_z[100];


  //milliseconds/no. of samples multiply by 1000 it will gives duration
  //here 60 is configuired as one minute
  // 60 can be replaced by as per requirement

  //time_delay = (60 / processing_unit) * 100;
  time_delay = 1000;
  /***********************************************************
    Data(Interger) to string conversion
    unx_str epox time converting to string epoch  //Now we are not using this
    heart_str Heart rate converting to string HRM
    SPO2_str SpO2 converting to string SpO2
    far_str Temperature converting to string Fahrenheit
    hum_str Humidity converting to string Humidity
    a_x X-axis converting to string Acc_Mag[0]
    a_y Y-axis converting to string Acc_Mag[1]
    a_z Z-axis converting to string Acc_Mag[2]
  ************************************************************/
  // dtostrf(epoch, 1, 2, unx_str);

  dtostrf(HRM1_SpO2[0], 1, 3, heart_str);
  dtostrf(HRM1_SpO2[1], 1, 3, SPO2_str);
  dtostrf(Fahrenheit, 1, 3, far_str);
  dtostrf(Humidity, 1, 3, hum_str);
  dtostrf(Acc_Mag[0], 1, 3, a_x);
  dtostrf(Acc_Mag[1], 1, 3, a_y);
  dtostrf(Acc_Mag[2], 1, 3, a_z);

  char BLE_PACKET[200];             //Bluetooth Data packet used for sending to Gateway
  char BLE_TEMP_ALERT_PACKET[200];  //Temperatur Alert packet



  /*To turn on and off the device*/
  Button_on_off();

  /**********  WI-FI Initialization ************
    //WiFi.begin(ssid, pass);
    //  while (WiFi.status() != WL_CONNECTED)
    //  {
    //    Serial.println("Connection to wifi");
    //    delay(500);
    //  }
    //
    //  udp.begin(localPort);
    //
    //  Serial.println("wifi Conected ");
  */

  Serial.println("Starting BLE_WATCH ");

  DOTS;
  afs = 0;

  /*--------------------------------------------------------------------------------------------------------------------------*/

  Serial.println("Executing All Tasks");

  /*------------------------------------------------------------------------------------*/
  /*
                    Looping all tasks
  */
  loop_running_task_ (sampling_unit != processing_unit)
  {
    /*------------------------------------------------------------------------------------*/

    temp_Hum_task( &Fahrenheit, &Humidity );          // Calling Temperatur function

    Serial.println("-----------------------------------------------------------------------------------------------");

    Serial.print(" Temperature :: "); Serial.println(Fahrenheit);
    Serial.print(" Humidity :: "); Serial.println(Humidity);

    Serial.println("-----------------------------------------------------------------------------------------------");

    Temp_Array[sampling_unit] = Fahrenheit;         //Storing temperature values

    Serial.print(" Temp_Array[sampling_unit] :: ");
    Serial.println(Temp_Array[sampling_unit]);

    Serial.println("-----------------------------------------------------------------------------------------------");
    Humidity_Array[sampling_unit] = Humidity;      //Storing Humidity calue

    Serial.print(" Humidity_Array[sampling_unit] :: ");
    Serial.println(Humidity_Array[sampling_unit]);

    Serial.print(" time_delay :: "); Serial.println(time_delay);

    /*
         We have to generate ALERTs for temperature changes from HIGH or LOW.
         These change in temperature are used to check with the threashold values set for high and low detection.
         These alertsare send to Gateway by using BLE on detect.
         In this BLE_PACKET stores the values which is above or equal to threashold and update to Gateway.
    */

    if (Fahrenheit > 99 && Fahrenheit < 102) {                        // if temp > 90 alert payload send
      //Collecting data in packet
      sprintf(BLE_PACKET, "%0.2f", Fahrenheit);                       //Need to define exact time for alert without using wifi
      pCharacteristic.setValue(BLE_PACKET);                          //transfering collected data alert via bluetooth to Bridgge
      pCharacteristic.notify();
      Serial.print(" High TEMPERATURE ALERT :: ");
      Serial.println(BLE_TEMP_ALERT_PACKET);
      delay(1000);
    } else if (Fahrenheit > 102) {                                    // if temp > 102 alert payload send
      // change readings for 100 and 102
      // Very high tempperature alert packet
      // Collecting data in packet
      int high_alert = 0;
      while (high_alert != 2) {                                       //We are sending this alert signal thrice after every 5 Second to gateway.
        sprintf(BLE_PACKET, "%0.2f", Fahrenheit);
        pCharacteristic.setValue(BLE_PACKET);                        //transfering collected data alert via bluetooth to Bridgge
        pCharacteristic.notify();
        Serial.print(" High TEMPERATURE ALERT:");
        Serial.println(BLE_TEMP_ALERT_PACKET);
        high_alert++;                                                 //Sending high alert 3 times after every 5 second
        delay(5000);
      }
    } else if (Fahrenheit < 80) {                                     // if temp <80 alert payload send
      //Low temperature alert packet
      sprintf(BLE_PACKET, "%0.2f", Fahrenheit);                       //Collecting data in packet
      pCharacteristic.setValue(BLE_PACKET);                          //transfering collected data alert via bluetooth to Bridgge
      pCharacteristic.notify();
      Serial.print(" High TEMPERATURE ALERT:");
      Serial.println(BLE_TEMP_ALERT_PACKET);
      delay(1000);
    }

    //******************** TEMP alert end  ********************
    /*------------------------------------------------------------------------------------*/

    delay(200);

    /*------------------------------------------------------------------------------------*/

    //Motion starts
    /*
       Function returns the values of Accelration
       x- axis
       y-axis
       z-axis
       Storing these values in a array ACC_X_Array[],ACC_Y_Array[],ACC_Z_Array[]

    */
    // Calling Accelration Task
    task_Acc_Mag(Acc_Mag);

    Serial.println("-----------------------------------------------------------------------------------------------");

    ACC_X_Array[sampling_unit] = Acc_Mag[0];         //Storing x-axis value

    Serial.print(" ACC_X_Array[sampling_unit] :: "); Serial.println(ACC_X_Array[sampling_unit]);

    ACC_Y_Array[sampling_unit] = Acc_Mag[1];         //Storing y-axis value

    Serial.print(" ACC_Y_Array[sampling_unit] :: "); Serial.println(ACC_Y_Array[sampling_unit]);

    ACC_Z_Array[sampling_unit] = Acc_Mag[2];         //Storing z-axis value

    Serial.print(" ACC_Z_Array[sampling_unit] :: "); Serial.println(ACC_Z_Array[sampling_unit]);

    Serial.println("-----------------------------------------------------------------------------------------------");

    delay(200);

    /*------------------------------------------------------------------------------------*/

    // Calling HRM Task
    HRM_FUNCTION(HRM1_SpO2);

    Serial.println("-----------------------------------------------------------------------------------------------");

    Serial.print(" HRM1_SpO2[0] :: "); Serial.println(HRM1_SpO2[0]);
    Serial.print(" HRM1_SpO2[1] :: "); Serial.println(HRM1_SpO2[1]);

    HRM_Array[sampling_unit] = HRM1_SpO2[0];

    Serial.println("-----------------------------------------------------------------------------------------------");

    Serial.print(" HRM_Array[sampling_unit] :: "); Serial.println(HRM_Array[sampling_unit]);

    SpO2_Array[sampling_unit] = HRM1_SpO2[1];

    Serial.print(" SpO2_Array[sampling_unit] :: "); Serial.println(SpO2_Array[sampling_unit]);

    Serial.println("-----------------------------------------------------------------------------------------------");

    delay(time_delay);

    Serial.print(" Sample time :: "); Serial.println(sampling_unit);

    delay(1000);

    sampling_unit++;

    delay(time_delay);                //delaying the loop

    Serial.println("-----------------------------------------------------------------------------------------------");
  }//Loop running Task ends here..............

  Serial.print(" Temperature : : ");              Serial.println(Temp_Array[0]);
  Serial.print(" Humidity : : ");                 Serial.println(Humidity_Array[0]);
  Serial.print(" HRM_Array[sampling_unit] :: ");  Serial.println(HRM_Array[0]);
  Serial.print(" SpO2_Array[sampling_unit] :: "); Serial.println(SpO2_Array[0]);
  Serial.print("X Axis ::");                      Serial.println(ACC_X_Array[0]);
  Serial.print("Y Axis ::");                      Serial.println(ACC_Y_Array[0]);
  Serial.print("Z Axis ::");                      Serial.println(ACC_Z_Array[0]);

  /*-------------------------------------------------------------------------------------------
      BLE_PACKET is a charecter array that stores all the values that,
      we have to send via Bluetooth to the Bridge/Gateway in JSON format
    ---------------------------------------------------------------------------------------------*/
  Serial.println("-----------------------------------------------------------------------------------------------");
  //Following JSON packet is of TYPE monitor packet
  Serial.println("BLE Packet to Send via BLE");

  /* BLE_PACKET holds all the data from sensors */
  sprintf(BLE_PACKET, "%0.2f,%0.2f,%0.2f,%0.2f,%0.2f,%0.2f,%0.2f",
          Fahrenheit, Humidity, HRM_Array[0], SpO2_Array[0], Acc_Mag[0], Acc_Mag[1], Acc_Mag[2]);

  Serial.println("\n------------------------------------------------");

  /*************** Bluetooth Initialization********************/

  // Name your BLE Device
  BLEDevice::init("BABY_WATCH");

  //Create the BLE Server
  pServer = BLEDevice::createServer();
  Serial.println("\n::::: Pserver Created ::::: ");

  // Set the function that handles server callbacks
  pServer->setCallbacks(new MyServerCallbacks());
  delay(1000);

  // Create the BLE Service
  pService = pServer->createService(SERVICE_UUID);
  Serial.println(":::::PServise Created ::::: ");
  delay(1000);

  // Create a BLE Characteristic
  pService->addCharacteristic(&pCharacteristic);

  // Create a BLE Descriptor
  pCharacteristic.addDescriptor(new BLE2902());

  // Start the service

  Serial.println("\n ::::: Turning ON Bluetooth :::: ");
  DOTS; afs = 0;
  Serial.println("------------------------------------------------\n");
  Serial.println("");
  Serial.println("\n ::::: BLUETOOTH TURNED ON ::::: \n");
  Serial.println("------------------------------------------------\n");

  pService->start();

  // Configure Advertising
  pAdvertising = BLEDevice::getAdvertising();     // Start advertising
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);            //previous it was true
  pAdvertising->setMinPreferred(0x06);            // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);            // set value to 0x00 to not advertise this parameter
  BLEDevice::startAdvertising();

  Serial.println("Waiting a Gateway connection to notify...");
  Serial.println("------------------------------------------------\n");
  Serial.println("\n");

  /*Sending collected data via BLE*/
  delay(10000);

  if (deviceConnected) {
    Serial.println(" Sending MONITOR packet to Bridge via bluetooth");
    //This value is transfer to gateway over BLE
    pCharacteristic.setValue(BLE_PACKET);
    pCharacteristic.notify();
    delay(10000);
    deviceConnected = false;
    pServer == NULL;
    BLEDevice::stopAdvertising();
  }
  Serial.println("BRIDGE is getting UPDATING now... \n");

  // deviceConnected = false;

  Serial.print(" Data packet :: ");
  Serial.println(BLE_PACKET);                         //Final BLE Packet, send to Gateway
  Serial.println("\n-----------------------------------------------------------------------------------------------");

  delay(2000);
  // BLE DATA PACKET END
  // Disconnecting BLE
//  BLEDevice::deinit(ESP.getFreeHeap());

  int t = 1;
  if (!deviceConnected)
  {
    deviceConnected = false;
    delay(2000);
    Serial.println("------------------------------------------------");
    Serial.println(":::: Bluetooth OFF ::::");
    Serial.println("------------------------------------------------\n");
    t = 0;
  }else if (t) {
      Serial.println("Not in if(!disconnect)");
    }
    
  //  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  //  //   Serial.println("BLE_BRIDGE  sleep for every " + String(TIME_TO_SLEEP) +
  //  //              " Seconds");
  //
  delay(5000);

  //  Serial.flush();
  //  esp_deep_sleep_start();
}  /*void loop() function ends here*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       Temperature and Humidity Task Execution
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
void temp_Hum_task( float * Fahrenheit, float * Humidity )
{
  Serial.println("Executing Temperature and Humidity Function");
  /*******  Temperature and Humidity Event  *******/
  /*Variable for Temprature & Humidity*/
  int t_data, t_status, h_data, h_status;
  /*Temprature and Humidity measurment*/
  ens210.measure(&t_data, &t_status, &h_data, &h_status );
  /*Calculating temperature in Fahrenheit*/
  *Fahrenheit = ens210.toFahrenheit(t_data, 100);
  *Fahrenheit /= 100;
  /*Calculating Humidity in % Relative humidity*/
  *Humidity =  ens210.toPercentageH(h_data, 1);
  //  Serial.print(" Humidity: ");  Serial.print(*Humidity);  Serial.print(" %\t");
  //  Serial.print(" Temperature: ");  Serial.print(*Fahrenheit);    Serial.println(" *F ");
  delay(50);
}  /*void temp_Hum_task() function ends here*/


/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   Acceleration and Magnetometer Task Execution
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
void task_Acc_Mag(float Acc_Mag[])
{
  Serial.println("Executing Acceleration Function");
  delay(5);
  /*******  Acceleration Event  *******/
  sensor_t sensor;                        //header for Acceleration sensor

  accel.getSensor(&sensor);               //Reading values from sensor

  sensors_event_t event;                  // header for occurence of event

  accel.getEvent(&event);                 //Reading values from event

  /* Display the results (acceleration is measured in m/s^2) */

  float Acc_X = event.acceleration.x;     //Acc_X-Axis

  Acc_Mag[0] = Acc_X;                     //Storing result from X-axis

  float Acc_Y = event.acceleration.y;     //Acc_Y-Axis

  Acc_Mag[1] = Acc_Y;                     //Storing result from Y-axis

  float Acc_Z = event.acceleration.z;     //Acc_Z-Axis

  Acc_Mag[2] = Acc_Z;                     //Storing result from Z-axis

  delay(5);

}/*void task_Acc_Mag() function ends here*/

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                  Max_HR_SpO2()

      This function gives the Heart rate and SpO2 measurments

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
void Max_HR_SpO2(float HR_SpO2[])
{
  // Make sure to call update as fast as possible
  pox.update();

  // Asynchronously dump heart rate and oxidation levels to the serial
  // For both, a value of 0 means "invalid"
  if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
    Serial.print("H:"); Serial.println(pox.getHeartRate());
    HR_SpO2[0] = pox.getHeartRate();
    Serial.print("Heart Rate :: "); Serial.println(HR_SpO2[0]);
    Serial.print("O:"); Serial.println(pox.getSpO2());
    HR_SpO2[1] = pox.getSpO2();
    Serial.print("SpO2 :: "); Serial.println(HR_SpO2[1]);
    tsLastReport = millis();
  }
}



void ble_deinit()

{
  BLEDevice::deinit(ESP.getFreeHeap());
  Serial.println("------------------------------------------------");
  Serial.println(" \t:::: Bluetooth OFF :::: ");
  Serial.println("------------------------------------------------");
  delay(100);
}


/************************************
    EPOCH UNIX TIME FUNCTION
*************************************/
/*
  unsigned long sendNTPpacket(IPAddress& address) {
  Serial.println(" Sending NTP packet...");
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  udp.beginPacket(address, 123);
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();
  return 0;
  //unsigned long sendNTPpacket() function ends here
  }
*/

markdh102
Posts: 11
Joined: Sat Apr 18, 2020 12:03 pm

Re: Esp32 BLE Connect and disconnect issue

Postby markdh102 » Thu Jun 18, 2020 9:21 am

I use the 1.0.0.4 Arduino libraries.
I have an ESP32 datalogger (to SD card). It connects to a BLE OBD2 scanner amongst other devices.
When logging is stopped I want to email the file to myself.
However, I could NEVER get this working. Either the WiFi would crash or the Bluetooth re-connection would hang.
I do not think that the WiFi and Bluetooth are able to work together.
My (admittedly) crude solution was to put a pushbutton on an input.
During logging there is no attempt made to connect to WiFi. Logging finishes. I power off. I then engage the pushbutton and power on again at which time the WiFi connection is made and the email is sent. (No attempt to use Bluetooth connection at all). I then power off, disengage the button and power back on again to connect to the Bluetooth OBD2 scanner.
Nasty, but it does what I need...

chegewara
Posts: 2378
Joined: Wed Jun 14, 2017 9:00 pm

Re: Esp32 BLE Connect and disconnect issue

Postby chegewara » Thu Jun 18, 2020 10:32 am

markdh102 wrote: I do not think that the WiFi and Bluetooth are able to work together.
Please dont say that out loud because someone may read it and believe it. Its NOT true.

Embel.Tech
Posts: 13
Joined: Tue Mar 03, 2020 5:26 am

Re: Esp32 BLE Connect and disconnect issue

Postby Embel.Tech » Fri Jun 19, 2020 7:40 am

Hello Guys,
I need solution on it.
Does my code is correct ?
can BLE work likewise?

color99
Posts: 2
Joined: Sun Oct 24, 2021 1:13 am

Re: Esp32 BLE Connect and disconnect issue

Postby color99 » Sun Oct 24, 2021 1:22 am

I am using latest arduino IDE to debug ESP32 Bluetooth project. I have the same problem. The ESP32 stop advertising after disconnect from a client. Where to add the code to my code?

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 110 guests