Description
Summary
Several GPIO pins on the ESP32 do not work with machine.PinInputPullup
. It seems like they are configured as PinInput
instead. These same pins do work in INPUT_PULLUP
mode in C++ under the ESP32 Arduino Core. The problem GPIO pins are:
- GPIO32, GPIO33, GPIO25, GPIO26, GPIO27, GPIO12, GPIO13, GPIO4, GPIO2.
This is not a high priority, because I can rewire my buttons to use different pins. But it would be nice to make these GPIO pins work as expected.
Environment
- tinygo version 0.27.0 linux/amd64 (using go version go1.19.3 and LLVM version 15.0.0)
- ESP32 Arduino Core v2.0.7
- Arduino IDE 1.8.19
- microcontroller: ESP32 DevKitV1 (30 pin version), using an ESP-WROOM-32 module
- command line:
$ tinygo flash -x -target=esp32-coreboard-v2
Symptoms
When the above problem GPIO pins are configured using machine.PinInputPullup
, the internal pullup resistor does not seem to be connected. The pin.Get()
method just returns a stream of false
. When I connect an external pullup 10kOhm pullup resistor, the pin.Get()
returns true
. I am then able to attach an active-low push button to that GPIO pin to read a false
(pressed) or true
(released).
Those problematic GPIO pin work perfectly fine in INPUT_PULLUP
mode using C++ under the ESP32 Arduino Core. No external pullup resistors are necessary to attach a push button to those pins.
I understand that 4 of the GPIO pins on the ESP32 do not have hardware support for INPUT_PULLUP
: GPIO34, GPIO35, GPIO36, and GPIO39. Those pins behave the same way under both TinyGo or Arduino C++.
Minimal Reproducible TinyGo Program
package main
import (
"machine"
"time"
)
const pin = machine.GPIO13 // Replace this with various GPIO pins
func main() {
pin.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
time.Sleep(time.Millisecond * 500)
print("Reading pin #", pin, ": ")
for {
value := pin.Get()
if value {
print("1")
} else {
print("0")
}
time.Sleep(time.Millisecond * 100)
}
}
Output:
Reading pin #13: 000000000000000000000000000000000000000000000000000000000000000000
Minimal Reproducible Arduino C++ Program
#include <Arduino.h>
const uint8_t PIN = 13;
void setup() {
Serial.begin(115200);
pinMode(PIN, INPUT_PULLUP);
delay(500);
Serial.print("Reading pin #");
Serial.print(PIN);
Serial.print(": ");
}
void loop() {
uint8_t value = digitalRead(PIN);
Serial.print(value);
delay(100);
}
Output:
Reading pin #13: 1111111111111111111111111111111111111111100111110011111
Complete Summary Various Pins on ESP32 DevKit V1
I tested all exposed GPIO pins on my DevKit V1, and collected the results in the table below. The [*]
indicates the pins which are observed to behave differently between TinyGo and Arduino C++.
GPIO2 is a strange one. On the DevKit1 that I have, it is connected to an onboard LED. Using Arduino C++, when I configure it to INPUT_PULLUP
, I can make it work with a button using a 10kOhm external pullup resistor. However, using TinyGo, I am not able to get this pin working with an external pullup. I'm not really sure what's happening with GPIO2.
+-----+------------+------------------------+------------------------+
| | Pin | TinyGo | ESP32 Arduino |
+-----+------------+------------------------+------------------------+
|Boot | | | |
| | GPIO0 | works | works |
+-----+------------+------------------------+------------------------+
|Left | | | |
| | GPIO36 | works with ext pullup | works with ext pullup |
| | GPIO39 | works with ext pullup | works with ext pullup |
| | GPIO34 | works with ext pullup | works with ext pullup |
| | GPIO35 | works with ext pullup | works with ext pullup |
| | GPIO32 [*] | works with ext pullup | works |
| | GPIO33 [*] | works with ext pullup | works |
| | GPIO25 [*] | works with ext pullup | works |
| | GPIO26 [*] | works with ext pullup | works |
| | GPIO27 [*] | works with ext pullup | works |
| | GPIO14 | works | works |
| | GPIO12 [*] | works with ext pullup | works |
| | GPIO13 [*] | works with ext pullup | works |
+-----+------------+------------------------+------------------------+
|Right| | | |
| | GPIO23 | works | works |
| | GPIO22 | works | works |
| | GPIO1/TX0 | no output | no output |
| | GPIO3/RX0 | works | works |
| | GPIO21 | works | works |
| | GPIO19 | works | works |
| | GPIO18 | works | works |
| | GPIO5 | works | works |
| | GPIO17/TX2 | works | works |
| | GPIO16/RX2 | works | works |
| | GPIO4 [*] | works with ext pullup | works |
| | GPIO2 [*] | always LOW, LED | works with ext pullup |
| | GPIO15 | works | works |
+-----+------------+------------------------+------------------------+
[*] - difference observed between TinyGo and ESP32 Arduino Core