ESP32 Data Logging Temperature to MicroSD Card

This project shows how to log data with timestamps to a microSD card using the ESP32. As an example, we’ll log temperature readings from the DS18B20 sensor every 10 minutes. The ESP32 will be in deep sleep mode between each reading, and it will request the date and time using Network Time Protocol (NTP).

Project Overview

Before getting started, let’s highlight the project’s main features:

  • The ESP32 reads temperature using the DS18B20 temperature sensor.
  • After getting the temperature, it makes a request to an NTP (Network Time Protocol) server to get date and time. So, the ESP32 needs a Wi-Fi connection.
  • The data (temperature and timestamp) are logged to a microSD card. To log data to the microSD card we’re using a microSD card module.
  • After completing these previous tasks, the ESP32 sleeps for 10 minutes.
  • The ESP32 wakes up and repeats the process.

Parts Required

Here’s a list of the parts required to build this project (click the links below to find the best price at Maker Advisor):

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Preparing the microSD Card Module

To save data on the microSD card with the ESP32, we use the following microSD card module that communicates with the ESP32 using SPI communication protocol.

Formatting the microSD card

When using a microSD card with the ESP32, you should format it first. Follow the next instructions to format your microSD card.

1. Insert the microSD card in your computer. Go to My Computer and right click on the SD card. Select Format as shown in figure below.

2. A new window pops up. Select FAT32, press Start to initialize the formatting process and follow the onscreen instructions.

Schematic

Follow the next schematic diagram to assemble the circuit for this project.

You can also use the following table as a reference to wire the microSD card module:

MicroSD Card ModuleESP32
3V33V3
CSGPIO 5
MOSIGPIO 23
CLKGPIO 18
MISOGPIO 19
GNDGND

The next figure shows how your circuit should look like:

Preparing the Arduino IDE

There’s an add-on for the Arduino IDE that allows you to program the ESP32 using the Arduino IDE and its programming language. Follow one of the next tutorials to prepare your Arduino IDE to work with the ESP32, if you haven’t already.

After making sure you have the ESP32 add-on installed, you can continue with this tutorial.

Installing Libraries

Before uploading the code, you need to install some libraries in your Arduino IDE.  The OneWire library by Paul Stoffregen and the Dallas Temperature library, so that you can use the DS18B20 sensor. You also need to install the NTPClient library forked by Taranais to make request to an NTP server.

Follow the next steps to install those libraries in your Arduino IDE:

OneWire library

  1. Click here to download the OneWire library. You should have a .zip folder in your Downloads
  2. Unzip the .zip folder and you should get OneWire-master folder
  3. Rename your folder from OneWire-master to OneWire
  4. Move the OneWire folder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

Dallas Temperature library

  1. Click here to download the DallasTemperature library. You should have a .zip folder in your Downloads
  2. Unzip the .zip folder and you should get Arduino-Temperature-Control-Library-master folder
  3. Rename your folder from Arduino-Temperature-Control-Library-master to DallasTemperature
  4. Move the DallasTemperaturefolder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

NTPClient library

  1. Click here to download the NTPClient library. You should have a .zip folder in your Downloads
  2. Unzip the .zip folder and you should get NTPClient-master folder
  3. Rename your folder from NTPClient-master to NTPClient
  4. Move the NTPClientfolder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

Uploading Code

Here’s the code you need to upload to your ESP32. Before uploading, you need to modify the code to include your network credentials (SSID and password). Continue reading to learn how the code works.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

// Libraries for SD card
#include "FS.h"
#include "SD.h"
#include <SPI.h>

//DS18B20 libraries
#include <OneWire.h>
#include <DallasTemperature.h>

// Libraries to get time from NTP Server
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Define deep sleep options
uint64_t uS_TO_S_FACTOR = 1000000;  // Conversion factor for micro seconds to seconds
// Sleep for 10 minutes = 600 seconds
uint64_t TIME_TO_SLEEP = 600;

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Define CS pin for the SD card module
#define SD_CS 5

// Save reading number on RTC memory
RTC_DATA_ATTR int readingID = 0;

String dataMessage;

// Data wire is connected to ESP32 GPIO 21
#define ONE_WIRE_BUS 21
// Setup a oneWire instance to communicate with a OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

// Temperature Sensor variables
float temperature;

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;

void setup() {
  // Start serial communication for debugging purposes
  Serial.begin(115200);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");

  // Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(3600);

  // Initialize SD card
  SD.begin(SD_CS);  
  if(!SD.begin(SD_CS)) {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();
  if(cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }
  Serial.println("Initializing SD card...");
  if (!SD.begin(SD_CS)) {
    Serial.println("ERROR - SD card initialization failed!");
    return;    // init failed
  }

  // If the data.txt file doesn't exist
  // Create a file on the SD card and write the data labels
  File file = SD.open("/data.txt");
  if(!file) {
    Serial.println("File doens't exist");
    Serial.println("Creating file...");
    writeFile(SD, "/data.txt", "Reading ID, Date, Hour, Temperature \r\n");
  }
  else {
    Serial.println("File already exists");  
  }
  file.close();

  // Enable Timer wake_up
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

  // Start the DallasTemperature library
  sensors.begin(); 

  getReadings();
  getTimeStamp();
  logSDCard();
  
  // Increment readingID on every new reading
  readingID++;
  
  // Start deep sleep
  Serial.println("DONE! Going to sleep now.");
  esp_deep_sleep_start(); 
}

void loop() {
  // The ESP32 will be in deep sleep
  // it never reaches the loop()
}

// Function to get temperature
void getReadings(){
  sensors.requestTemperatures(); 
  temperature = sensors.getTempCByIndex(0); // Temperature in Celsius
  //temperature = sensors.getTempFByIndex(0); // Temperature in Fahrenheit
  Serial.print("Temperature: ");
  Serial.println(temperature);
}

// Function to get date and time from NTPClient
void getTimeStamp() {
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);

  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  Serial.println(dayStamp);
  // Extract time
  timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
  Serial.println(timeStamp);
}

// Write the sensor readings on the SD card
void logSDCard() {
  dataMessage = String(readingID) + "," + String(dayStamp) + "," + String(timeStamp) + "," + 
                String(temperature) + "\r\n";
  Serial.print("Save data: ");
  Serial.println(dataMessage);
  appendFile(SD, "/data.txt", dataMessage.c_str());
}

// Write to the SD card (DON'T MODIFY THIS FUNCTION)
void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if(!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if(file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

// Append data to the SD card (DON'T MODIFY THIS FUNCTION)
void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if(!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if(file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

View raw code

How the Code Works

In this example, the ESP32 is in deep sleep mode between each reading. In deep sleep mode, all your code should go in the setup() function, because the ESP32 never reaches the loop().

Importing libraries

First, you import the needed libraries for the microSD card module:

#include "FS.h"
#include "SD.h"
#include <SPI.h>

Import these libraries to work with the DS18B20 temperature sensor.

#include <OneWire.h>
#include <DallasTemperature.h>

The following libraries allow you to request the date and time from an NTP server.

#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

Setting deep sleep time

This example uses a conversion factor from microseconds to seconds, so that you can set the sleep time in the TIME_TO_SLEEP variable in seconds.

In this case, we’re setting the ESP32 to go to sleep for 10 minutes (600 seconds). If you want the ESP32 to sleep for a different period of time, you just need to enter the number of seconds for deep sleep in the TIME_TO_SLEEP variable.

// Define deep sleep options
uint64_t uS_TO_S_FACTOR = 1000000; // Conversion factor for micro seconds to seconds
// Sleep for 10 minutes = 600 seconds
uint64_t TIME_TO_SLEEP = 600;

Setting your network credentials

Type your network credentials in the following variables, so that the ESP32 is able to connect to your local network.

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Initializing sensors and variables

Next, define the microSD card SD pin. In this case, it is set to GPIO 5.

#define SD_CS 5

Create a variable called readingID to hold the reading ID. This is a way to get your readings organized. To save a variable value during deep sleep, we can save it in the RTC memory. To save data on the RTC memory, you just need to add RTC_DATA_ATTR before the variable definition.

// Save reading number on RTC memory
RTC_DATA_ATTR int readingID = 0;

Create a String variable to hold the data to be saved on the microSD card.

String dataMessage;

Next, create the instances needed for the temperature sensor. The temperature sensor is connected to GPIO 21.

// Data wire is connected to ESP32 GPIO21
#define ONE_WIRE_BUS 21
// Setup a oneWire instance to communicate with a OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

Then, create a float variable to hold the temperature retrieved by the DS18B20 sensor.

float temperature;

The following two lines define an NTPClient to request date and time from an NTP server.

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

Then, initialize String variables to save the date and time.

String formattedDate;
String dayStamp;
String timeStamp;

setup()

When you use deep sleep with the ESP32, all the code should go inside the setup() function, because the ESP32 never reaches the loop().

Connecting to Wi-Fi

The following snippet of code connects to the Wi-Fi network. You need to connect to wi-fi to request date and time from the NTP server.

Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}

Initializing the NTP client

Next, initialize the NTP client to get date and time from an NTP server.

timeClient.begin();

You can use the setTimeOffset(<time>) method to adjust the time for your timezone.

timeClient.setTimeOffset(3600);

Here are some examples for different timezones:

  • GMT +1 = 3600
  • GMT +8 = 28800
  • GMT -1 = -3600
  • GMT 0 = 0

Initializing the microSD card module

Then, initialize the microSD card. The following if statements check if the microSD card is properly attached.

SD.begin(SD_CS); 
if(!SD.begin(SD_CS)) {
  Serial.println("Card Mount Failed");
  return;
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE) {
  Serial.println("No SD card attached");
  return;
}
Serial.println("Initializing SD card...");
if (!SD.begin(SD_CS)) {
  Serial.println("ERROR - SD card initialization failed!");
  return; // init failed
}

Then, try to open the data.txt file on the microSD card.

File file = SD.open("/data.txt");

If that file doesn’t exist, we need to create it and write the heading for the .txt file.

writeFile(SD, "/data.txt", "Reading ID, Date, Hour, Temperature \r\n");

If the file already exists, the code continues.

else {
  Serial.println("File already exists");
}

Finally, we close the file.

file.close();

Enable timer wake up

Then, you enable the timer wake up with the timer you’ve defined earlier in the TIME_TO_SLEEP variable.

esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

Initializing the library for DS18B20

Next, you initialize the library for the DS18B20 temperature sensor.

sensors.begin();

Getting the readings and data logging

After having everything initialized, we can get the readings, timestamp, and log everything into the microSD card.

To make the code easier to understand, we’ve created the following functions:

  • getReadings(): reads the temperature from the DS18B20 temperature sensor;
  • getTimeStamp(): gets date and time from the NTP server;
  • logSDcard(): logs the preceding data to the microSD card.

After completing these tasks, we increment the readingID.

readingID++;

Finally, the ESP32 starts the deep sleep.

esp_deep_sleep_start();

getReadings()

Let’s take a look at the getReadings() function. This function simply reads temperature from the DS18B20 temperature sensor.

sensors.requestTemperatures(); 
temperature = sensors.getTempCByIndex(0); // Temperature in Celsius

By default, the code retrieves the temperature in Celsius degrees. You can uncomment the following line and comment the previous one to get temperature in Fahrenheit.

//temperature = sensors.getTempFByIndex(0); // Temperature in Fahrenheit

getTimeStamp()

The getTimeStamp() function gets the date and time. These next lines ensure that we get a valid date and time:

while(!timeClient.update()) {
  timeClient.forceUpdate();
}

Sometimes the NTPClient retrieves the year of 1970. To ensure that doesn’t happen we force the update.

Then, convert the date and time to a readable format with the getFormattedDate() method:

formattedDate = timeClient.getFormattedDate();

The date and time are returned in this format:

2018-04-30T16:00:13Z

So, we need to split that string to get date and time separately. That’s what we do here:

// Extract date
int splitT = formattedDate.indexOf("T");
dayStamp = formattedDate.substring(0, splitT);
Serial.println(dayStamp);
// Extract time
timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
Serial.println(timeStamp);

The date is saved on the dayStamp variable, and the time on the timeStamp variable.

logSDCard()

The logSDCard() function concatenates all the information in the dataMessage String variable. Each reading is separated by commas.

dataMessage = String(readingID) + "," + String(dayStamp) + "," + String(timeStamp) + "," + String(temperature) + "\r\n";

Note: the “\r\n” at the end of the dataMessagevariable ensures the next reading is written on the next line.

Then, with the following line, we write all the information to the data.txt file in the microSD card.

appendFile(SD, "/data.txt", dataMessage.c_str());

Note: the appendFile() function only accepts variables of type const char for the message. So, use the c_str() method to convert the dataMessage variable.

writeFile() and appendFile()

The last two functions: writeFile() and appendFile() are used to write and append data to the microSD card. They come with the SD card library examples and you shouldn’t modify them.

To try other examples to work with the microSD card, go to File > Examples > SD(esp32).

Uploading the Code

Now, upload the code to your ESP32. Make sure you have the right board and COM port selected.

Demonstration

Open the Serial Monitor at a baud rate of 115200.

Press the ESP32 Enable button, and check that everything is working properly (the ESP32 is connected to your local network, and the microSD card is properly attached).

Let the ESP32 run for a few hours to test if everything is working as expected. After the testing period, remove the microSD card and insert it into your computer. The microSD card should contain a file called data.txt.

You can copy the file content to a spreadsheet on Google Sheets for example, and then split the data by commas. To split data by commas, select the column where you have your data, then go to Data > Split text to columns… Then, you can build charts to analyse the data.

Wrapping Up

In this tutorial we’ve shown you how to log data to a microSD card using the ESP32. We’ve also shown you how to read temperature from the DS18B20 temperature sensor and how to request time from an NTP server.

You can apply the concepts from this tutorial to your own projects. If you like ESP32 and you want to learn more, make sure you check our course exclusively dedicated to the ESP32: Learn ESP32 with Arduino IDE.

You might also like reading other articles related with ESP32:

Thanks for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

42 thoughts on “ESP32 Data Logging Temperature to MicroSD Card”

  1. It was very useful, Roy. thanks,.
    I hope, you work on projects that connecting esp8266 or esp32 to LABVIEW (Control & Monitor).

  2. Hey Rui, how are you?!
    Thankx for sharing your projects, they are clear and educationals!
    I´m not working with the NTPClient, but i has add in my project! hehehe

    Only one point… in the NPT offset, the example you show, for plus eigth hours, maybe you writing wrong, because the paramter is the hours in seconds, is this?
    I´m live in Brazil, and here we have -3 hours. So im use 10800?

    Rui, very thankyou for showing the code, was very clarance efor me!

    • Hi Carlos.
      Yes, you are right. The offset for the eight hours was wrong. We’ve already updated that.
      Thanks for noticing and for reading our projects.
      Regards,
      Sara 🙂

  3. Great tutorial, and nice to see deep sleep illustrated. It would be great to show how to do battery powered projects. I have a couple of related questions on this project– on this dev board (or other dev boards with a LiPo charger) is the USB-UART always powered on via the same 3.3V ESP module supply? (An unused USB-UART could drain a battery.) In deep sleep what is the power consumption, i.e. how long can a battery last?

    BTW, I would suggest a sleep calculated to wake at the next 10 minute real-clock interval rather than 600s, so the some seconds to make a WiFi + NTP connection doesn’t shift the interval. But that’s a pretty straightforward change in your tutorial code.

    • For a real lower power application with the ESP32, you shouldn’t use an ESP32 Development board. It’s recommended to use an ESP32 chip directly on your own PCB, because any dev board has many unnecessary components draining the batteries (even in deep sleep).

  4. Thanks !
    I have to use a battery and it seems that the largest drain is getting the network time.
    have you tried to get it once every 24hours ? or maybe every 6 hours ?

    • Hi Dave.
      I haven’t tried with 24 hours interval.
      But you can edit the deep sleep time in the code. It doesn’t have to be every 10 minutes.
      Getting the network time consumes a lot of power because the ESP32 needs to connect via Wi-Fi.
      To get very low power consumption during deep sleep, you need to use the bare ESP32 chip instead of the full development board (as we do here, but with the ESP8266 – only 7uA during deep sleep)
      Regards,
      Sara

  5. more on the delayed fetch of time
    Can the ESP32 re-set it’s internal time so that it can wake and datalog every 5 minutes, and once an hour reset the time and post error?
    jan5 6:06:02 21.3C
    jan5 6:11:122 21.5C
    jan5 6:16:24 21.3C
    jan5 6:21:33 20.9C
    jan5 6:25:04 21.3C time adjust 2951ms

  6. Hi Rui and Sandra, i have some problem with sd card. Com port show this massage:

    ets Jun 8 2016 00:22:57

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0018,len:4
    load:0x3fff001c,len:1100
    load:0x40078000,len:10312
    load:0x40080400,len:6460
    entry 0x400806a4
    Card Mount Failed

    Can u help me with this?

    • Hi Andrey,
      Please double check that the microSD card module is wired correctly to the ESP32. Make sure you are using a microSD card formatted as FAT32.
      Before continuing with the project, can you try the microSD card example available on Arduino IDE? Go to File > Examples > SD(esp32) > SD_Test.
      Upload that code and see how the microSD responds.
      Regards,
      Sara

      • Hi Sara, microSD card module is wired correctly and its work with esp12e module, but didnt work with esp32. The SD_tesr example dont work too with same result.

        • Hey Andrey, i had the same problem. The datasheet for my SD module says something about VCC-in 3.3v/5v, i used it with the 3.3v output of my esp32, which didn’t work. I then used the 5v and voila, everything worked! maybe it can help you!

  7. Hi,
    It would be awesome if one could transfer the log file over Wi-Fi (internet even), without removing the SD card !

    Could you provide some pointers on how to achieve this ?

      • Hi, I have the same question of Royce J Pereira… a way to save the file_data from SD (ESP32) to windows folder. Removing the SD card is an operation for a caveman!!! 😀 😀
        Have you any suggestion? libraries? link?
        Thanks for your support and for the detailed and usefull blog….IT’S FANTASTIC!!

      • I forgot to add an important information to my previous post: the way to save the file from SD and windows folder has to be through wi-fi connection to private network.
        If it is not possible (or too complicated), please consider that the ESP32 it is not connected to pc by USB, only by wi-fi network.
        Thanks in advance.
        regards
        Francesco

        • Hi Francesco.
          Your suggestion is a great idea.
          However, at the moment I don’t have any solution for that. That is quite a big project.
          I don’t know if there are any libraries that can do that, I haven’t search much about the subject.
          Sorry that I can’t help much and thank you for following our work.
          Regards,
          Sara

          • Hi, thanks for reply.
            I surfed in net to find solutions….and I found it…
            forum.arduino.cc/index.php/topic,93502.msg707104.html#msg707104
            I could use the FTP way. The library WIFI should permit to choose the right address and the right gate for a FTP server. Then with ftp command I can copy the file from sd to server… it seems good… what do you think? 😉
            Bye. Francesco

  8. Should this project work with the newer AI Thinker boards, that have the built in card reader (and camera, but we do not always have to use it)? I imagine that would save a lot of wiring.

    • Hi John.
      I haven’t tried it. But I think it should work by doing the proper pin assignment in the code.
      Regards,
      Sara

  9. HI,
    I cannot understand why my post is disappearing while it is “awaiting moderation”.

    Anyway this is my 3rd attempt.

    I am always getting ‘Card Mount Failed’.

    But the in built SD_test example works fine.

    Why could this be happening.

    • If you try to submit multiple comments very quickly, it will probably block you and flag the comment as spam.
      I’m not sure… That usually means that you either need to double-check your wiring or if you have formatted the MicroSD card in the properly.

      • Hi, thanks for the response.

        But as I said in my comment, The inbuilt SD_test example works fine .
        (i.e. File > Examples > SD(esp32) > SD_Test.)

        Only the code from this project is failing.

        The wiring in both cases is the same!

        Thank you!

  10. Yes.
    Strangely, after retrying it the next day, it worked fine with both programs, without changing a thing…

    Thank you for taking the trouble to check!
    ——-
    (Unrelated) I have observed the following in your code:

    In line 81:
    SD.begin(SD_CS);
    if(!SD.begin(SD_CS)) { ….

    Is the 1st SD.begin necessary ?

    Again in line 91 once again we have :
    Serial.println(“Initializing SD card…”);
    if (!SD.begin(SD_CS)) { …

    This code will never be reached if already failed in line 82 above.
    Otherwise, SD card is already initialized in line 81/82, so I think no need for this again?

    And let me thank you for all these projects and the courses. I’m learning a lot! 🙂

    • I’m glad it is working now.
      Yes, you are right. We have to fix the code.
      Thank you for pointing that out.
      Regards,
      Sara

  11. Hello,

    First, an excellent tutorial and guide.

    However, I have the same problem with SD card as reported by Andrey
    on April 3 2019 — “Card Mount Failed” error.

    I have checked that wiring is correct.
    The microSD card is formatted as FAT32.
    I can write/read files to it when plugged into PC.
    I have also tried File > Examples > SD(esp32) > SD_Test: That gives same error.
    ( Contrary to Royce, May 1, for whom the test example worked )
    I have tried suggestion by Andi (Apr 11), connecting SD module VCC to 5V: Still the same error.
    I have tried a second SD card module, also same error.

    Andrey’s thread ends without any solution reported. I wonder if he found a fix?
    In Royce’s case the problem vanished the next day! I don’t hold much hope
    for that to happen for me.

    So for now I am stuck! Any suggestions you can offer?
    Many thanks, Ken.

    • Hi Ken.
      If you’ve double-check the wiring, tried an external power source and you’ve tried with 5V and nothing worked, I don’t know what can be the problem.
      I’m sorry that I can’t help much, the example works just fine for me.
      Regards,
      Sara

  12. Hello Again,
    To follow-up on my comment of 18 May about “Card Mount Failed” error.
    I have connected my SD card to an ATMega328, and uploaded
    File>Examples>SD>ReadWrite
    using a USBtiny programmer.
    This work just fine; I can write to and read from the SD card.
    So there is nothing wrong with my card or connections.

    But when I use the ESP32 DoIt Dev Board with
    File > Examples > SD(esp32) > SD_Test
    I consistently get “Card Mount Failed” error.

    Compiling the ATMega328 sketch, the following is reported:
    Using library SPI at version 1.0 in folder: C:\Program Files (x86)\arduino-1.8.9\hardware\arduino\avr\libraries\SPI
    Using library SD at version 1.2.3 in folder: C:\Program Files (x86)\arduino-1.8.9\libraries\SD

    But compiling the ESP32sketch, the following is reported:
    Multiple libraries were found for “SD.h”
    Used: C:\Users\Ken\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\SD
    Not used: C:\Program Files (x86)\arduino-1.8.9\libraries\SD
    Using library SPI at version 1.0 in folder: C:\Users\Ken\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\SPI
    Using library SD at version 1.0.5 in folder: C:\Users\Ken\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\SD
    Using library FS at version 1.0 in folder: C:\Users\Ken\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\FS

    So the ESP32 version uses different code for the SD card (as would be expected). This strongly suggests that the problem is with the code.

    It seems from the Comments that quite a lot of your followers have this problem, and some have managed to find a fix. But for now I am completely stuck, and can go no further with my project. Perhaps you can suggest another forum that might be able to help?
    With thanks, ken.

  13. Hello Again,

    Solution found to my “Card Mount Failed” error.

    After many hours trying to fix this problem, as a last resort
    I tried using another ESP32 DoIt Dev Board (I had purchased two
    boards). And it worked! The boards are new from RS, so thought
    it very unlikely that one would be faulty, especially as the faulty
    board seemed to work OK in other respects, eg. connecting successfully
    to WiFi.

    As always, the problem is with the last thing you try. Now it’s
    onwards and upwards!

    Thanks, Ken.

    • Hi Ken.
      I’m glad you solved your problem.
      So, it was a problem in your previous ESP32 board, right?
      Regards,
      Sara

      • Hi Sara,
        Yes, that’s right — faulty board. I have swapped them back and
        forth a few times and one is OK, the other always fails.
        Very unexpected, but maybe I was just unlucky.
        Regards, ken.

        • Hi Ken.
          Yes, it is very unexpected.
          I’ve worked with several ESP32 boards from different vendors and I’ve never had a faulty one.
          Maybe it is bad luck 🙁
          Regards,
          Sara

  14. Hi,
    Ken here again.
    First, apologies for such a long comment.

    Following my earlier comments, ending on 1 June, everything was working just fine, and continued to work for a couple of weeks. But now, after doing other unrelated stuff for about a week, I have gone back to the data logging project, and a new problem has appeared! As far as I’m aware I have not changed anything significant, in particular, I have changed nothing in the code (anyway, problem is not the code)

    I have selected board “ESP32 Dev Module”
    and programmer “Arduino as ISP”
    (These are what I used when it was working)
    Compile is OK.
    I then attempt Upload Using Programmer.
    I get following error message:

    java.lang.NullPointerException
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingProgrammer(SerialUploader.java:314)
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:89)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:82)
    at processing.app.SketchController.upload(SketchController.java:736)
    at processing.app.SketchController.exportApplet(SketchController.java:703)
    at processing.app.Editor$DefaultExportAppHandler.run(Editor.java:2125)
    at java.lang.Thread.run(Thread.java:748)

    To eliminate code issues, I have tried an absolute minimum sketch, as follows:
    void setup() {
    }
    void loop() {
    }
    Obviously this does nothing, but it compiles OK.
    But on Upload Using Programmer I get same error message:

    If I unplug the board I get exactly same error. This implies the problem occurs before it even get as far as trying to communicate with board.

    This happens when I select any ESP32 board, but does NOT happen when I select any Arduino board, when I just get the expected “programmer is not responding” error.

    I have uninstalled Java and re-installed Java release 1.8.0_211
    I have uninstalled Arduino IDE, deleted folder “C:\Users\Ken\AppData\Local\Arduino15”,
    and then re-installed latest version 1.8.9 (which is what I have been using).
    I then install the ESP32 Board in Arduino IDE (Windows instructions) exactly
    as in the link you give to
    https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/

    Following this, no change, still get same error.

    I have uninstalled Arduino IDE again, deleted folder “C:\Users\Ken\AppData\Local\Arduino15”,
    and then re-installed OLDER version 1.8.7

    And again, no change, still get same error.

    All the above indicates that there is nothing wrong with the sketch, and nothing wrong with the board, and to repeat — it all worked fine about a week ago, and I am not aware of having changed anything significant.

    I have spent several hours Googling “java.lang.NullPointerException”.
    There are many links, mostly just confusing and not offering a fix.
    The main message seems to be that there is a mistake in the code, and indeed the error message seems to be pointing at errors at specific lines
    in seven different .java files (see above).

    But I have done a search of my whole C drive and cannot find any of these .java files.

    So I’m stuck again!
    Any suggestions on what I should do?
    Thank you, Ken.

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.