In this article you will learn how to get more free GPIO pins for your ESP32-CAM board. The ESP32-CAM modules are small ESP32 based boards with an integrated camera, flash LED and SD card interface. They are great to build simple surveillance or monitoring systems.
However, the number of freely available GPIO pins is very small, especially when the Camera and SD Card Interface are in use. This tutorial shows you how to get around this limitation.
Required Parts
You will need an ESP32-CAM module with a programming shield or an FTDI USB-TTL Adapter. Some other parts such as USB cable, micro SD Card, or SD Card reader you may already have. No need to buy it then, none of those parts is special for this project.
ESP32-CAM with USB-TTL Shield
FTDI USB-TTL Adapter
MicroSD Card 4GB
SD Card Reader
USB Data Cable
Arduino IDE
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Pin Usage of the ESP32-CAM
The following picture shows the Pinout of the ESP32-CAM. The ESP32-S chip on the board has 32 GPIO pins but most of them are used by the Camera and PSRAM and not exposed.
The 10 GPIO pins that are accessible (purple color) are also not freely available but shared with the SD Card and the Serial Communication interfaces. Specifically, all the yellow marked GPIOs (12, 13, 15, 14, 2, 4) on the left side of the board are shared with the SD Card. The following schematic shows the signal lines used by the SD Card socket:
As you can also see, the data lines connected to SD Card are internally pulled high with 47K resistors. The table below list which GPIO pin maps to which data line of the SD Card interface:
SD Card | ESP32-CAM |
---|---|
HS2_CLK | GPIO14 |
HS2_CMD | GPIO15 |
HS2_DATA0 | GPIO2 |
HS2_DATA1 / flash LED | GPIO4 |
HS2_DATA2 | GPIO12 |
HS2_DATA3 | GPIO13 |
The GPIO3 and GPIO1 pins on the right side of the board are needed for Serial communication (U0_RXD, U0_TXD) and the programming of the board.
Finally, GPIO0 is connected to the camera XCLK pin and should be left floating (not connected) when running the ESP32. Internally, GPIO0 is pulled up by a 10KΩ resistor and needs to be connected to GND while flashing.
That leaves you only with GPIO16 as a freely usable pin, if the SD Card Interface is used in 4-bit mode. If you need just some kind of status LED you can use GPIO33, which is connected to a red LED on the back of board.
Available GPIOs in different Scenarios
Let’s us look at different application scenarios and see which GPIO pins are available. GPIO 16 will be always available but I include it in the following descriptions for completeness:
No SD Card used
If the SD Card interface is not used, you have GPIOs 2, 4, 12, 13, 14, 15 and 16 available. Those are the blue marked pins in the following picture:
You can try the following test code to see what happens when you want to blink an LED on various pins when using the SD Card interface in 4-bit mode, 1-bit mode or not at all:
#include "SD_MMC.h" const byte ledPin = 12; // 13, ... void setup() { Serial.begin(115200); pinMode(ledPin, OUTPUT); // SD_MMC.begin(); // 4-bit Mode // SD_MMC.begin("/sdcard", true); // 1-bit Mode for (int i = 0; i < 10; i++) { Serial.println("blink"); digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); } } void loop() { }
You will find more details about these mode in the following sections. Just remember, if you want to use the SD Card interface you will need to have a properly formatted SD Card inserted. Otherwise, the SD_MMC.begin()
call will fail with a return value of false
.
SD Card used in 4-bit Mode
If you use the SD Card interface in 4-bit (high speed) mode, you will have only GPIO16 available:
The following code excerpt shows how to initialize the SD Card interface in the default 4-bit mode:
#include "SD_MMC.h" void setup() { SD_MMC.begin(); ... }
Note that the built-in Flash LED is connected to GPIO 4, which causes the Flash LED to flash briefly when the SD Card reader is used. You can avoid this by initializing the SD Card Interface in 1-bit Mode, which we will discuss in the next section.
SD Card used in 1-bit Mode
If you run the SD Card Interface in 1-bit Mode, data transfer with the SD Card will be slower but you gain GPIO12 and GPIO13 as available pins:
To initialize the SD Card Interface to use 1-bit Mode use the following code. The important bit here is to set the second parameter in SD_MMC.begin(..., true)
to true
, which switches on the 1-bit mode.
#include "SD_MMC.h" void setup() { SD_MMC.begin("/sdcard", true); ... }
This also allows you to avoid the flashing of the flash LED (at GPIO4) like so:
#include "SD_MMC.h" void setup() { pinMode(GPIO_NUM_4, OUTPUT); digitalWrite(GPIO_NUM_4, LOW); // switch of flash LED SD_MMC.begin("/sdcard", true); // flash LED remains off ... }
While you can’t use GPIO4 for other purposes, you can at least switch the flash LED on and off as you like, without interference with the SD Card operations. However, you must not switch on the flash LED for more than a second! It has no current limiting resistor, gets very hot and will burn out! For more details see the Control ESP32-CAM Flash LED tutorial.
Utilizing Deep-sleep
If you need GPIO pins only to wake up the ESP32-CAM from deep-sleep, e.g. to take a picture when motion is detected, you can actually use GPIOs 2, 4, 12, 13, 14 or 15, even when the SD Card interface is initialized in 4-bit mode. Below a wiring example from the Motion Activated ESP32-CAM tutorial
Adding GPIOs
If you want to use the SD Card and need more than 3 GPIO pins, the easiest method is to add a GPIO Expander board that uses an I2C interface. I2C needs only two pins and if you initialize the SD Card in 1-bit Mode, you have three GPIO pins available (12, 13, 16).
The following wiring diagram show you how to connect the MCP23017 GPIO Expander board via I2C to GPIO12 and GPIO13 of the ESP32-CAM:
And here is some example code that describes how to initialize the GPIO Expander and the SD Card:
include "Wire.h" #include "Adafruit_MCP23X17.h" #include "SD_MMC.h" Adafruit_MCP23X17 mcp; void setup() { Serial.begin(115200); SD_MMC.begin("/sdcard", true); // 1-bit Mode Wire.begin(13, 12); // SDA=13, SCL=12 if (!mcp.begin_I2C()) { // Default address 0x20 Serial.println("MCP23017 not found!"); while (1); } // Example: set pin 0 on MCP23017 as output mcp.pinMode(0, OUTPUT); } void loop() { mcp.digitalWrite(0, ...); ... }
If you want to learn more about the MCP23017 GPIO Expander have a look at the Using GPIO Expander MCP23017 With Arduino tutorial. Note that you can chain multiple MCP23017 chips, which gives you up to 128 GPIOs. Certainly enough ; )
Instead of a bi-directional GPIO Expander such as the MCP23017 you could also use Shift Registers to add more inputs or outputs. See the More Inputs With 74HC165 Shift Register and the More Arduino Outputs With 74HC595 Shift Register tutorials, for more details.
Conclusions
This article showed you how to get more GPIO pins for your ESP32-CAM. I hope this helps with your projects. If you have any questions, feel free to leave them in the comment section.
Happy Tinkering 😉
Stefan is a professional software developer and researcher. He has worked in robotics, bioinformatics, image/audio processing and education at Siemens, IBM and Google. He specializes in AI and machine learning and has a keen interest in DIY projects involving Arduino and 3D printing.