ESP32 запускает BLE после глубокого сна

Я новичок в использовании esp32 в качестве микроконтроллера. Сейчас я работаю над так сказать пультом дистанционного управления. Поскольку я хочу использовать esp32 с внешней батареей, мне нужно перевести его в режим глубокого сна после того, как я нажал несколько кнопок, чтобы сохранить заряд батареи.

Все работает нормально. Я подключил небольшую сенсорную панель, чтобы перевести esp32 в режим глубокого сна с помощью функции esp_deep_sleep_start() . Сам контроллер переходит в спящий режим, и его можно разбудить с помощью следующих двух строк:

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

Для связи с моей «Базовой станцией» Raspberry Pi я решил использовать BLE. Мой сервер настроен следующим образом (где bleServer, bleCharacteristic и bleService — глобальные переменные):

  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();

При обычном перезапуске с помощью кнопок все работает нормально. Я могу подключиться к устройству с помощью python и библиотеки bluepy.

Если я сейчас разбужу контроллер, я больше ничего не смогу сделать. Функция setup() вызывается, и ошибок нет, а контроллер не выходит из строя из-за каких-либо ошибок кода (по-видимому).

Затем функция цикла вызывается один раз, и все. Я больше не могу подключиться к устройству, пока не нажму кнопку аппаратного сброса.

Возникают следующие вопросы:

  • Может ли быть какая-то ошибка при отключении модуля Bluetooth?
  • Работает ли функция цикла после пробуждения от глубокого сна?

Возможно, у кого-то из вас есть идеи относительно моей проблемы. Если мне нужно предоставить дополнительную информацию, не стесняйтесь сообщить мне, я новичок во всей теме mcu и не знаю, что лучше здесь предоставить.

, 👍0


2 ответа


2

Работает ли функция цикла после пробуждения от глубокого сна? ДА

функция цикла не волшебная. это просто функция, которая вызывается снова и снова. Другими словами, если он вызывается один раз, его можно вызвать снова, за исключением случаев, когда

  • он сделал что-то, чтобы деактивировать себя
  • никогда не доходил до конца

во время первого звонка. Убедитесь, что вы не активируете какое-то состояние внутри цикла или не входите в блокирующий вызов в ожидании сигнала, который никогда не отправляется.

На всякий случай не забудьте сбросить все свои переменные в их ожидаемые состояния — ожидание того, что что-то будет равно 0 или установлено с помощью исходного определения, может быть недостаточным. Это то, что происходит при сбросе питания, поэтому, если сброс заставляет его снова работать, это, вероятно, виновник. Используйте минимум кода в цикле отладки, чтобы вы могли разобраться.

,

Спасибо за ответ, я посмотрю на это. Есть ли у вас какие-либо рекомендации по проблеме BLE?, @hGen

Я не в это время. Я читал, что «пульт дистанционного управления TV Begone» намеренно перешел в спящий режим без пробуждения после отправки сигнала отключения питания и привязан к кнопке сброса для повторного пробуждения, поэтому будьте осторожны, что вы копируете и откуда. https://www.gammon.com.au/сила, @Abel


0

Есть хороший учебник здесь о том, как подключить клиент сервера BLE к ESP32. И хорошее исправление здесь для проблем с повторным подключением.

Ниже приведен фрагмент кода прототипа, который я написал для подключения клиента к серверу BLE:

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("*********");

        //значениеПолучено=сообщение;
      } 
    }

    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");
    }

  }; 

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


// Создаем BLE-устройство
  BLEDevice::init("Smart Concrete Curing");  // Даем ему имя
  
  // Создаем BLE-сервер
  pServer = BLEDevice::createServer(); 
  pServer->setCallbacks(new MyServerCallbacks());

  // Создаем службу BLE
  pService = pServer->createService(SERVICE_UUID);
  
  // Создаем характеристику BLE

  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);

  // Запускаем службу
  pService->start();

в этом конкретном коде я использую легкий сон , поэтому чтобы заснуть :

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

      changeMcuFreq(interface, interface->MIN_MCU_FREQUENCY);

и проснуться :

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