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.
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.
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.
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
}