0

I'm new to using the esp32 as a microcontroller. I'm currently working on a so-to-say remote control. Since I want to use the esp32 with an external battery I need to put it in deep-sleep after I pressed some buttons to preserve battery.

All that works fine I've connected a small touchpad to put the esp32 into deep sleep mode using the esp_deep_sleep_start() function . The controller itself goes to sleep and can be woken up using the following 2 lines:

  touchAttachInterrupt(T0, wakeCallback, TOUCH_THRESHOLD);
  esp_sleep_enable_touchpad_wakeup();

In order to communicate with my Raspberry Pi 'Base Station' I decided to use BLE. My server is configured the following way (where bleServer, bleCharacteristic and bleService are global variables):

  BLEDevice::init("esp-32-remote");
  bleServer = BLEDevice::createServer();
  bleServer->setCallbacks(new ServerCallbacks());

  bleService = bleServer->createService(SERVICE_UUID);
  bleCharacteristic = bleService->createCharacteristic(
                        CHARACTERISTIC_UUID,
                        BLECharacteristic::PROPERTY_READ |
                        BLECharacteristic::PROPERTY_WRITE
                      );

  bleCharacteristic->addDescriptor(new BLE2902());
  bleService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();

Upon regular restart using the buttons everything works fine. I can connect to the device using python and the bluepy library.

If I now wake the controller I can't do anything anymore. The setup() function gets called and there are no errors, nor does the controller crash due to any code errors (seemingly).

Then the loop function gets called once, and thats it. I can't connect to the device anymore until I press the hardware reset button.

The questions that arise are:

  • might there be some error in the way I shutdown the bluetooth module?
  • Does the loop function work after being woken up from deep sleep?

Maybe one of you has an idea regarding my issue. If there are more information that I need to provide, don't hesitate to tell me, I'm new to the whole mcu topic and I don't know whats best to provide here.

2 Answers 2

2

Does the loop function work after being woken up from deep sleep? YES

loop function isn't magical. its just a function that gets called over and over. In other words, if it gets called once, it can be called again except if

  • it did something to deactivate itself
  • never reached the end

during that first call. Check that you are not activating some sort of state inside the loop or going into a blocking call awaiting a signal that is never sent.

For good measure, make sure to reset all your variables to their expected states - expecting something to be 0 or set via the original definition may be insufficient. This is something that occurs on a power reset so if reset is making it work again, thats a likely culprit. Use a bare minimum of code in the loop for debug so you can figure it out.

2
  • Thanks for the answer I'll look into that. Do you have any recommendation regarding the BLE issue?
    – hGen
    Commented Aug 27, 2020 at 9:32
  • I do not at this time. I did read that a "the TV Begone remote control" intentionally went to a sleep without wake upon sending a power off signal, and tied into the reset button for waking again, so be careful what you copy and from where. gammon.com.au/power
    – Abel
    Commented Aug 28, 2020 at 7:23
0

There's a good tutorial here on how to connect the BLE server client to the ESP32. And a Good fix here for reconnection issues.

Below is a piece of prototype code I wrote for BLE server client connectivity:

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      deviceDisconnected=false;
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_GREEN;
      interface->onBoardLED->statusLED(100, 1);
      BLEDevice::startAdvertising();
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
      interface->onBoardLED->statusLED(100, 1);
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
      interface->onBoardLED->statusLED(100, 1);
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
      interface->onBoardLED->statusLED(100, 1);
      pServer->getAdvertising()->start();
    }
};

class pCharacteristicTX_Callbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
    
      if (rxValue.length() > 0) {
        String msg="";
        mserial->printStrln("*********");
        mserial->printStr("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++) {
           msg=msg+String(rxValue[i]);
           mserial->printStr(String(rxValue[i])); 
        } 
      
        mserial->printStrln(""); 
        mserial->printStrln("*********");

        //valueReceived=msg;
      } 
    }

    void onRead(BLECharacteristic *pCharacteristic) {
      mserial->printStrln("*********");
      mserial->printStr("onRead...");    
      pCharacteristic->setValue("OK");
    }

  }; 
                    
class pCharacteristicRX_Callbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
      
      mserial->ble=false;

      if (rxValue.length() > 0) {
        String msg="";
        mserial->printStr("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++) {
           msg=msg+String(rxValue[i]);
           mserial->printStr(String(rxValue[i])); 
        } 
      
        msg.trim();
        $BLE_CMD=msg;
        mserial->ble=true;
        newCMDarrived=true;
      }
    } 

    void onRead(BLECharacteristic *pCharacteristic) {
      mserial->printStrln("*********");
      mserial->printStr("onRead...");    
      pCharacteristic->setValue("OK");
    }

  }; 

//------------------------------------------------------------------


// Create the BLE Device 
  BLEDevice::init("Smart Concrete Curing");  // Give it a name 
  
  // Create the BLE Server 
  pServer = BLEDevice::createServer(); 
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  pService = pServer->createService(SERVICE_UUID);
  
  // Create a BLE Characteristic

  pCharacteristicTX = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_TX,
                      BLECharacteristic::PROPERTY_NOTIFY
                    );


  pCharacteristicTX->addDescriptor(new BLE2902());

  pCharacteristicRX = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_RX,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  pCharacteristicTX->setCallbacks(new pCharacteristicTX_Callbacks());
  pCharacteristicRX->setCallbacks(new pCharacteristicRX_Callbacks());

  interface->init_BLE(pCharacteristicTX);

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

on this particular code, I'm using light sleep , so to go to sleep :

      btStop();
      delay(1000);
      WiFi.disconnect(true);
      WiFi.mode(WIFI_OFF);

      changeMcuFreq(interface, interface->MIN_MCU_FREQUENCY);

and to wake up :

changeMcuFreq(interface, interface->WIFI_FREQUENCY);
btStart();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.