Usypianie ESP32

1. Usypianie i budzenie za pomocą funkcji touchAttachInterrupt().

Źródło: Touch Pins as Wake-up Source (ESP32 + Arduino series)

  • Argumenty funkcji touchAttachInterrupt():
    1. uint8_t pin. W moim przypadku T0 to pin GPIO0. Nazwy pinów dotykowych możemy odczytać z diagramów płytek ESP32.
    2. void (*)() userFunc. U mnie Callback to funkcja wykonywana po wybudzeniu
    3. uint16_t threshold. TOUCH_THRESHOLD zdefiniowana czułość na dotyk. Czym wyższa wartość, tym czulszy na dotyk.

KOD

//#include <Arduino.h>
#define TOUCH_THRESHOLD 40

void callback(){}

void setup() {
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor
  Serial.println("ESP32 has started");

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

  esp_deep_sleep_start();
}

void loop() {
  // put your main code here, to run repeatedly:

}

2. Usypianie i budzenie z (jednego) zewnętrznego źródła:

Źródło: ESP32 External Wake Up from Deep Sleep

Aby użyć (jednego) zewnętrznego źródła budzenia, należy użyć następującej funkcji:
esp_sleep_enable_ext0_wakeup(GPIO_NUM_X, level)
Przyjmuje ona jako pierwszy argument numer pinu, który ma być użyty do budzenia, w tym formacie GPIO_NUM_X, gdzie X reprezentuje numer GPIO tego pinu.
Drugi argument to poziom sygnału wejściowego, może być albo 1 (HIGH) albo 0 (LOW). Reprezentuje stan GPIO, który spowoduje wybudzenie.

KOD

Do kodu dodałem włączanie wbudowanej diody po wybudzeniu.

/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots

This code is under Public Domain License.

Hardware Connections
======================
Push Button to GPIO 34 pulled down with a 10K Ohm
resistor

NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.

Author:
Pranav Cherukupalli <cherukupallip@gmail.com>
*/

#ifdef ESP32
#define LED_BUILTIN 2
#elif ESP8266
#define LED_BUILTIN D4
#endif

//#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
//#define BUTTON_PIN_BITMASK 0x400000000 // 2^34 in hex 

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
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;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor
  pinMode(LED_BUILTIN, OUTPUT);

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

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_34,1); //1 = High, 0 = Low

  //If you were to use ext1, you would use it like
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

  //Go to sleep now
  Serial.println("Going to sleep now");
  digitalWrite(2, HIGH);
  delay(3000);
  digitalWrite(2, LOW);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}

3. Kilka źródeł budzenia

ext1

W poprzednim skeczu użyliśmy funkcji:
esp_sleep_enable_ext0_wakeup();
która pozwala kontrolować jedno źródło wybudzenia.
Jeśli mamy kilka czujników i chcemy by procesor wykonywał różne zadania w zależności od źródła wybudzenia, musimy użyć funkcji:
esp_sleep_enable_ext1_wakeup();
Funkcja ma dwa parametry/argumenty. Pierwszy mask, drugi mode.
Argument mask informuje które piny biorą udział przy wybudzaniu. Jeśli pin byłby jeden, na przykład chcemy użyć GPIO34, wówczas parametr mask przyjmie wartość:
0x400000000.
Obliczamy go tak: 2^34 = 17179869184 następnie zamieniamy na liczbę w systemie szesnastkowym. Możemy skorzystać z konwertera:

#define PIN_BITMASK 0x400000000 // 2^34 in HEX
Jeśli chcemy wykorzystać dwa piny, na przykład GPIO33 i GPIO34 wówczas musimy dodać 2^33 do 2^34. Otrzymamy 25769803776. Po zamianie na liczbę w systemie szesnastkowym otrzymamy 600000000.
#define PIN_BITMASK 0x600000000 // 2^33+2^34 in HEX

Pamiętajmy, że do wybudzania możemy użyć pinów: 0, 2, 4, 12-15, 25-27, 32-39.

Poniżej kod. Żeby było trudniej piny budzenia to GPIO4 i GPIO15. Maska przyjmuje wartość 0x8010. Do pinu 4 podłączyłem czujnik przechyłu, do pinu 15 mikrofalowy czujnik ruchu. Oba świetnie wybudzają.

KOD

/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots

This code is under Public Domain License.

Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor

NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.

Author:
Pranav Cherukupalli <cherukupallip@gmail.com>
*/

#define LED_BUILTIN 2

#define PIN_BITMASK 0x8010 // GPIOs 4 and 15
//#define PIN_BITMASK 0x300000000000 // 2^33+2^34 in HEX

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
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;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

/*
Method to print the GPIO that triggered the wakeup
*/
void print_GPIO_wake_up(){
  int GPIO_reason = esp_sleep_get_ext1_wakeup_status();
  Serial.print("GPIO that triggered the wake up: GPIO ");
  Serial.println((log(GPIO_reason))/log(2), 0);
}
  
void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor
  pinMode(LED_BUILTIN, OUTPUT);
  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  //Print the GPIO used to wake up
  print_GPIO_wake_up();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
  //esp_deep_sleep_enable_ext0_wakeup(GPIO_NUM_15,1); //1 = High, 0 = Low

  //If you were to use ext1, you would use it like
  esp_sleep_enable_ext1_wakeup(PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

  //Go to sleep now
  Serial.println("Going to sleep now");
  digitalWrite(2, HIGH);
  delay(3000);
  digitalWrite(2, LOW);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}

Świetny tutorial, który wykorzystałem we wpisie:

LINKI

Dodaj komentarz