buttonPin 最初从按下状态开始。因此,当在开始时按下按钮上传代码时,esp32-c3 会进入睡眠状态。当 GPIO 变高时,另一个按钮 (buttonPin2) 将 esp 从深度睡眠中唤醒。唤醒后,esp 运行 BLE 脚本并连接到手机(使用 ble 扫描仪进行测试)。一旦成功连接(经过一段延迟),deviceConnected 回调将使 esp 重新进入睡眠状态。现在,当设备返回睡眠状态时,应通过第一个按钮 (buttonPin) 唤醒。该代码包含用于在 GPIO 变低时唤醒 esp 的行。但是,一旦释放按钮,esp 就会重置(需要再按一次按钮才能打印唤醒原因并切换 LED)。为什么ESP复位了,没有被按钮唤醒?我怎样才能解决这个问题?我希望buttonPin2最初唤醒esp以通过蓝牙将其配对,然后希望buttonPin在它再次返回睡眠状态后将其唤醒(并在唤醒时切换LED)。
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <Wire.h>
#include <Preferences.h>
#include <WiFi.h>
#include <WiFiMulti.h>
const int buttonPin = 3; // # for button pin for States/Interrupt
const int buttonPin2 = 2; // # for button pin for BLE
const int ledPin = 5; // # for the Green LED pin
const int ledPin2 = 6; // # for the Red LED pin
const int ledPin3 = 7; // # for the Blue LED pin
// variables will change:
int buttonState = 0;
int lastButtonState = 0;
int buttonState2 = 0;
int lastButtonState2 = 0;
int ledState = 0;
int state = 0;
//int BLEcounter = 0;
RTC_DATA_ATTR int counter = 0;
#define SERVICE_UUID "f0e279fc-a979-4ffd-924c-59ced5392948"
#define CHARACTERISTIC_UUID "7f98738e-382d-43d9-b256-3cf8bd3120b7"
BLEServer *pServer = NULL;
BLEService *pService = NULL;
BLECharacteristic *pCharacteristic = NULL;
Preferences preferences;
WiFiMulti wifimulti;
bool deviceConnected = false;
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
Serial.println("True");
state = preferences.getInt("state", 0);
Serial.print("State: ");
Serial.println(counter);
delay(5000);
Serial.println("Going to Sleep");
digitalWrite(ledPin3, LOW); // Turn off LED
esp_deep_sleep_start(); // Enter deep sleep mode
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
Serial.println("Disconnected!");
Serial.println("Advertising...");
pServer->getAdvertising()->start();
}
};
class MyCallbacks: public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *pCharacteristic)
{
std::string value = pCharacteristic->getValue();
if (value.length() > 0)
{
Serial.println("*********");
Serial.print("New value: ");
for (int i = 0; i < value.length(); i++)
{
Serial.print(value[i]);
}
Serial.println();
Serial.println("*********");
}
}
};
void setupBLEServer(void) {
Serial.println("Starting BLE Server!");
BLEDevice::init("Pirouette-IoT-Device");
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("device_state_0_stored");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
pAdvertising->start();
}
void pairing(){
digitalWrite(ledPin3, HIGH);
setupBLEServer();
}
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0:
Serial.println("Wakeup caused by external signal using RTC_IO");
break;
case ESP_SLEEP_WAKEUP_EXT1:
Serial.println("Wakeup caused by external signal using RTC_CNTL");
break;
case ESP_SLEEP_WAKEUP_TIMER:
Serial.println("Wakeup caused by timer");
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD:
Serial.println("Wakeup caused by touchpad");
break;
case ESP_SLEEP_WAKEUP_ULP:
Serial.println("Wakeup caused by ULP program");
break;
case ESP_SLEEP_WAKEUP_GPIO: //New wakeup reason <--
Serial.println("Wakeup caused by a GPIO");
if(lastButtonState == HIGH && buttonState == LOW){
counter++;
Serial.print("Counter: ");
Serial.println(counter);
}
if(counter == 1){
digitalWrite(ledPin, HIGH);
}
//digitalWrite(ledPin, HIGH);
//Serial.println("Advertising...");
//pServer->startAdvertising();
if(deviceConnected){
if(pCharacteristic != NULL){
pCharacteristic->setValue("device_state_1_ready"); //add code for device state 1 ready once buttonPin1 is pushed/released
pCharacteristic->notify();
}
}
break;
default:
Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
break;
}
}
void setup() {
Serial.begin(115200);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
pinMode(buttonPin2, INPUT_PULLUP);
//Enable GPIO Wakeup from buttonPin
esp_deep_sleep_enable_gpio_wakeup(1 << buttonPin, ESP_GPIO_WAKEUP_GPIO_LOW);
esp_deep_sleep_enable_gpio_wakeup(1 << buttonPin2, ESP_GPIO_WAKEUP_GPIO_HIGH);
gpio_set_direction((gpio_num_t)buttonPin, GPIO_MODE_INPUT); // <<<=== Add this line
gpio_set_direction((gpio_num_t)buttonPin2, GPIO_MODE_INPUT); // <<<=== Add this line
preferences.begin("dev-states", false);
state = preferences.getInt("state", 0);
Serial.print("State: ");
Serial.println(counter);
buttonState2 = digitalRead(buttonPin2);
if(buttonState2 == HIGH && lastButtonState2 == LOW){
print_wakeup_reason();
pairing();
}
buttonState = digitalRead(buttonPin);
buttonState2 = digitalRead(buttonPin2);
if(buttonState == HIGH && buttonState2 == LOW){
Serial.println("Going to Sleep");
esp_deep_sleep_start();
}
}
void loop() {
// read the state of the BLE pushbutton
buttonState2 = digitalRead(buttonPin2);
if (lastButtonState2 == HIGH && buttonState2 == LOW) {
print_wakeup_reason();
Serial.println("The button is pressed");
pairing();
}
lastButtonState2 = buttonState2;
// read the state of the internal pushbutton:
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (lastButtonState == HIGH && buttonState == LOW) {
print_wakeup_reason();
//counter++;
Serial.print("Number of button pushes: ");
Serial.println(counter);
// if the current state is HIGH then the button went from off to on:
ledState = !ledState;
}
if(counter == 2){
buttonState = lastButtonState;
}
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
// sets the LED to the button's state
if(counter == 1){
digitalWrite(ledPin, HIGH);
digitalWrite(ledPin2, LOW);
if(pCharacteristic != NULL){
pCharacteristic->setValue("device_state_3_locked"); //add code for device state 1 ready once buttonPin1 is pushed/released
pCharacteristic->notify();
}
}
if(counter == 3){
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin, LOW);
if(pCharacteristic != NULL){
pCharacteristic->setValue("device_state_3_locked"); //add code for device state 3 used once buttonPin1 is pushed/released
pCharacteristic->notify();
}
}
if(counter >= 4){
digitalWrite(ledPin, LOW);
digitalWrite(ledPin2, LOW);
}
delay(50);
}
愚蠢的建议,但根据您的描述,我想到的一个可能的原因是您可能无意中触发了实际上是 ESP 上的重置引脚的引脚。
如果您查看主板的引脚图,它会显示哪个引脚标记为“RST”,具体取决于您的接线,如果您向该引脚供电,它将重置芯片。
问题是有些主板只会打印数字 1,2,3...但只有当您查看实际的引脚图时,它才会告诉您哪个引脚做什么。
我一直这样做,但是是故意的,如果我没有物理开关而是使用按钮,我会让 ESP 进入睡眠状态,当需要使用设备时,用户按下按钮按钮向 RST 发送脉冲,有效地重新启动设备,就像刚刚插入电源一样。
正如一些人评论的那样,您发布了太多的代码,最好的办法是隔离问题,放弃代码中除睡眠/唤醒部分之外的所有内容,并对其进行测试,直到该部分机制起作用,或者如果它不只发布该代码。如果内容切中要点,则更有机会获得优质帮助(否则您只会收到脾气暴躁的评论:-)