Esp32 BLE Connect and disconnect issue
Posted: 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
This is my server code
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
}
*/