Setup:

  • ESP32-C3 SuperMini
  • Jumper wires on GND, 3V3, GPIO4, GPIO3
  • Multimeter

Goal:

  • Understand how to control internal pull up/down resistors when configuring deep sleep

ESPHome with ESP-IDF

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# Commands:
# esphome compile test_sandbox.yaml && esphome upload test_sandbox.yaml --device 192.168.178.222
# esphome logs test_sandbox.yaml --device /dev/tty.usbmodem21201


substitutions:
  devicename: "test-sandbox"
  static_ip: "192.168.178.222"
  gateway: "192.168.178.1"
  subnet: "255.255.255.0"

ota:
  platform: esphome
  password: !secret esphome_ota_key

wifi:
  id: wifi_component
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: ${static_ip}
    gateway: ${gateway}
    subnet: ${subnet}

logger:
  level: DEBUG

debug:

api:

esp32:
  board: lolin_c3_mini
  framework:
    type: esp-idf
    version: recommended

esphome:
  name: ${devicename}
  on_boot:
    - script.execute:
        id: configure_deep_sleep
        pin: 4
        on_high: true
    - script.execute:
        id: configure_deep_sleep
        pin: 3
        on_high: false
    - script.execute: enter_deep_sleep
  
script:
  - id: configure_deep_sleep
    parameters:
      pin: int
      on_high: bool
    mode: parallel
    then:
      - lambda: |-
          ESP_LOGI("configure_deep_sleep", "Configuring deep sleep");
          ESP_LOGI("configure_deep_sleep", "\tpin = %d", pin);
          ESP_LOGI("configure_deep_sleep", "\ton_high = %s", on_high ? "ON" : "OFF");
          esp_deepsleep_gpio_wake_up_mode_t mode;
          if (on_high) {
            mode = ESP_GPIO_WAKEUP_GPIO_HIGH;
          } else {
            mode = ESP_GPIO_WAKEUP_GPIO_LOW;
          }
          ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(1ULL << pin, mode));
          
  - id: enter_deep_sleep
    mode: single
    then:
      - lambda: |-
          esp_deep_sleep_start();

deep_sleep:
  id: dummy_deep_sleep_component

If you don’t have deep_sleep block, the imports are going to be missing in the CPP code, hence you can’t use ESP_GPIO_WAKEUP_GPIO_HIGH, etc, in the CPP code.

1
2
deep_sleep:
  id: dummy_deep_sleep_component
PIN Configuration Expectation Observed Voltage during DeepSleep Observed resistance
4 ON HIGH Pull down resistor 0V 16.5K with GND
0 with 3.3V
3 ON LOW Pull up resistor 3.3V 0 with GND
100M with 3.3V - I don’t think this counts

Adding CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS: n.

1
2
3
4
5
6
7
esp32:
  board: lolin_c3_mini
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS: y
PIN Configuration Expectation Observed Voltage during DeepSleep Observed resistance
4 ON HIGH No resistors 0.11V 0 with GND
100M with 3.3V
3 ON LOW No resistors 0.11V 0 with GND
100M with 3.3V

ESPHome with Arduino

PIN Configuration Expectation Observed Voltage during DeepSleep Observed resistance
4 ON HIGH Pull down resistor 0.13V 0 with GND
100M with 3.3V
3 ON LOW Pull up resistor 0.13V 0 with GND
100M with 3.3V - I don’t think this counts

Surprisingly, it seems like ESPHome Arduino doesn’t use the internal pull up/down resistors. But I also couldn’t control it with CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS

Arduino

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <Arduino.h>

#define PIN1 4
#define PIN2 3


void goToSleep()
{
    esp_deep_sleep_enable_gpio_wakeup(1 << PIN1, ESP_GPIO_WAKEUP_GPIO_HIGH);
    esp_deep_sleep_enable_gpio_wakeup(1 << PIN2, ESP_GPIO_WAKEUP_GPIO_LOW);
    esp_deep_sleep_start();
}

void setup()
{
    Serial.begin(115200);
    goToSleep();
}

void loop()
{
    // Never reached
}
PIN Configuration Expectation Observed Voltage during DeepSleep Observed resistance
4 ON HIGH Pull down resistor 0V 16.5K with GND
0 with 3.3V
3 ON LOW Pull up resistor 3.3V 0 with GND
100M with 3.3V - I don’t think this counts

So we see the internal resistors are present in this case.

Build flag doesn’t work either:

1
2
3
build_flags =
    -DCONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=0
    -DESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=0

As far as I understood the alternative is to recompile the Arduino library itself. Instructions for recompiling Arduino library for ESP32 after updating the necessary esp-idf configs. https://github.com/espressif/arduino-esp32/issues/4529#issuecomment-746219537

I needed this investigation, as I added an external 100K pull-up resistor, while the ESP32-C3 SuperMini was adding internal pull down resistor. Because of this I wasn’t getting the necessary voltage to trigger HIGH binary signal on the pin.