BLE Arduino Uart Disconnects after connecting to Windows 10 client

gnorkus
Posts: 35
Joined: Thu Mar 22, 2018 12:41 pm

BLE Arduino Uart Disconnects after connecting to Windows 10 client

Postby gnorkus » Fri Mar 23, 2018 8:50 am

Hi,

I'm new to Esp32. I have 2 issues:

1. I designed and order some pcbs to use with the wrover module as a pedal input device. Below is some code I cobbled together from some of your sample user code. It seems to work ok with an android phone, but Windows 10, about 6 seconds after connecting properly, drops the connection. The message in the log for the disconnection is:
E (230557) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0013


2. The code is designed to go into deep sleep if the buttons aren't pressed after two minutes. However, when returning from sleep, it appears that the device cannot reestablish a connection with the Windows to client. I manually have to remove the device from the list of Bluetooth devices and reset the module to attempt connecting again. Of course, this is not proper behavior, so I'm missing something.

I believe that there may be some information I can store in the rtc memory to handle the reconnection problem. However, the drop connection is maddening.

Below is the code. It works identically on the Sparkfun ESP32 Thing as well as the wrover module. The idf in the background seems to be doing autodetect on the xtal frequency. I'm fairly proficient in c++, but not in esp-idf. (I have managed to compile the hid SampleHIDKeyboard code using the great instructions from nkolban. BUT it crashes on both of my boards during board reset.)

Any clues?

Code: Select all

/*
    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
    Ported to Arduino ESP32 by Evandro Copercini

   Create a BLE server that, once we receive a connection, will send periodic notifications.
   The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
   Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" 
   Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with  "NOTIFY"

   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.

   In this example rxValue is the data received (only accessible inside that function).
   And txValue is the data to be sent, in this example just a byte incremented every second. 
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <string>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_gatts_api.h"



#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
RTC_DATA_ATTR int bootCount = 0;
long wait_counter = 0 ;
long wait_amount = 50*120 ;  // 50x a second, 120 seconds

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
float txValue = 0;
const int LED = 5; // Could be different depending on the dev board. I used the DOIT ESP32 dev board.

//std::string rxValue; // Could also make this a global var to access it in loop()

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#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"


void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case 1  : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case 2  : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case 3  : Serial.println("Wakeup caused by timer"); break;
    case 4  : Serial.println("Wakeup caused by touchpad"); break;
    case 5  : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.println("Wakeup was not caused by deep sleep"); break;
  }
}

class MyServerCallbacks: public BLEServerCallbacks 
{
    void onConnect(BLEServer* pServer) 
    {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) 
    {
      deviceConnected = false;
    }
};

long nHiLo = LOW ;

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

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

BLEServer *pServer = 0 ;
BLEService *pService = 0 ;

int center, left, right ;
int centerPin = 0 ;
int leftPin = 21 ;
int rightPin = 25 ;
char txString[8]; 


void setup() 
{
  //
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  pinMode(centerPin, INPUT);
  delay(1000);

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_0,0); //1 = High, 0 = Low

  wait_counter = wait_amount ;      
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
  delay(1000);
  BLEDevice::init("ESP32 Envisic FootPedal"); // Give it a name    // Create the BLE Device
  pServer = BLEDevice::createServer();                        // Create the BLE Server
  pService = pServer->createService(SERVICE_UUID);            // Create the BLE Service
  pServer->setCallbacks(new MyServerCallbacks());

  pCharacteristic = pService->createCharacteristic(           // Create a BLE Characteristic
                      CHARACTERISTIC_UUID_TX,
                      BLECharacteristic::PROPERTY_NOTIFY
                    );
  pCharacteristic->addDescriptor(new BLE2902());
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_RX,
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setCallbacks(new MyCallbacks());
  pService->start();                                          // Start the service
  pServer->getAdvertising()->start();                         // Start advertising
  Serial.println("Waiting a client connection to notify...");
}



void loop() 
{
    // First, check the pins to find the one that is pressed.
    // The center button is pin0 and sends 'A' continuously when pressed
    //     left button is   pin  and sends 'B' continuously when pressed
    //     right button is  pin  and sends 'C' continuously when pressed
    center = digitalRead(centerPin);
    txString[1] = 0 ;
    if (center==0)
    {
        wait_counter = wait_amount ;
        txString[0] = 'A' ;
    }
    else
        txString[0] = 0 ;
        

  
    if (deviceConnected) 
    {
        // Let's convert the value to a char array:
        if (txString[0]>0) 
        {
            pCharacteristic->setValue(txString);
            pCharacteristic->notify(); // Send the value to the app!
            if (txString[0]=='A')
                Serial.println("Sent A");
        }
    }

    if (wait_counter==0)
    {
        Serial.println("Going to sleep now");

        // Start advertising
        pServer->getAdvertising()->stop();
        ::esp_ble_gatts_stop_service(pService->getHandle()) ;
        ::esp_ble_gatts_delete_service(pService->getHandle()) ;
        ::esp_bt_controller_disable() ;
        ::esp_bt_controller_deinit() ;

        esp_deep_sleep_start();
        Serial.println("This will never be printed");
    }
    else
    {
        delay(20);  // 50x a second, 20ms delay
        wait_counter = wait_counter - 1 ;
        digitalWrite(LED, ((wait_counter/50)%2)?HIGH:LOW) ;
        Serial.println("Count down=" + String(wait_counter) + "  center=" + String(center) ) ;
    }
}








Who is online

Users browsing this forum: No registered users and 112 guests