ESP32Sim800L issues with SD.open

Hi,
Im using a ESP32Sim800L to post sensor data to a google sheet for my project. However the issue is that SD.open returns a 0. Any ideas ?

const char apn[]      = "net";            // Access Point Name (APN) !!! SET ACCORDINGLY
const char gprsUser[] = "";               // GPRS User
const char gprsPass[] = "";               // GPRS Password
const char simPIN[]   = "0123";           // SIM card PIN

const char server[] = "maker.ifttt.com";                                                // Domain name
const char resource[] = "/trigger/ESP32SIM800L/with/key/zfR3-3glTE0rkEX6NLv3N" ;        // Resource path
const String apiKeyValue = "";                                     // API key
const int  port = 80;                                                                   // Server port number

#define MODEM_RST            5            // TTGO T-Call pins
#define MODEM_PWKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define I2C_SDA              21
#define I2C_SCL              22

#include "FS.h"
#include <SPI.h>          // SD card module
#include <SD.h>           // SD card
////const int chipSelect = 15;// SD card chip
File txtFile;             // Create a file to store the data

SPIClass sdSPI(HSPI);
#define SCK  14 //yellow
#define MISO  2 //blue
#define MOSI  13 //green
#define CS  15 //brown

#define SerialMon Serial                 // Set serial for debug console
#define SerialAT Serial1                 // Set serial for AT commands

#define TINY_GSM_MODEM_SIM800            // Modem is SIM800
#define TINY_GSM_RX_BUFFER   1024        // Set RX buffer to 1Kb

//#define DUMP_AT_COMMANDS               // Define the serial console for debug prints

#include <Wire.h>
#include <TinyGsmClient.h>

#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

TinyGsmClient client(modem);             // TinyGSM Client for Internet connection

#define uS_TO_S_FACTOR 1000000UL   /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) 3600 seconds = 1 hour */

void setup() {

  //pinMode(CS, OUTPUT);

  SerialMon.begin(115200);               // Set serial monitor
  pinMode(MODEM_PWKEY, OUTPUT);          // Set modem reset, enable, power pins
  pinMode(MODEM_RST, OUTPUT);
  pinMode(MODEM_POWER_ON, OUTPUT);
  digitalWrite(MODEM_PWKEY, LOW);
  digitalWrite(MODEM_RST, HIGH);
  digitalWrite(MODEM_POWER_ON, HIGH);

  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);           // Set GSM module baud rate and UART pins
  delay(3000);

  SerialMon.println("Initializing modem...");
  modem.restart();
  //  use modem.init()                                               // If don't need the complete restart

  if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
    modem.simUnlock(simPIN);                                        // Unlock your SIM card
  }
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);    // Configure the wake up source as timer wake up
}

void loop() {
  SerialMon.print("Connecting to APN: ");
  SerialMon.print(apn);
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println(" fail");
    delay(3000);
    return;
  }
  else {
    SerialMon.println(" OK");

    SerialMon.print("Connecting to ");
    SerialMon.print(server);
    if (!client.connect(server, port)) {
      SerialMon.println(" fail");
      delay(3000);
      return;
    }
    else {
      SerialMon.println(" OK");
      sdSPI.begin(SCK, MISO, MOSI, CS);
      if (!SD.begin(CS, sdSPI)) {                // Check SD card
        Serial.println("SD CARD NOT FOUND");
        delay(3000);
        //return;
      }
      else {
        Serial.println("SD CARD FOUND");
        txtFile.close();
      }
      txtFile = SD.open("DATA.txt", FILE_APPEND);
      if (txtFile) {
        Serial.println("- – Reading start – -");
        char character;
        while ((character = DATA.txt.read()) != -1) { // this while loop reads data stored in "DATA.txt" and prints it to serial monitor
          Serial.print(character);
        }
        txtFile.close();
        Serial.println("- – Reading end – -");
      } else {
        Serial.println("Could not open file (reading).");
        Serial.println(txtFile);
      }
      //for (int i = 0; i<sizeof (temp_storage); i++){ }
      int h = 9;
      int t = 12;
      int h1 = 1988979878;
     // sendDataToSheet("&value1=" + String(int(h)) + "&value2=" + String(int(t)) + "&value3=" + String(int(h1)));
    }
    esp_deep_sleep_start();                   // Put ESP32 into deep sleep mode
  }
}
void sendDataToSheet(String parameters) {

  SerialMon.println("Performing HTTP POST request...");         // Making an HTTP POST request

  String httpRequestData = "api_key=" + apiKeyValue + parameters;

  client.print(String("POST ") + resource + " HTTP/1.1\r\n");
  client.print(String("Host: ") + server + "\r\n");
  client.println("Connection: close");
  client.println("Content-Type: application/x-www-form-urlencoded");
  client.print("Content-Length: ");
  client.println(httpRequestData.length());
  client.println();
  client.println(httpRequestData);

  unsigned long timeout = millis();
  while (client.connected() && millis() - timeout < 10000L) {

    while (client.available()) {                    // Print available data (HTTP response from server)
      char c = client.read();
      SerialMon.print(c);
      timeout = millis();
    }
  }
  SerialMon.println();

  client.stop();                                    // Close client and disconnect
  SerialMon.println(F("Server disconnected"));      // Disconnect server
  modem.gprsDisconnect();
  SerialMon.println(F("GPRS disconnected"));        // Disconnect GPRS
}

I'm missing a link to the used hardware.

My guess is a wiring problem or a not formatted SD card.

I got a broken computer it does not show the schematic or links either.

Hardware:
ESP32SIM800L
Micro SD Card Adapter
16 GB Sand Disk Micro SD Card

Micro SD card & ESP32SIM800L connections:

  • SCK IO14
  • MISO IO2
  • MOSI IO13
  • CS IO15
    *VCC and GND of Micro SD card are connected to the 5V-out and GND respectively.
    *The SD card is only detected using the corresponding HSPI connections configuration for some reason.

Solutions that I have considered/tried:

  • Using an Arduino Mega 2560 to read and write a text file to the SD card module works as intended, indicating that the micro SD card and adapter are functioning.
  • The micro SD card is formatted to MS-Dos FAT32.
  • Another discussion on this forum confer a similar issue whereby sd.open returns 0. This discussion suggests that it can likely be caused by insufficient static RAM (sRAM). As of now I am working on determining the amount of sRAM left on heap.

Update:

  • I used the ESP.getFreeHeap() function, still to no avail. The output was 351060 which is way more than the necessary static memory of 500 bytes for the sd.open. Any avenues or takes on this matter ? I don't mind an alternative method to accomplish the intended results of reading the SD card.

Unfortunately there is no schematics for that board. So we cannot tell if that board can be used with the ESP.

Maybe possible but the Mega2560 is a 5V board while the ESP32 runs on 3.3V. If the board outputs 5V to the SPI bus it may have destroyed the ESP pin.

Yeah you're right I couldn't find a schematic for the SD card adapter as well. But plenty of sources on youtube show that this board is compatible with ESP32. The ESP32SIM800L module actually has a 5V output while the SD card adapter has a built-in voltage regulator, hence the board should work fine right ?

Wrong. The 5V pin is not explicitly an output. It just offers the 5V the board gets from the USB bus to other components but may also be an input if the board is not powered by the USB bus in which case it provides the power to the voltage regulator that generates the 3.3V the ESP32 needs.

If the board is one of the cheap Chinese modules (and it looks like that) the SPI signal lines are converted to 5V which is definitely over the voltage range the datasheet defines.

  1. The ESP32SIM800L is powered by the USB bus in my case
  2. Then shouldn't this issue not persist if the micro SD card adapter is powered with an independent 5V power supply ?
  3. If not then what should I do ?

I assumed that.

No, it's not a problem of not enough current (most probably) but of a wrong signal voltage.

Get an SD card adapter from one of the suppliers which does it right (Adafruit, Sparkfun, etc.) or insert a level converter yourself but ensure you get one that is able to switch at SPI speeds.
In any case you must test your ESP SPI pins if they are not fried already.

Generally: Don't buy any board you don't get schematics for! Otherwise you have incredibly more work to do because you have to reverse engineer every board before you can use it. Believe me, it's worth the price of the established providers if you make the calculation right.

I am pleased to say the issue has been solved. The solution to this issue is SIMPLE and lies with the filename. I'm no expert but a black-slash should precede the filename as "/DATA.txt". The credit goes to sergyegorov, who debugs a similar issue. Live and learn. Thanks @pylon for the help too. To anyone requiring a future reference the UPDATED code is as follows:

const char apn[]      = "";            // Access Point Name (APN) !!! SET ACCORDINGLY
const char gprsUser[] = "";               // GPRS User
const char gprsPass[] = "";               // GPRS Password
const char simPIN[]   = "";           // SIM card PIN

const char server[] = "";                                                // Domain name
const char resource[] = "" ;        // Resource path
const String apiKeyValue = "";                                     // API key
const int  port = 80;                                                                   // Server port number

#define MODEM_RST            5            // TTGO T-Call pins
#define MODEM_PWKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define I2C_SDA              21
#define I2C_SCL              22

#include "FS.h"
#include <SPI.h>          // SD card module
#include <SD.h>           // SD card
File txtFile;             // Create a file to store the data

SPIClass sdSPI(HSPI);
#define SCK  25 //yellow
#define MISO 2 //blue
#define MOSI 26 //green
#define CS  33 //orange

#define SerialMon Serial                 // Set serial for debug console
#define SerialAT Serial1                 // Set serial for AT commands

#define TINY_GSM_MODEM_SIM800            // Modem is SIM800
#define TINY_GSM_RX_BUFFER   1024        // Set RX buffer to 1Kb

//#define DUMP_AT_COMMANDS               // Define the serial console for debug prints

#include <Wire.h>
#include <TinyGsmClient.h>

#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

TinyGsmClient client(modem);             // TinyGSM Client for Internet connection

#define uS_TO_S_FACTOR 1000000UL   /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) 3600 seconds = 1 hour */

void setup() {

  //pinMode(CS, OUTPUT);

  SerialMon.begin(115200);               // Set serial monitor
  pinMode(MODEM_PWKEY, OUTPUT);          // Set modem reset, enable, power pins
  pinMode(MODEM_RST, OUTPUT);
  pinMode(MODEM_POWER_ON, OUTPUT);
  digitalWrite(MODEM_PWKEY, LOW);
  digitalWrite(MODEM_RST, HIGH);
  digitalWrite(MODEM_POWER_ON, HIGH);

  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);           // Set GSM module baud rate and UART pins
  delay(3000);

  SerialMon.println("Initializing modem...");
  modem.restart();
  //  use modem.init()                                               // If don't need the complete restart

  if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
    modem.simUnlock(simPIN);                                        // Unlock your SIM card
  }
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);    // Configure the wake up source as timer wake up
}

void loop() {
  SerialMon.print("Connecting to APN: ");
  SerialMon.print(apn);
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println(" fail");
    delay(3000);
    return;
  }
  else {
    SerialMon.println(" OK");

    SerialMon.print("Connecting to ");
    SerialMon.print(server);
    if (!client.connect(server, port)) {
      SerialMon.println(" fail");
      delay(3000);
      return;
    }
    else {
      SerialMon.println(" OK");
      sdSPI.begin(SCK, MISO, MOSI, CS);
      if (!SD.begin(CS, sdSPI)) {                // Check SD card
        Serial.println("SD CARD NOT FOUND");
        delay(3000);
        //return;
      }
      else {
        Serial.println("SD CARD FOUND");
        txtFile.close();
      }
      txtFile = SD.open("/DATA.txt", FILE_READ);
      if (txtFile) {

        //        while ((char character = DATA.txt.read()) != -1) { // this while loop reads data stored in "DATA.txt" and prints it to serial monitor
        //          Serial.print(character);
        Serial.println(txtFile);
        txtFile.close();

      }
      else {
        Serial.println("File ERROR");
        //        Serial.println(txtFile);
      }
      //for (int i = 0; i<sizeof (temp_storage); i++){ }
      int h = 9;
      int t = 12;
      int h1 = 1988979878;
      // sendDataToSheet("&value1=" + String(int(h)) + "&value2=" + String(int(t)) + "&value3=" + String(int(h1)));
    }
    esp_deep_sleep_start();                   // Put ESP32 into deep sleep mode
  }
}
void sendDataToSheet(String parameters) {

  SerialMon.println("Performing HTTP POST request...");         // Making an HTTP POST request

  String httpRequestData = "api_key=" + apiKeyValue + parameters;

  client.print(String("POST ") + resource + " HTTP/1.1\r\n");
  client.print(String("Host: ") + server + "\r\n");
  client.println("Connection: close");
  client.println("Content-Type: application/x-www-form-urlencoded");
  client.print("Content-Length: ");
  client.println(httpRequestData.length());
  client.println();
  client.println(httpRequestData);

  unsigned long timeout = millis();
  while (client.connected() && millis() - timeout < 10000L) {

    while (client.available()) {                    // Print available data (HTTP response from server)
      char c = client.read();
      SerialMon.print(c);
      timeout = millis();
    }
  }
  SerialMon.println();

  client.stop();                                    // Close client and disconnect
  SerialMon.println(F("Server disconnected"));      // Disconnect server
  modem.gprsDisconnect();
  SerialMon.println(F("GPRS disconnected"));        // Disconnect GPRS
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.