Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLE Transfer data #8406

Closed
1 task done
savagerex opened this issue Jul 13, 2023 · 3 comments
Closed
1 task done

BLE Transfer data #8406

savagerex opened this issue Jul 13, 2023 · 3 comments
Assignees
Labels
Area: BLE Issues related to BLE Type: Question Only question

Comments

@savagerex
Copy link

Board

ESP32 S3

Device Description

Sensor - IIS3DWB

Flash

Hardware Configuration

NONE

Version

v2.0.9

IDE Name

Arduino

Operating System

Windows 11

Flash frequency

80M

PSRAM enabled

no

Upload speed

921600

Description

When i use mobile APP transfer data to ESP32 S3 by BLE.

but after several times, esp32 will reset.

Sketch

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <nvs.h>
#include <nvs_flash.h>
#include "Sensor.h"
#include "BleTask.h"
#include "SensorPreferences.h"
#include "LedBlinker.h"
#include "BoardConfig.h"
#include <WiFi.h>
#include <ArduinoJson.h>

BLEServer *pServer = NULL;
static BLECharacteristic * pTxCharacteristic = NULL;
static bool deviceConnected = false;
static bool oldDeviceConnected = false;
static uint8_t txValue = 0;

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

/** SSIDs of local WiFi networks */
static String ssidPrim = "";
static String ssidSec = "";
/** Password for local WiFi network */
static String pwPrim = "";
static String pwSec = "";

static int rtcYear;
static int rtcMonth;
static int rtcDay;
static int rtcHour;
static int rtcMinute;
static int rtcSecond;



static String mqttServer = "";
static String mqttUserName = "";
static String mqttPw = "";
static String SensorId = "";
static String GValue = "";

static String DeviceId = "";

static int rtcStartYear;
static int rtcStartMonth;
static int rtcStartDay;
static int rtcEndYear;
static int rtcEndMonth;
static int rtcEndDay;
static int RecordTime;
static int SleepTime;
static String SetOnOff = "";

static String DateMon = "";
static String DateTue = "";
static String DateWed = "";
static String DateThu = "";
static String DateFri = "";
static String DateSat = "";
static String DateSun = "";

int SetWifiFlag = 0;
int SetRtcFlag = 0;
int SetMqttServerFlag = 0;
int ScheduleFlag = 0;
int GoingScheduleFlag = 0;
int SetSensorIdFlag = 0;

static DynamicJsonDocument jsonBuffer(1024);   //512
static StaticJsonDocument<256> jsonResult;

//ESP32Time rtc(3600);

extern unsigned long BleStartTime;
extern unsigned long BleEndTime;
extern unsigned long AbsBleTime;

extern int BleConnect;
extern int BleDisConnect;

extern int SensorValue;

void ParseReceivedData(String receivedData);

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      BleConnect = 1;
      BleDisConnect = 0;
      Serial.println("Ble Connect");
      led_quick_blink();
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      BleDisConnect = 1;
      BleConnect = 0;
      Serial.println("Ble DisConnect");
      led_on();
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
//        Serial.println("*********");
//        Serial.print("Received Value: ");
//        for (int i = 0; i < rxValue.length(); i++)
//          Serial.print(rxValue[i]);
          
        ParseReceivedData(rxValue.c_str());
//        Serial.println();
//        Serial.println("*********");
      }
    }
};

void BleUartTaskStep() {
  /*
  if (deviceConnected) {
      pTxCharacteristic->setValue(&txValue, 1);
      pTxCharacteristic->notify();
      txValue++;
      delay(10); // bluetooth stack will go into congestion, if too many packets are sent
  }
  */

  // disconnecting
  if (!deviceConnected && oldDeviceConnected) {
      delay(500); // give the bluetooth stack the chance to get things ready
      //BLEDevice::startAdvertising();
      pServer->startAdvertising(); // restart advertising
      Serial.println("start advertising");
      //SF_PRINTLN("[BleUart] Ble Start Advertising");
      //BleAdvertiseFlag =1;
      oldDeviceConnected = deviceConnected;
  }
  
  // connecting
  if (deviceConnected && !oldDeviceConnected) {
  // do stuff here on connecting
      oldDeviceConnected = deviceConnected;
  }
}

void BleStart()
{
    BleUartSetup();
    Serial.println("Ble Mode");
    BleStartTime = millis(); 
    led_on(); 
}

void BleStop()
{
   BLEDevice::deinit(false);
}

void BleUartSetup() {
  //Serial.begin(115200);
  //Serial.println("[BleUart] MethodCall BleUartSetup");
  SF_PRINTLN("[BleUart] MethodCall BleUartSetup");

  Preferences preferences;
  preferences.begin(PrefNamespace, false);
  String DeviceId = preferences.getString(PrefDeviceIdWrite, "");
  preferences.end();
  Serial.println(DeviceId);

  String ShowData = DeviceId + "_" + "AISSENS100AW";

  
  // Create the BLE Device
  //BLEDevice::init("UART Service");
  BLEDevice::init(ShowData.c_str());
  //BLEDevice::setMTU(mtu);

//  BLEAdvertisementData advertisementData;
//  char manData[] = {0x00,0xff,0x28,0x50};
//  advertisementData.setManufacturerData(std::string(manData, sizeof manData));

//  BLEAdvertisementData advdata = BLEAdvertisementData();
//  String servicedata = "Hello";
//  advdata.setManufacturerData(servicedata.c_str());

  // Create the BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);
  pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pTxCharacteristic = pService->createCharacteristic(
                    CHARACTERISTIC_UUID_TX,
                    BLECharacteristic::PROPERTY_NOTIFY
                  );

  pTxCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
                       CHARACTERISTIC_UUID_RX,
                      BLECharacteristic::PROPERTY_WRITE
                    );

  pRxCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  // pServer->getAdvertising()->start(); // for backward compability
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  //Serial.printf("[BleUart] UART Service started(BLE address: %s), waiting a client connection to notify ...\n", BLEDevice::getAddress().toString().c_str());
}

void ParseReceivedData(String receivedData) {
  receivedData.trim();
  
  Serial.println("Received message " + receivedData + " over Bluetooth");

  /** Json object for incoming data */
  auto error = deserializeJson(jsonBuffer, receivedData);

  if (!error) {
        if (jsonBuffer.containsKey("SsidPrim")) {
        ssidPrim = jsonBuffer[PrefSsidPrim].as<String>();
        pwPrim = jsonBuffer[PrefPwPrim].as<String>();
         
        Preferences preferences;
        preferences.begin(PrefNamespace, false);
        if (jsonBuffer.containsKey(PrefSsidPrim)) {
          preferences.putString(PrefSsidPrim, ssidPrim);
        }
        if (jsonBuffer.containsKey(PrefPwPrim)) {
          preferences.putString(PrefPwPrim, pwPrim);
        }
        preferences.end();

        WirelessMode = WIFI_MODE;
        SetWifiFlag = 1;

              if (deviceConnected) {
                 String result;
                 jsonResult.clear();
                 jsonResult["Version_Info"] = "Ver0.0";
                 jsonResult["Command_Id"] = "SET_WIFI_CONNECT";
                 jsonResult["Error_Code"] = "Success";
                  if ((WiFi.status() != WL_CONNECTED))
                  {
                      jsonResult[PrefWifiStatus] = "DisConnect";
                  }
                  else
                  {
                      jsonResult[PrefWifiStatus] = "Connect";
                  }
                 serializeJson(jsonResult, result);
                 result += "\n";
                 pTxCharacteristic->setValue(result.c_str());
                 pTxCharacteristic->notify();
              } else {
                String result;
                jsonResult.clear();
                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                jsonResult[PrefStatus] = PrefStatusError; 
                jsonResult[PrefMessage] = "error input"; 
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify(); 
                
            }

//              if (deviceConnected) {
//              String result;
//              jsonResult.clear();
//              jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
//              jsonResult[PrefStatus] = PrefStatusSuccess;
//              jsonResult[PrefFirmwareVersion] = "0.0";
//              jsonResult[PrefConfigurationVersion] = "0.0";
//              Preferences preferences;
//              preferences.begin(PrefNamespace, false);
//              SensorId = preferences.getString(PrefSensorId,"");
//              if (SensorId == NULL)
//              {
//                 jsonResult[PrefSensorId] = "Please Enter Sensor Id";
//              } else {
//                 jsonResult[PrefSensorId] = SensorId;
//              }
//              jsonResult[PrefBrand] = "ASUS";
//              jsonResult[PrefModel] = "AISSENS100AW";
//              jsonResult[PrefBandwidth] = "abc";
//              jsonResult[PrefSamplingRate] = "4K";
//              GValue = preferences.getString(PrefGValue,"");
//              if (SensorId == NULL)
//              {
//                jsonResult[PrefGValue] = "8G";
//              } else {
//                jsonResult[PrefGValue] = GValue;
//              }
//              preferences.end();
//              jsonResult[PrefMessage] = "update success";
//              serializeJson(jsonResult, result);
//              result += "\n";
//              pTxCharacteristic->setValue(result.c_str());
//              pTxCharacteristic->notify();        
//            } else {
//                String result;
//                jsonResult.clear();
//                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
//                jsonResult[PrefStatus] = PrefStatusError; 
//                jsonResult[PrefMessage] = "error input"; 
//                serializeJson(jsonResult, result);
//                result += "\n";
//                pTxCharacteristic->setValue(result.c_str());
//                pTxCharacteristic->notify(); 
//                
//            }
        
//        WirelessMode = WIFI_MODE;
//        SetWifiFlag = 1;
        }
        else if (jsonBuffer.containsKey("Year"))
        {
            rtcYear = jsonBuffer[PrefYear].as<int>();
            rtcMonth = jsonBuffer[PrefMonth].as<int>();
            rtcDay = jsonBuffer[PrefDay].as<int>();
            rtcHour = jsonBuffer[PrefHour].as<int>();
            rtcMinute = jsonBuffer[PrefMinute].as<int>();
            rtcSecond = jsonBuffer[PrefSecond].as<int>();

            Preferences preferences;
            preferences.begin(PrefNamespace, false);
            if (jsonBuffer.containsKey(PrefYear)) {
            preferences.putInt(PrefYear, rtcYear);
            }
            if (jsonBuffer.containsKey(PrefMonth)) {
              preferences.putInt(PrefMonth, rtcMonth);
            }
            if (jsonBuffer.containsKey(PrefDay)) {
              preferences.putInt(PrefDay, rtcDay);
            }
            if (jsonBuffer.containsKey(PrefHour)) {
              preferences.putInt(PrefHour, rtcHour);
            }
            if (jsonBuffer.containsKey(PrefMinute)) {
              preferences.putInt(PrefMinute, rtcMinute);
            }
            if (jsonBuffer.containsKey(PrefSecond)) {
              preferences.putInt(PrefSecond, rtcSecond);
            }
            preferences.end();

            if (deviceConnected) {
              String result;
              jsonResult.clear();
              jsonResult["Version_Info"] = "Ver0.0";
              jsonResult["Command_Id"] = "SET_RTC";
              jsonResult["Error_Code"] = "Success";
              serializeJson(jsonResult, result);
              result += "\n";
              pTxCharacteristic->setValue(result.c_str());
              pTxCharacteristic->notify();        
              } else {
                String result;
                jsonResult.clear();
                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                jsonResult[PrefStatus] = PrefStatusError; 
                jsonResult[PrefMessage] = "error input"; 
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify(); 
                
              }
            
            SetRtcFlag =1;
        }
        else if (jsonBuffer.containsKey("MqttServer"))
        {
            mqttServer = jsonBuffer[PrefMqttServer].as<String>();
            mqttPw = jsonBuffer[PrefMqttPw].as<String>();

            Preferences preferences;
            preferences.begin(PrefNamespace, false);
            if (jsonBuffer.containsKey(PrefMqttServer)) {
              preferences.putString(PrefMqttServer, mqttServer);
            }
            if (jsonBuffer.containsKey(PrefMqttPw)) {
              preferences.putString(PrefMqttPw, mqttPw);
            }
            preferences.end();

            if (deviceConnected) {
              String result;
              jsonResult.clear();
              jsonResult["Version_Info"] = "Ver0.0";
              jsonResult["Command_Id"] = "SET_MQTT_SETTING";
              jsonResult["Error_Code"] = "Success";
              serializeJson(jsonResult, result);
              result += "\n";
              pTxCharacteristic->setValue(result.c_str());
              pTxCharacteristic->notify();        
              } else {
                String result;
                jsonResult.clear();
                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                jsonResult[PrefStatus] = PrefStatusError; 
                jsonResult[PrefMessage] = "error input"; 
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify(); 
                
              }
            
            SetMqttServerFlag = 1;

            
            
        } 
        else if (jsonBuffer.containsKey("MqttUserName"))
        {
          mqttUserName = jsonBuffer[PrefMqttUserName].as<String>();
          mqttPw = jsonBuffer[PrefMqttPw].as<String>();

            Preferences preferences;
            preferences.begin(PrefNamespace, false);
            if (jsonBuffer.containsKey(PrefMqttUserName)) {
              preferences.putString(PrefMqttUserName, mqttUserName);
            }
            if (jsonBuffer.containsKey(PrefMqttPw)) {
              preferences.putString(PrefMqttPw, mqttPw);
            }
            preferences.end();

            if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                jsonResult[PrefStatus] = PrefStatusSuccess;
                jsonResult[PrefMessage] = "update success";
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();        
                } else {
                  String result;
                  jsonResult.clear();
                  jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                  jsonResult[PrefStatus] = PrefStatusError; 
                  jsonResult[PrefMessage] = "error input"; 
                  serializeJson(jsonResult, result);
                  result += "\n";
                  pTxCharacteristic->setValue(result.c_str());
                  pTxCharacteristic->notify(); 
                  
                }

                SetMqttServerFlag = 1;

          
        } else if (jsonBuffer.containsKey("StartYear")) {
               rtcStartYear = jsonBuffer[PrefStartYear].as<int>();
               rtcStartMonth = jsonBuffer[PrefStartMonth].as<int>();
               rtcStartDay = jsonBuffer[PrefStartDay].as<int>();
               rtcEndYear = jsonBuffer[PrefEndYear].as<int>();
               rtcEndMonth = jsonBuffer[PrefEndMonth].as<int>();
               rtcEndDay = jsonBuffer[PrefEndDay].as<int>();
               RecordTime = jsonBuffer[PrefRecordTime].as<int>();
               SleepTime = jsonBuffer[PrefSleepTime].as<int>();
               SetOnOff = jsonBuffer[PrefSleepTime].as<String>();

                Preferences preferences;
                preferences.begin(PrefNamespace, false);
                if (jsonBuffer.containsKey(PrefStartYear)) {
                preferences.putInt(PrefStartYear, rtcStartYear);
                }
                if (jsonBuffer.containsKey(PrefStartMonth)) {
                  preferences.putInt(PrefStartMonth, rtcStartMonth);
                }
                if (jsonBuffer.containsKey(PrefStartDay)) {
                  preferences.putInt(PrefStartDay, rtcStartDay);
                }
                if (jsonBuffer.containsKey(PrefEndYear)) {
                preferences.putInt(PrefEndYear, rtcEndYear);
                }
                if (jsonBuffer.containsKey(PrefEndMonth)) {
                  preferences.putInt(PrefEndMonth, rtcEndMonth);
                }
                if (jsonBuffer.containsKey(PrefEndDay)) {
                  preferences.putInt(PrefEndDay, rtcEndDay);
                }
                if (jsonBuffer.containsKey(PrefRecordTime)) {
                  preferences.putInt(PrefRecordTime, RecordTime);
                }
                if (jsonBuffer.containsKey(PrefSleepTime)) {
                  preferences.putInt(PrefSleepTime, SleepTime);
                }
                if (jsonBuffer.containsKey(PrefSet)) {
                  preferences.putString(PrefSet, SetOnOff);
                }
                preferences.end();

                if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult["Version_Info"] = "Ver0.0";
                jsonResult["Command_Id"] = "Cmd_schedule_connect";
                jsonResult["Error_Code"] = "Success";
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();        
                } else {
                  String result;
                  jsonResult.clear();
                  jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                  jsonResult[PrefStatus] = PrefStatusError; 
                  jsonResult[PrefMessage] = "error input"; 
                  serializeJson(jsonResult, result);
                  result += "\n";
                  pTxCharacteristic->setValue(result.c_str());
                  pTxCharacteristic->notify(); 
                  
                }

                if (SetOnOff == "On")
                {
                   ScheduleFlag = 1;
                   GoingScheduleFlag = 1;
                }
        } else if (jsonBuffer.containsKey("Status")) {


          if (deviceConnected) {
              String result;
              jsonResult.clear();
              jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
              jsonResult[PrefStatus] = PrefStatusSuccess;
              if ((WiFi.status() != WL_CONNECTED))
              {
                  jsonResult[PrefWifiStatus] = "DisConnect";
              }
              else
              {
                  jsonResult[PrefWifiStatus] = "Connect";
                  Preferences preferences;
                  preferences.begin(PrefNamespace, false);
                  String ssidPrim = preferences.getString(PrefSsidPrim, ""); //SSID
                  preferences.end();
                  String LocalIp = WiFi.localIP().toString();//IP
                  jsonResult[PrefSsidPrim] = ssidPrim;
                  jsonResult[PrefLocalIp] = LocalIp;
              }

              SensorValue = analogRead(SensorPin);

              if(SensorValue <4095 && SensorValue >= 3276)
              {
                 jsonResult[PrefBatteryStatus] = "4";
              } 
              else if(SensorValue < 3276 && SensorValue >= 2457)
              {
                 jsonResult[PrefBatteryStatus] = "3";
              }
              else if(SensorValue < 2457 && SensorValue >= 1638)
              {
                 jsonResult[PrefBatteryStatus] = "2";
              }
              else if(SensorValue < 1638 && SensorValue >= 819)
              {
                 jsonResult[PrefBatteryStatus] = "1";
              }
              else if(SensorValue < 819)
              {
                 jsonResult[PrefBatteryStatus] = "0";
              }

              int a = WiFi.RSSI();
              int rssi;
              if(a<0 && a>-50)
              {
                 rssi = 4;
              }
              else if(a<-50 && a>-60)
              {
                 rssi = 3;
              }
              else if(a<-60 && a>-70)
              {
                 rssi = 2;
              }
              else if(a<-70)
              {
                 rssi = 1;
              }
              jsonResult["SignalStrength"] = rssi;
               
              jsonResult[PrefMessage] = "update success";
              serializeJson(jsonResult, result);
              result += "\n";
              pTxCharacteristic->setValue(result.c_str());
              pTxCharacteristic->notify();        
            }
          

          if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                jsonResult[PrefStatus] = PrefStatusSuccess;
                jsonResult[PrefMessage] = "update success";
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();        
                } else {
                  String result;
                  jsonResult.clear();
                  jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                  jsonResult[PrefStatus] = PrefStatusError; 
                  jsonResult[PrefMessage] = "error input"; 
                  serializeJson(jsonResult, result);
                  result += "\n";
                  pTxCharacteristic->setValue(result.c_str());
                  pTxCharacteristic->notify(); 
                  
                }
        } else if (jsonBuffer.containsKey("SensorId")) {
            SensorId = jsonBuffer[PrefSensorId].as<String>();

            Preferences preferences;
            preferences.begin(PrefNamespace, false);
            if (jsonBuffer.containsKey(PrefSensorId)) {
              preferences.putString(PrefSensorId, SensorId);
            }
            preferences.end();
            SetSensorIdFlag = 1;
        } else if (jsonBuffer.containsKey("GValue")) {
           GValue = jsonBuffer[PrefGValue].as<String>();

           Preferences preferences;
            preferences.begin(PrefNamespace, false);
            if (jsonBuffer.containsKey(PrefGValue)) {
              preferences.putString(PrefGValue, GValue);
            }
            preferences.end();

        } else if (jsonBuffer.containsKey("Mon")) {
               DateMon = jsonBuffer[PrefDateMon].as<String>();
               DateTue = jsonBuffer[PrefDateTue].as<String>();
               DateWed = jsonBuffer[PrefDateWed].as<String>();
               DateThu = jsonBuffer[PrefDateThu].as<String>();
               DateFri = jsonBuffer[PrefDateFri].as<String>();
               DateSat = jsonBuffer[PrefDateSat].as<String>();
               DateSun = jsonBuffer[PrefDateSun].as<String>();

                Preferences preferences;
                preferences.begin(PrefNamespace, false);
                if (jsonBuffer.containsKey(PrefDateMon)) {
                preferences.putString(PrefDateMon, DateMon);
                }
                if (jsonBuffer.containsKey(PrefDateTue)) {
                  preferences.putString(PrefDateTue, DateTue);
                }
                if (jsonBuffer.containsKey(PrefDateWed)) {
                  preferences.putString(PrefDateWed, DateWed);
                }
                if (jsonBuffer.containsKey(PrefDateThu)) {
                preferences.putString(PrefDateThu, DateThu);
                }
                if (jsonBuffer.containsKey(PrefDateFri)) {
                  preferences.putString(PrefDateFri, DateFri);
                }
                if (jsonBuffer.containsKey(PrefDateSat)) {
                  preferences.putString(PrefDateSat, DateSat);
                }
                if (jsonBuffer.containsKey(PrefDateSun)) {
                  preferences.putString(PrefDateSun, DateSun);
                }
                preferences.end();
        }  else if (jsonBuffer.containsKey("DeviceIdWrite")) {
                DeviceId = jsonBuffer[PrefDeviceIdWrite].as<String>();

                Preferences preferences;
                preferences.begin(PrefNamespace, false);
                if (jsonBuffer.containsKey(PrefDeviceIdWrite)) {
                preferences.putString(PrefDeviceIdWrite, DeviceId);
                }
                preferences.end();

                if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                jsonResult[PrefStatus] = PrefStatusSuccess;
                jsonResult[PrefMessage] = "update success";
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();        
                } else {
                  String result;
                  jsonResult.clear();
                  jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                  jsonResult[PrefStatus] = PrefStatusError; 
                  jsonResult[PrefMessage] = "error input"; 
                  serializeJson(jsonResult, result);
                  result += "\n";
                  pTxCharacteristic->setValue(result.c_str());
                  pTxCharacteristic->notify(); 
                  
                }
        } else if (jsonBuffer.containsKey("DeviceIdRead")) {
                Preferences preferences;
                preferences.begin(PrefNamespace, false);
                DeviceId = preferences.getString(PrefDeviceIdWrite, "");
                preferences.end();

                if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                jsonResult[PrefDeviceIdRead] = DeviceId;
                jsonResult[PrefStatus] = PrefStatusSuccess;
                jsonResult[PrefMessage] = "update success";
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();        
                } else {
                  String result;
                  jsonResult.clear();
                  jsonResult[PrefBluetoothMac] = mac2String(BluetoothMac);
                  jsonResult[PrefStatus] = PrefStatusError; 
                  jsonResult[PrefMessage] = "error input"; 
                  serializeJson(jsonResult, result);
                  result += "\n";
                  pTxCharacteristic->setValue(result.c_str());
                  pTxCharacteristic->notify(); 
                  
                }
                
        } else if (jsonBuffer.containsKey("PageWifiInfoA")) {
                if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult["Version_Info"] = "Ver0.0";
                jsonResult["Command_Id"] = "GET_WIFI_PROVISION";
                jsonResult["Error_Code"] = "Success";
                Preferences preferences;
                preferences.begin(PrefNamespace, false);
                String DeviceId = preferences.getString(PrefDeviceIdWrite, "");
                preferences.end();
                jsonResult["SensorId"] = DeviceId;
                jsonResult["ModelName"] = "AISSENS100AW";
                preferences.begin(PrefNamespace, false);
                String ssidPrim = preferences.getString(PrefSsidPrim, ""); //SSID
                preferences.end();
                jsonResult["Ssid"] = ssidPrim;
                if ((WiFi.status() != WL_CONNECTED))
                {
                    jsonResult["WifiStatus"] = "DisConnect";
                }
                else
                {
                    jsonResult["WifiStatus"] = "Connect";
                }

                int a = WiFi.RSSI();
                int rssi;
                if(a<0 && a>-50)
                {
                   rssi = 4;
                }
                else if(a<-50 && a>-60)
                {
                   rssi = 3;
                }
                else if(a<-60 && a>-70)
                {
                   rssi = 2;
                }
                else if(a<-70)
                {
                   rssi = 1;
                }
                jsonResult["SignalStrength"] = rssi;
                String LocalIp = WiFi.localIP().toString();//IP
                jsonResult[PrefLocalIp] = LocalIp;
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();
                }
        } else if (jsonBuffer.containsKey("PageWifiInfoB")) {
               if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult["Version_Info"] = "Ver0.0";
                jsonResult["Command_Id"] = "Cmd_wifi_devie_infomation_connect";
                jsonResult["Error_Code"] = "Success";

                SensorValue = analogRead(SensorPin);

              if(SensorValue <4095 && SensorValue >= 3276)
              {
                 jsonResult[PrefBatteryStatus] = "4";
              } 
              else if(SensorValue < 3276 && SensorValue >= 2457)
              {
                 jsonResult[PrefBatteryStatus] = "3";
              }
              else if(SensorValue < 2457 && SensorValue >= 1638)
              {
                 jsonResult[PrefBatteryStatus] = "2";
              }
              else if(SensorValue < 1638 && SensorValue >= 819)
              {
                 jsonResult[PrefBatteryStatus] = "1";
              }
              else if(SensorValue < 819)
              {
                 jsonResult[PrefBatteryStatus] = "0";
              }
                
                Preferences preferences;
                preferences.begin(PrefNamespace, false);
                String DeviceId = preferences.getString(PrefDeviceIdWrite, "");
                preferences.end();
                jsonResult["SensorId"] = DeviceId;
                jsonResult["ModelName"] = "AISSENS100AW";
                jsonResult["Brand"] = "ASUS";
                jsonResult["Bandwidth"] = "1K";
                jsonResult["SamplingRate"] = "4K";
                GValue = preferences.getString(PrefGValue,"");
                if (SensorId == NULL)
                {
                  jsonResult["GValue"] = "8G";
                } else {
                  jsonResult["GValue"] = GValue;
                }
                preferences.end();
                jsonResult["FirmwareVersion"] = "0.0";
                jsonResult["ConfigurationVersion"] = "0.0";

                preferences.begin(PrefNamespace, false);
                String ssidPrim = preferences.getString(PrefSsidPrim, ""); //SSID
                preferences.end();
                jsonResult["Ssid"] = ssidPrim;
                if ((WiFi.status() != WL_CONNECTED))
                {
                    jsonResult["WifiStatus"] = "DisConnect";
                }
                else
                {
                    jsonResult["WifiStatus"] = "Connect";
                }

                int a = WiFi.RSSI();
                int rssi;
                if(a<0 && a>-50)
                {
                   rssi = 4;
                }
                else if(a<-50 && a>-60)
                {
                   rssi = 3;
                }
                else if(a<-60 && a>-70)
                {
                   rssi = 2;
                }
                else if(a<-70)
                {
                   rssi = 1;
                }
                jsonResult["SignalStrength"] = rssi;
                String LocalIp = WiFi.localIP().toString();//IP
                jsonResult[PrefLocalIp] = LocalIp;

                preferences.begin(PrefNamespace, false);
                String mqttServer = preferences.getString(PrefMqttServer, "");
                preferences.end();
                jsonResult["MqttAddress"] = mqttServer;

                preferences.begin(PrefNamespace, false);
                String mqttPw = preferences.getString(PrefMqttPw, "");
                preferences.end();
                jsonResult["MqttPassword"] = mqttPw;

                preferences.begin(PrefNamespace, false);
                rtcStartYear = preferences.getInt(PrefStartYear);
                rtcStartMonth = preferences.getInt(PrefStartMonth);
                rtcStartDay = preferences.getInt(PrefStartDay);
                rtcEndYear = preferences.getInt(PrefEndYear);
                rtcEndMonth = preferences.getInt(PrefEndMonth);
                rtcEndDay = preferences.getInt(PrefEndDay);
                RecordTime = preferences.getInt(PrefRecordTime);
                SleepTime = preferences.getInt(PrefSleepTime);
                SetOnOff = preferences.getString(PrefSet, "");

                DateMon = preferences.getString(PrefDateMon, "");
                DateTue = preferences.getString(PrefDateTue, "");
                DateWed= preferences.getString(PrefDateWed, "");
                DateThu = preferences.getString(PrefDateThu, "");
                DateFri = preferences.getString(PrefDateFri, "");
                DateSat = preferences.getString(PrefDateSat, "");
                DateSun = preferences.getString(PrefDateSun, "");
                preferences.end();

                jsonResult["StartYear"] = rtcStartYear;
                jsonResult["StartMonth"] = rtcStartMonth;
                jsonResult["StartDay"] = rtcStartDay;
                jsonResult["EndYear"] = rtcEndYear;
                jsonResult["EndMonth"] = rtcEndMonth;
                jsonResult["EndDay"] = rtcEndDay;
                jsonResult["SamplingTime"] = RecordTime;
                jsonResult["IntervalFrequency"] = SleepTime;
                jsonResult["On/Off"] = SetOnOff;

                jsonResult["Mon"] = DateMon;
                jsonResult["Tue"] = DateTue;
                jsonResult["Wed"] = DateWed;
                jsonResult["Thu"] = DateThu;
                jsonResult["Fri"] = DateFri;
                jsonResult["Sat"] = DateSat;
                jsonResult["Sun"] = DateSun;

                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();
                
               }
        } else if (jsonBuffer.containsKey("WifiList")) {

          if (deviceConnected) {
                String result;
                jsonResult.clear();
                jsonResult["Version_Info"] = "Ver0.0";
                jsonResult["Command_Id"] = "Cmd_wifi_list_connect";
                jsonResult["Error_Code"] = "Success";
                int n = WiFi.scanNetworks();
                if (n == 0) {
                    jsonResult["List"] = "no networks found";
                }else {
                    for (int i = 0; i < n; ++i) {
                       jsonResult["List"] = WiFi.SSID(i);
                       jsonResult["WifiSignal"] = WiFi.RSSI(i);
                    }
                }
                serializeJson(jsonResult, result);
                result += "\n";
                pTxCharacteristic->setValue(result.c_str());
                pTxCharacteristic->notify();
          }
          
        }
        
  } else {
    Serial.println("Received invalid JSON");
  }
  
}

Debug Message

Received message {"SsidPrim":"ASUS-38", "PwPrim":"12345678"} over Bluetooth




Backtrace: 0xfffffffe:0x80381fb8 |<-CORRUPTED




ELF file SHA256: ecc258b6f93a6885

Rebooting...
x⸮⸮ESP-ROM:esp32s3-20210327

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@savagerex savagerex added the Status: Awaiting triage Issue is waiting for triage label Jul 13, 2023
@savagerex
Copy link
Author

Somteimes debug message

Received message {"SsidPrim":"ASUS-38", "PwPrim":"12345678"} over Bluetooth
Guru Meditation Error: Core 0 panic'ed (Unhandled debug exception).
Debug exception reason: Stack canary watchpoint triggered (BTC_TASK)
Core 0 register dump:
PC : 0x40379801 PS : 0x00060e36 A0 : 0x3fcbd130 A1 : 0x3fcbd070
A2 : 0x3fcbd60c A3 : 0x3fcbd372 A4 : 0x00000002 A5 : 0x3c12b968
A6 : 0x02cc3bcc A7 : 0x00ffffff A8 : 0x00000001 A9 : 0x3fcbd60c
A10 : 0x00000034 A11 : 0x3fcd4878 A12 : 0x00000068 A13 : 0xbaad5678
A14 : 0x00060820 A15 : 0x00000001 SAR : 0x00000017 EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000 LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0x00000000

Backtrace: 0x403797fe:0x3fcbd070 0x3fcbd12d:0x3fcbd150 |<-CORRUPTED

ELF file SHA256: 16a5d47fb756a2a4

Rebooting...

@SuGlider
Copy link
Collaborator

@savagerex -

Based on the message Debug exception reason: Stack canary watchpoint triggered (BTC_TASK), it looks like the Bluetooth processing task has a small stack size for the processing done in BLECharacteristicCallbacks().

BLECharacteristicCallbacks() calls ParseReceivedData() which may be the place where the BLE processing task stack overflows.

My suggestion would be to just copy the BLE received data into a HEAP buffer (global array while in BLECharacteristicCallbacks()) and then signal to some other task (or even in loop()) to process the data outside of BLECharacteristicCallbacks().

A separated task can be created with a bigger stack size.
It is also possible to increase the stack size of the task that processes loop().

This is a similar issue to #7428
CONFIG_BT_BTC_TASK_STACK_SIZE=3072 - 3KB is the BTC task stack size.
It is defined in the sdkconfig of Arduino.

If necessary (which I think, it may not be the case), it is possible to turn this project into an Arduino as IDF Component project and then modify the BTC STACK SIZE to whatever you may need.

I think that it is always possible to rewrite the code and tasks architecture to solve it.
But, of course, this is your call.

@SuGlider SuGlider self-assigned this Jul 13, 2023
@SuGlider SuGlider added Type: Question Only question Area: BLE Issues related to BLE and removed Status: Awaiting triage Issue is waiting for triage labels Jul 13, 2023
@savagerex
Copy link
Author

OK!!! Thanks, it is solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: BLE Issues related to BLE Type: Question Only question
Projects
None yet
Development

No branches or pull requests

3 participants