I started an Arduino project that could execute instructions from an SD card file on the screen. I managed to do it, but another problem appeared: I can't print all the files from the SD card to the serial port to show it on the pc. I think it happened because of the lack of memory. Since I'm using an Arduino Nano, my sketch takes up 90% of the memory and 71% of the dynamic memory. I assumed so because the function works perfectly if I shorten the code I would like to hear suggestions on how to optimize my code to make it work again or hear what the problem is if I'm wrong.
Here is my code:
#include <Adafruit_GFX.h> #include <Adafruit_ST7735.h> #include <SPI.h> #include <SD.h> //SD: //GND = GND //VCC = 5v //MISO = 12 //MOSI = 11 //SCK = 13 //CS = 10 //ST7735: //GND = GND //VCC = 5v //DC = 7 //RES = 5 //CS = 6 //SDA = 11 //SCL = 13 //BLK # Sd2Card card; SdVolume volume; SdFile root; const int chipSelect = 10; String mode; int len; #define TFT_CS 6 #define TFT_RST 5 #define TFT_DC 7 int x = 0; int y = 0; int color; String codeStr = "Screen.SetObjectColor('0')\nScreen.SetCursor('120,32')\nScreen.SetTextSize('3')\nScreen.Print('SF')"; //code to execute Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); String split(String text, String separator, int index){ //splits string by separator and returns string by the index for(int i = 0; i < index; i++){ text = text.substring(text.indexOf(separator)+1,text.length()); } return(text.substring(0,text.indexOf(separator))); } void compile(String code) { //executes command if (code.indexOf("Screen.Print(") != -1) { tft.setCursor(x, y); tft.print(code.substring(14, code.length()-2)); } else if (code.indexOf("Screen.SetCursor(") != -1) { x = code.substring(18, code.indexOf(",")).toInt(); y = code.substring(code.indexOf(",")+1, code.length()-2).toInt(); tft.setCursor(x,y); } else if (code.indexOf("Screen.SetObjectColor(") != -1) { tft.setTextColor(code.substring(23, code.length()-2).toInt()); color = code.substring(23, code.length()-2).toInt(); } else if (code.indexOf("Screen.Fill(") != -1) { tft.fillScreen(code.substring(13, code.length()-2).toInt()); } else if (code.indexOf("Screen.SetTextSize(") != -1) { tft.setTextSize(code.substring(20, code.length()-2).toInt()); } else if (code.indexOf("Screen.DrawLine(") != -1) { tft.drawLine(x, y, code.substring(17, code.indexOf(",")).toInt(), code.substring(code.indexOf(",")+1, code.length()-2).toInt(), color); } } void showFiles(File dir, int numTabs) { //i got this form SD example and it dose not work here but if i delete some code to clear memory it will while (true) { File entry = dir.openNextFile(); if (!entry) { dir.rewindDirectory(); break; } for (uint8_t i = 0; i < numTabs; i++) { Serial.print('\t'); } Serial.print(entry.name()); if (entry.isDirectory()) { Serial.println("/"); showFiles(entry, numTabs + 1); } else { Serial.print("\t\t"); Serial.println(entry.size(), DEC); } entry.close(); } } //functions that triggers from the serial port in void loop() void state(){ if (card.init(SPI_HALF_SPEED, chipSelect)) { Serial.print("Wiring is correct and a card is present."); } } void createFile(String text, String dir){ File newFile = SD.open(dir, FILE_WRITE); newFile.print(text); newFile.close(); } void readFile(String dir){ File readingFile = SD.open(dir, FILE_READ); if (readingFile) { while (readingFile.available()) { Serial.write(readingFile.read()); } readingFile.close(); } } int countLines(String file){ int del = -1; int count = 0; String string = SD.open(file, FILE_READ).readString(); while(true){ if(string.indexOf("\n", (del + 1)) == -1){ return(count); break; } else{ del = string.indexOf("\n", (del + 1)); count++; } } } void setup() { Serial.begin(9600); tft.initR(INITR_MINI160x80); tft.setRotation(3); tft.fillScreen(ST7735_WHITE); } void loop() { if (!SD.begin(chipSelect)) { Serial.println("SD card mount failed!"); while (true); } while (!Serial) {;} //gets input from the serial port String input = Serial.readString(); if (input == "showfiles" or input == "sf") { //prints directory(don`t work) showFiles(SD.open("/"), 0); } else if (input == "state" or input == "s") { state(); } else if (input == "clearinput" or input == "ci") { SD.remove("file.txt"); } else if (input == "delete" or input == "d" or mode == "d") { mode = "d"; delay(100); if (input!="d" and input!="delete"){ SD.remove(input); } } else if (input == "deletefolder" or input == "df" or mode == "df") { mode = "df"; delay(100); if (input!="df" or input!="deletefolder"){ SD.rmdir(input); } } else if (input == "rename" or input == "rn" or mode=="rn") { mode = "rn"; delay(1000); if (input!="rn" and input!="rename"){ File renameFile = SD.open("file.txt"); String text = ""; while (renameFile.available()){ text += (char)renameFile.read(); } renameFile.close(); createFile(text.substring(text.length()-len ,text.length()), input); } } else if (input == "create" or input == "c" or mode == "c") { mode = "c"; delay(100); if (input!="c" and input!="create" and input.length()!=0){ len = input.length(); createFile(input, "file.txt"); } } else if (input == "createfolder" or input == "cf" or mode == "cf") { mode = "cf"; delay(100); if (input!="cf" and input!="createfolder"){ SD.mkdir(input); } } else if (input == "read" or input == "r" or mode == "r") { mode = "r"; delay(100); readFile(input); } else if (input == "cl" or mode == "cl") { mode = "cl"; delay(100); if (input!="cl"){ Serial.print(countLines(input)); } } for(int i = 0; i < 4; i++){ //compiles every line in text(i'll make it so that the file executes here) compile(split(codeStr, "\n", i)); } }