Introduction: How to Burn MicroSD Files With ESP32

About: Do you like technology? Follow my channel on Youtube and my Blog. In them I put videos every week of microcontrollers, arduinos, networks, among other subjects.

This is the continuation of a previous video where I used the 1.8-inch TFT display, which is a 128-by-160 graphic display. I think this graphic display is super cool. This time, our circuit will use an adapter and a 32 GB microSD.

If you’d like to see the first video, access: Value your project: use graphical display!

Step 1: Demonstration

Step 2: Resources Used

· ESP32-WROOM

· 1.8 '' TFT Lcd Display

· Protoboard

· Jumpers

· SD card

· Button

· 10k ohm resistor

Step 3: Assembly - 1.8 '' TFT Display Pinout

Step 4: Mounting ESP-WROOM32 With 1.8 '' TFT Display

Step 5: ESP-WROOM32 Connection Table and 1.8 '' TFT Display

Step 6: SD Card Formatting for FAT32 (Recommended)

• Format the SD card as FAT32, and use a USB adapter like this:

• Use a program to format it, such as GUIformat:

Download: https://www.techtudo.com.br/tudO-sobre/fat32-format.html

Step 7: Library Required

Step 8: Install the Library

1. Click Include Library -> Add Library .ZIP

2. On the search screen, browse to the downloaded ZIP file and click open

Step 9: Code ESP-WROOM Code 32

Declarations and variables

#include <Adafruit_GFX.h> // Biblioteca de gráficos
#include <Adafruit_ST7735.h> // Biblioteca do hardware ST7735 #include <SPI.h> // Biblioteca para comunicação SPI #include <Fonts/FreeSerif9pt7b.h> // Fonte Serif que é usada no display #include "SD_File_Record.h" // Biblioteca com as funções referentes ao SD card // ESP32-WROOM #define TFT_DC 12 // A0 #define TFT_CS 13 // CS #define TFT_MOSI 14 // SDA #define TFT_CLK 27 // SCK #define TFT_RST 0 // RESET #define TFT_MISO 0 // MISO // Objeto do display tft Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST); // Variável que guarda uma mensagem de erro caso aconteça algum problema com o display ou SD card String errorMsg; // Botão usado para excluir o arquivo do cartão SD const int buttonPin = 33; // Flag que impede que o display pisque quando o botão estiver pressionado bool flag = false; // Altura da fonte que é usada no display int fontHeight = 7; const int MICROSD_PIN_CHIP_SELECT = 21; // Pino serial const int MICROSD_PIN_MOSI = 19; // Pino serial const int MICROSD_PIN_MISO = 18; // Pino serial const int MICROSD_PIN_SCK = 22; // Clock pin // Instancia um objeto SD_File_Record enviando o nome do arquivo e o tamanho máximo dos registros (sem contar o \r\r) no construtor, ou seja, o tamanho real será de 3+2 = 5 SD_File_Record ObjSD("test.txt", 3);

Setup

void setup()
{ // Inicia a serial com velocidade de 9600 Serial.begin(115200); // Seta botão como entrada (INPUT) pinMode(buttonPin, INPUT); // Inicia display TFT com a tela preta tft.initR(INITR_BLACKTAB); // Limpa display, seta a fonte e posiciona cursor no início resetDisplay(); // Exibe na serial "Starting..." Serial.print("Starting..."); // Inicializa cartão SD if(!ObjSD.init(MICROSD_PIN_CHIP_SELECT, MICROSD_PIN_MOSI, MICROSD_PIN_MISO, MICROSD_PIN_SCK)) { // Se não obteve sucesso, exibe no display e reinicia o ESP tft.println("\nSD begin fail\n"); Serial.println("SD begin fail"); delay(1000); ESP.restart(); } // Se obteve sucesso exibe no display Serial.println("SD card ok"); // Escreve no arquivo os números sequenciais writeNewRecord(); // Lê o arquivo e exibe no display showFile(); // Função que busca um registro // String reg = ObjSD.findRecord(10); // 10 é a posição do registro }

Clearing Display and Displaying Data

// Limpa o display e posiciona o cursor no início
void resetDisplay() { tft.setFont(&FreeSerif9pt7b); tft.fillScreen(ST77XX_BLACK); tft.setTextColor(ST7735_WHITE); tft.setCursor(0,fontHeight+5); tft.setTextSize(1); } // Lê e exibe o arquivo void showFile() { // Variável usada para guardar a linha lida do arquivo txt String linha; // Contador usado para limpar o display quando o texto não couber mais int count = 0; // Exibe no display e na serial o início do arquivo Serial.println("# Begin of file #"); tft.println("# Begin of file #"); // Enquanto for possível ler a próxima linha do arquivo ObjSD.rewind(); while(ObjSD.readFileNextLine(&linha, &errorMsg)) { // Se ocorreu algum erro durante a leitura if(errorMsg != "") { // Exibe o erro no display e aborta o while tft.println(errorMsg); break; } // Incrementa contador count++; // Se o contador for divisivel por 6 (qtde de linhas que cabem no display com esta fonte) if(count % 6 == 0) { //Exibe "..." sinalizando que ainda não é o fim do arquivo tft.println("..."); // Aguarda 1.5s para poder visualizar os valores delay(1500); // Limpa display resetDisplay(); }

Displaying Display and Writing to File

// Exibe a linha obtida no display e na Serial
tft.println(linha); Serial.println(linha); } //Fim do while // Exibe no display e na serial indicando fim do arquivo Serial.println("# End of file #"); tft.println("# End of file #"); } // Escreve os números sequencias no arquivo void writeNewRecord() { // String que será escrita no arquivo txt String line; // Inteiro que receberá o número da última linha registrada int nLine; // Se o arquivo não existe if(!ObjSD.fileExists()) ObjSD.newFile(); // Cria o arquivo // Lê a última linha do arquivo if(!ObjSD.readFileLastLine(&line,&errorMsg) && errorMsg != "") tft.println(errorMsg); else if(errorMsg == "") // Se foi possível ler o arquivo { // Se o arquivo estiver vazio if(line == "") line = "001"; // Atribui para a String o primeiro valor da sequência (1) else // Se o arquivo não estiver vazio { // Converte String para int e incrementa 1 nLine = atoi(line.c_str())+1; // Insere zeros à esquerda conforme o número atual do registro if(nLine < 10) line = "00"; else if(nLine < 100) line = "0"; // Converte o novamente o valor para String line += String(nLine); } // Escreve no arquivo a String "line" if(!ObjSD.writeFile(line, &errorMsg)) tft.println(errorMsg); // Se existir um erro durante a escrita, exibe no display } else tft.println(errorMsg); // Se existir um erro, exibe no display }

Loop

void loop()
{ // Se o botão foi pressionado e a flag estiver "false" if(digitalRead(buttonPin) == HIGH && !flag) { // Tenta excluir o arquivo if(ObjSD.destroyFile()) showFileDeleted(true); // Se obteve sucesso, chama a função "showFileDeleted" enviando valor "true" else showFileDeleted(false); // Se não obteve sucesso, chama a função "showFileDeleted" enviando valor "false" // Impede que o display pisque e que o ESP tente excluir o arquivo mais de uma vez flag = true; } else if(digitalRead(buttonPin) == LOW && flag) // Se o botão foi solto e a flag estiver "true" { // Limpa display resetDisplay(); // Exibe arquivo showFile(); // Impede que o display pisque e que o ESP tente excluir o arquivo mais de uma vez flag = false; } // Aguarda 10ms delay(10); }

SD_File_Record Library - Header

// ifndef evita erros de duplicação ao chamar esta lib mais de uma vez
#ifndef SD_File_Record_h #define SD_File_Record_h #include //Biblioteca Arduino (opcional) #include // Biblioteca referente ao cartão SD // Classe SD_File_Record e suas funções class SD_File_Record { // Todas as funções desta lib são publicas, mais detalhes em SD_File_Record.cpp public: SD_File_Record(String, int); SD_File_Record(String); bool init(int, int, int, int); bool readFileLastLine(String *, String *); bool destroyFile(); String findRecord(int); void rewind(); bool writeFile(String, String *); bool seekFile(int); bool readFileNextLine(String *, String *); String getFileName(); void setFileName(String); int getSizeRecord(); void setSizeRecord(int); void newFile(); bool fileExists(); };

Declarations and Variables, Constructors and Init

// Importamos o header referente a lib SD_File_Record
#include "SD_File_Record.h" // Nome do arquivo em que os registros serão salvos String fileName; // Ponteiro do arquivo File pFile; /* ############################## Importante ############################## O registro tem tamanho FIXO de 3 caracteres e seus valores são de: 001 002 003 004 005 ... 999 ########################################################################## */ // Tamanho do registro (default 3) int sizeOfRecord = 5; // Exemplo: // 001\r\n = 5 caracteres // Construtor que seta o nome do arquivo e o tamanho do registro SD_File_Record::SD_File_Record(String _fileName, int _sizeOfRecord) { fileName = _fileName; sizeOfRecord = _sizeOfRecord+2; } // Construtor que seta somente o nome do arquivo deixando o tam do registro default SD_File_Record::SD_File_Record(String _fileName){ fileName = _fileName; } // Funcao de inicialização que configura o Cartão SD com os pinos recebidos por parametro bool SD_File_Record::init(int _MICROSD_PIN_CHIP_SELECT, int _MICROSD_PIN_MOSI, int _MICROSD_PIN_MISO, int _MICROSD_PIN_SCK) { return SD.begin(_MICROSD_PIN_CHIP_SELECT, _MICROSD_PIN_MOSI, _MICROSD_PIN_MISO, _MICROSD_PIN_SCK); }

Reading the file

// Lê a próxima linha do arquivo
bool SD_File_Record::readFileNextLine(String *line, String *errorMsg) { // Se o ponteiro estiver nulo if(!pFile) { // Abre arquivo para leitura pFile = SD.open(fileName.c_str(), FILE_READ); // Se aconteceu algum erro if(!pFile) { // Guarda msg de erro *errorMsg = "Failed to open the file"; // Retorna falso return false; } } // Se for possível ler o arquivo if(pFile.available()) { // Lê arquivo *line = pFile.readStringUntil('\n'); // Retorna true return true; } // Se não for possível ler o arquivo retorna falso return false; }

Pointer positioning and writing to file

//Posiciona ponteiro do arquivo na posição "pos"
bool SD_File_Record::seekFile(int pos) { // Se o ponteiro estiver nulo if(!pFile) pFile = SD.open(fileName.c_str(), FILE_READ); // Abre o arquivo para leitura // Posiciona o ponteiro na posição multiplicando pelo tamanho do registro return pFile.seek(sizeOfRecord*pos); } // Escreve no arquivo bool SD_File_Record::writeFile(String line, String *errorMsg) { // Abre arquivo para escrita pFile = SD.open(fileName.c_str(), FILE_WRITE); // Se foi possível abrir if (pFile) { // Escreve registro pFile.println(line); // Fecha arquivo pFile.close(); // Retorna true return true; } // Se não foi possível abrir guarda mensagem de erro e retorna false *errorMsg = "Failed to open the file: "+String(fileName); return false; }

Positioning at the beginning of the file and last line reading

// Posiciona ponteiro no início do arquivo
void SD_File_Record::rewind() { pFile.seek(0); } // Lê o último registro do arquivo bool SD_File_Record::readFileLastLine(String *line, String *errorMsg) { // Variável que guardará o tamanho do arquivo int sizeArq; // Limpa string *errorMsg = ""; // Se o arquivo está aberto, fecha if(pFile) pFile.close(); // Abre o arquivo para leitura pFile = SD.open(fileName.c_str(), FILE_READ); // Se não foi possível abrir o arquivo if(!pFile) { // Guarda mensagem de erro e retorna false *errorMsg = "Failed to open the file: "+String(fileName); return false; } // Obtém o tamanho do arquivo sizeArq = pFile.size(); // Se existe ao menos um registro if(sizeArq >= sizeOfRecord) pFile.seek(sizeArq-sizeOfRecord); // Posiciona o ponteiro no final do arquivo menos o tamanho de um registro (sizeOfRecord) // Lê registro retornando o resultado da função "readFileNextLine" return readFileNextLine(*&line, *&errorMsg); }

File Deletion and Search

// Exclui arquivo
bool SD_File_Record::destroyFile() { // Se o arquivo estiver aberto, fecha if(pFile) pFile.close(); // Exclui arquivo e retorna o resultado da função "remove" return SD.remove((char*)fileName.c_str()); } // Função que busca um registro // "pos" é a posição referente ao registro buscado String SD_File_Record::findRecord(int pos) { // Linha que receberá o valor do registro buscado String line = "", errorMsg = ""; // Posiciona na posição desejada // Obs. A posição se inicia com zero "0" if(!seekFile(pos)) return "Seek error"; // Lê o registro if(!readFileNextLine(&line, &errorMsg)) return errorMsg; return line; }

File exists, new file, and get and set functions

// Verifica se o arquivo existe
bool SD_File_Record::fileExists() { return SD.exists((char*)fileName.c_str()); } // Cria um novo arquivo, se já existir o arquivo será removido antes void SD_File_Record::newFile() { if(pFile) pFile.close(); SD.remove((char*)fileName.c_str()); pFile = SD.open(fileName.c_str(), FILE_WRITE); pFile.close(); } // Obtém o nome do arquivo String getFileName() { return fileName; } // Seta o nome do arquivo void setFileName(String _fileName) { fileName = _fileName; } // Obtém o tamanho do registro int getSizeRecord() { return sizeOfRecord-2; } // Seta o tamanho do registro void setSizeRecord(int _sizeOfRecord) { sizeOfRecord = _sizeOfRecord+2; }

Step 10: Files

Download the files:

PDF

INO