How to update ESP32 firmware with an SD card [Guide + Code]

  1. ESP32 Micro SD Card Firmware Update Process
  2. ​​ESP32 Micro SD Card Update Hardware
  3. ESP32 Micro SD Card Update Sketch
  4. ESP32 Micro SD Card Update Sketch Highlights
  5. ESP32 Micro SD Card Sketch progresscallback() function
  6. ESP32 Micro SD Card Sketch setup() function
  7. ESP32 Micro SD Card Sketch loop() function
  8. Testing The ESP32 Micro SD Card Firmware Update Sketch
  9. Where To Go From Here

In this article, we will discuss an alternative method for updating ESP32 firmware using a micro SD card and a micro SD card reader.  

Firmware is the software that is programmed into a microcontroller like the ESP32 to execute a set of instructions.  And micro SD cards ( secure digital cards ) are used in many applications, from cell phones to laptops to digital cameras, for storing data.  

Updating firmware by micro SD card is not frequently used in the ESP32 / Arduino development environment, but it can be a very effective alternative method for updating a device’s firmware.  

Most projects you develop will require firmware updates from time to time.  If your ESP32 device does not have internet access for running OTA ( over the air ) updates via an internet connection.  If your ESP32 device has access to a micro SD card reader, then micro SD card-based updates can be an effective and reliable method for updating an ESP32 device’s firmware.  

You will, of course, also need to be able to physically access the ESP32 device and its micro SD card slot in order to perform the firmware update.  So, this necessity may need to be taken into account when designing a PCB or case for your project.

At the end of this article, you should be able to successfully update your ESP32 device’s firmware using a micro SD card.  Once you have this understanding, then you can determine which method for updating an ESP32 device’s firmware will work best for you and your specific projects in the future.

ESP32 Micro SD Card Firmware Update Process

In this ESP32 micro SD card update process, we will be updating the firmware that is currently running on your ESP32 with new firmware that has been saved onto a micro SD card.  

Step
Format SD CardFirst, we will make sure our micro SD card is properly formatted.
Save FirmwareNext, we will save our new firmware onto a micro SD card.  In order to save our firmware onto a micro SD card, we will create a binary file of our firmware using the Arduino IDE.  This binary file will be described further down in the article.
Confirm ESP32 DetectionIn the new firmware we create, we will make sure our micro SD card is detected by the ESP32.
Update FirmwareIf an SD card is detected and there is new firmware on our micro SD card, then we will start the update process for our ESP32 to get the new firmware copied to the ESP32.  
Report to Serial MonitorWhile this micro SD card updating is occurring, we will be reporting the update progress to the serial monitor, if we have our ESP32 connected to the serial monitor.
Rename Firmware FileFinally, once the firmware update process is complete, we will rename our firmware update file so we don’t try to update the ESP32 again whenever the device is restarted.

​​ESP32 Micro SD Card Update Hardware

An ESP32 device equipped with a micro SD card reader and the ability to access the SD card reader is the required hardware platform for this tutorial.  

A formatted micro SD card is also required.  FAT formatting is the preferred format for the micro SD card for these updates  An example of a micro SD card that has worked successfully for this task before is the following:

The example sketch below was tested using Arduino IDE Version: 1.8.19 along with ESP IDF version: 5.0.

ESP32 Micro SD Card Update Sketch

The following sketch is an example of an ESP32 micro SD card based firmware update:

//  SD Card Update Example Sketch
//  Programming Electronics Academy

// include file system library
#include "FS.h"

// include SD card library
#include "SD.h"

// include SPI library
#include "SPI.h"

// include Update library
#include <Update.h>
#define FIRMWARE_VERSION 1.00

//#define FIRMWARE_VERSION 2.00
// Define SD card connection
#define SD_MOSI     15
#define SD_MISO     2
#define SD_SCLK     14
#define SD_CS       13

// Update progress status
void progresscallback(size_t currSize, size_t totalSize) 
{
  Serial.printf("CALLBACK:  Update process at %d of %d bytes...n", currSize, totalSize);
}

// Setup
void setup()

{

  Serial.begin(115200);
  Serial.println("Setup start");
  SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
  if (!SD.begin(SD_CS)) 
  {
    Serial.println("SD Card MOUNT FAIL");
  } 
  else 
  {

    Serial.println("SD Card MOUNT SUCCESS");
    Serial.println("");
    uint32_t cardSize = SD.cardSize() / (1024 * 1024);
    String str = "SDCard Size: " + String(cardSize) + "MB";
    Serial.println(str);
    uint8_t cardType = SD.cardType();
    if(cardType == CARD_NONE)
    {
      Serial.println("No SD card attached");
    }
    Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC)
    {
        Serial.println("MMC");
    } 

    else if(cardType == CARD_SD)

    {
        Serial.println("SDSC");

    } 

    else if(cardType == CARD_SDHC)

    {

        Serial.println("SDHC");

    } 

    else 

    {

        Serial.println("UNKNOWN");

    }

    /////////////////////////////////////////////////////////
    //  SD CARD FIRMWARE UPDATE BEGIN
    /////////////////////////////////////////////////////////

    Serial.print("Card size:  ");
    Serial.println((float)SD.cardSize()/1000);
    Serial.print("Total bytes: ");
    Serial.println(SD.totalBytes());
    Serial.print("Used bytes: ");
    Serial.println(SD.usedBytes());
    Serial.print("nCurrent firmware version: ");
    Serial.println(FIRMWARE_VERSION);
    Serial.print("nSearching for firmware update..");
    File firmware =  SD.open("/firmware.bin");
    if (firmware) 

    {
        Serial.println("Found!");
        Serial.println("Try to update!");
        Update.onProgress(progresscallback);
        Update.begin(firmware.size(), U_FLASH);
        Update.writeStream(firmware);
        if (Update.end())

        {

            Serial.println("Update finished!");

        }

        else

        {

            Serial.println("Update error!");
            Serial.println(Update.getError());
        }

        firmware.close();
        if (SD.rename("/firmware.bin", "/firmware.bak"))

        {
            Serial.println("Firmware renamed successfully!");
        }

        else

        {
            Serial.println("Firmware rename error!");
        }

        delay(200);

        ESP.restart();

    }

    else

    {

        Serial.println("Firmware update not found!");

    }

    Serial.print("Firmware version ");
    Serial.println(FIRMWARE_VERSION);

    /////////////////////////////////////////////////////////
    //  SD CARD FIRMWARE UPDATE END
    /////////////////////////////////////////////////////////

  }
 SD.end();
  SPI.end();
  Serial.println("INFO: Setup complete");

}

// Loop
void loop()

{ 

  // Nothing to do here. 

}

ESP32 Micro SD Card Update Sketch Highlights

We must include the FS ( file system ) library for file handling, the SD library for micro SD card functionality and the SPI ( serial peripheral interface ) library for communicating between the ESP32 and the micro SD card reader.  Also, we need to include the Update class for performing the firmware update.

// include file system library
#include "FS.h"

// include SD card library
#include "SD.h"

// include SPI library
#include "SPI.h"

// include Update library
#include <Update.h>

ESP32 Micro SD Card Sketch progresscallback() function

This function displays progress updates in the serial monitor during the firmware update processing.

ESP32 Micro SD Card Sketch setup() function

Initialize the serial communication with the serial monitor using a baud rate of 115200.

Serial.begin(115200);

Initialize the SPI communications with the SD card reader using the begin() function.  For your sketch, you will need to use the appropriate values of SCLK, MISO, MOSI, and CS for the SD card reader connected to your ESP32.

SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);

Initialize the micro SD card reader using the begin() function.  If no argument is passed to the begin function, the SPI will use the default chip select pin of GPIO5.  In this example, the chip select pin of GPIO13 is being passed as an argument to the SD card reader begin() function.

  if (!SD.begin(SD_CS)) 
  {
    Serial.println("SD Card MOUNT FAIL");
  } 

Get the micro SD card size.

    uint32_t cardSize = SD.cardSize() / (1024 * 1024);

    String str = "SDCard Size: " + String(cardSize) + "MB";

    Serial.println(str);

Display the micro SD card type in the serial monitor.

    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE)
    {
      Serial.println("No SD card attached");
    }

    Serial.print("SD Card Type: ");

    if(cardType == CARD_MMC)
    {
        Serial.println("MMC");
    } 

    else if(cardType == CARD_SD)
    {
        Serial.println("SDSC");
    } 

    else if(cardType == CARD_SDHC)
    {
        Serial.println("SDHC");
    } 
    else 
    {
        Serial.println("UNKNOWN");
    }

Now, search the micro SD card to see if a firmware update exists on the micro SD card by trying to open a file named firmware.bin.

    File firmware =  SD.open("/firmware.bin");

If the firmware.bin file exists, begin the update process by copying the file to the OTA partition on the ESP32.

        Update.begin(firmware.size(), U_FLASH);

        Update.writeStream(firmware);

The copy progress can be monitored in the serial monitor by using the following callback.

        Update.onProgress(progresscallback);

Once the file copy is complete, rename the firmware so the ESP32 device does not try to update itself again after a restart.

        if (SD.rename("/firmware.bin", "/firmware.bak"))

Finally, restart the ESP32 to allow for the copy of the firmware from the OTA partition to the flash memory partition on the device.

        ESP.restart();

ESP32 Micro SD Card Sketch loop() function

The entire SD card update occurs in the setup function.  So, there is nothing to do in the Arduino main loop.

Testing The ESP32 Micro SD Card Firmware Update Sketch

Once you have downloaded the above sketch to your ESP32 device.  Update the sketch and comment out the following line:

<code>
//#define FIRMWARE_VERSION 1.00
<code>

And uncomment this line:

<code>
#define FIRMWARE_VERSION 2.00
<code>

After the above change has been made and you have saved the changes, you can then create a firmware binary for the updated sketch.  In your Arduino IDE, from the main menu, select Sketch -> Export compiled Binary.  

This will create the firmware binary for your update.  A binary file is a computer file ( non text file ) that can be read and executed by your ESP32’s operating system from the device’s memory.

You can find where your new firmware binary is located by doing the following: in your Arduino IDE, from the main menu, select Sketch -> Show Sketch Folder.  

Go to your sketch folder and copy your firmware.bin file to your micro SD card.  Insert your micro SD card into your micro SD reader card slot.  Press the reset ( RST ) button on your ESP32 device.   If you are monitoring your serial output with your Arduino IDE serial monitor, then you will see the firmware update progress status.  

After the firmware update is complete, the firmware will rename your firmware.bin file to firmware.bak and restart your device.  If you continue to monitor your serial output with the serial monitor, then you should observe that the Firmware Version has been updated from version 1.0 to 2.0.  

Remember that every time you do a micro SD card update, you will need to include the same update code above in your software to be able to update the firmware again using this process!

And that is all there is to it.  It is that easy to update your firmware on your ESP32 device using your micro SD card reader and micro SD card!

Where To Go From Here

Micro SD card based firmware updates for ESP32 devices can be an effective and reliable solution for modifying a device’s firmware when other options are not possible.

For practice, try to create your own ESP32 firmware upload sketch that displays “Hello World” on the serial monitor after your update is successfully completed and your device is restarted. 

AppLab Bricks open in background with actual brick

Arduino AppLab Bricks → Marketing Garbage or New Powerful Interface?

Arduino Ventuno single board computer - top side

New Ventuno Q Dual Brain Single Board Computer

AppLab Pip Install

How to Add Python Packages in Arduino AppLab (No pip install needed)

Arduino Power Section Schematic

Kit-on-a-Shield Schematic Review

Just how random is the ESP32 random number generator?

Just how random is the ESP32 random number generator?

Leave a Comment