The IDE reported that global variables used 1199 bytes (58%).
For temporary debugging I added 18 sets of lines like this to void setup() :
Serial.print("Tracks in folder 01\t"); Serial.print(myDFPlayer.readFileCountsInFolder(1)); Serial.print("\n");
delay(50);
The global variables jumped to 1577 (77%) and I had a 'Low memory..instability..' message.
Should I be surprised at this? If I want to use these variables elsewhere, such as to get a total of those 18 file counts, or in void loop(), must I now define them all again myself? Presumably reducing storage even more?
If it's relevant, I'm using the DFRobot library:``` #include "SoftwareSerial.h"
There were 18 file counts, with an initial header set, i.e:
// TEMP INFO
Serial.print("File counts \t"); Serial.print(myDFPlayer.readFileCounts()); Serial.print("\n");
delay(50);
Serial.print("Tracks in folder 01\t"); Serial.print(myDFPlayer.readFileCountsInFolder(1)); Serial.print("\n");
delay(50);
Serial.print("Tracks in folder 02\t"); Serial.print(myDFPlayer.readFileCountsInFolder(2)); Serial.print("\n");
delay(50);
// etc
// etc
Serial.print("Tracks in folder 18\t"); Serial.print(myDFPlayer.readFileCountsInFolder(18)); Serial.print("\n");
delay(50);
I'm not sure what you mean by Make "Tracks in folder " a const global string, why that would help? And trying any of these three in my initial code all gave errors, presumably because my syntax is wrong?
const char "Tracks in folder ";
String "Tracks in folder ";
String Tracks in folder ;
Thanks, got it. But I found no difference in the memory usage. With my original (no F macro, no for loop) it uses:
1615 bytes of dynamic memory (78%, prompting the stability message)
10174 bytes of program storage.
After adding the statement
const char * tracksText = "Tracks in folder ";
the numbers were identical.
Using the F macro gave:
1223 bytes of dynamic memory (59%)
9418 bytes of program storage (29%)
Again, your constant made no difference.
And what about the extra instructions that are needed to get this 1 character from PROGMEM to Serial.print()? OK, those instructions are also in PROGMEM, but still I guess it is not really worth it for one character...
well the function is already loaded for the other prints with the F() macro and a longer text, so you don't eat up more memory for the code, but the pointer will be 2 bytes whereas the char itself is only 1 byte. and if you use write() it's faster.
Duh, yes, of course! I have yet to study that asterisk (pointer?) stuff and had assumed it was a sort of #define.
With this replacing my function, your suggestion does indeed give a small reduction, 1255 down to 1249 bytes:
void folderCountsUKH()
{
/////////// TEMP INFO ON FOLDER COUNTS //////////////////////
Serial.print("File counts \t");
Serial.print(myDFPlayer.readFileCounts());
Serial.print("\n");
delay(50);
for (int i = 1; i <= 18; i++)
{
Serial.print("tracksText ");
Serial.print(i);
Serial.print("\t");
Serial.print(myDFPlayer.readFileCountsInFolder(i));
Serial.print("\n");
delay(50);
}
}
With the following that number is 1223 bytes.
( I'm only applying it to 3 folders at the moment, not 18, although that appears to make no difference.)
void folderCounts2()
{
/////////// TEMP INFO ON FOLDER COUNTS //////////////////////
Serial.print(F("File counts \t"));
Serial.print(myDFPlayer.readFileCounts());
Serial.print(F("\n"));
delay(50);
for (int i = 1; i <= 3; i++)
{
Serial.print(F("Tracks in folder "));
Serial.print(i);
Serial.print(F("\t"));
Serial.print(myDFPlayer.readFileCountsInFolder(i));
Serial.print(F("\n"));
delay(50);
}
}
P.S. Unlikely, but if any other user of DFRobotDFPlayerMini library sees this: have you succeeded in getting readFileCountsInFolder() to work reliably? That's yet another failing in this this buggy and woefully documented library. This thread was a good learning exercise, thanks to all, but I've now abandoned use of the command.
Print typically builds an ASCII representation of what you are asking to send out and then sends those bytes out (using write)
write takes literally the binary representation of the parameter and sends it out.
For example with a number
Serial.print(65);
Will send out the ascii code for 6 and the ascii code for 5 as print understood you wanted to see the integer printed out.
whereas
Serial.write(65);
will send out ONE byte which decimal value is 65. If the target is the Serial monitor you will see a capital A as 65 is the ascii code for ‘A‘ and the serial monitors interprets bytes as an ASCII flow
When you send only one char like "X" or F("X") (note the double quote), there is no need to use print which will dereference the pointer to the const string and go through the steps of looking at the length of the string (which is just 1) and do a loop to call write for each byte. Just calling write with a char notation (simple quote) is thus more effective.