Ok, so I am newer to the Arduino and have a question of efficiency of char vs string. Please correct me where I am going wrong with my understanding! I am writing a rather large program and am worried about crashing. I'm trying to optimize where I can, and from what I have read I should avoid strings because of the potential for memory fragmentation.
The part of code that I have question about is when I load my system setpoints from the SD card. This will only occur in the case of a power failure, or a restart. That being said however I will have parts of code that I have yet to write that would follow a similar pattern.
I didn't write all the first code, I did modify it. I forgot where I originally got it from my apologies to the author I tried to find it with no success.
Here is the method that uses strings.
void getParameters() {
char inChar;
String parameter;
String paramValue;
myFile = SD.open("sysParam.txt");
if (myFile) {
while (myFile.available()) {
inChar = myFile.read();
while ((myFile.available()) && (inChar != '[')) {
inChar = myFile.read();
}
inChar = myFile.read();
while ((myFile.available()) && (inChar != ',')) {
parameter = parameter + inChar;
inChar = myFile.read();
}
inChar = myFile.read();
while ((myFile.available()) && (inChar != ']')) {
paramValue = paramValue + inChar;
inChar = myFile.read();
}
if (inChar == ']') {
Serial.print(F("\nParameter Name: "));
Serial.print(parameter);
Serial.print(F("\nParameter Value: "));
Serial.print(paramValue);
applySetting(parameter, paramValue);
parameter = "";
paramValue = "";
}
}
myFile.close();
}
else {
Serial.print(F("\nError opening systems parameter file"));
errorCode = 1;
printError(0, 100);
}
}
void applySetting(String parameter, String paramValue) {
if (parameter == "pHL")
pH_lowerLimit = paramValue.toFloat();
else if (parameter == "pHU")
pH_upperLimit = paramValue.toFloat();
else if (parameter == "DOSet")
DO_lowerLimit = paramValue.toFloat();
else if (parameter == "WV")
wasteVolume = paramValue.toFloat();
else if (parameter == "RV")
reactorVolume = paramValue.toFloat();
else if (parameter == "DV")
decantVolume = paramValue.toFloat();
else if (parameter == "sampleRate")
sampleRate = paramValue.toFloat();
else if (parameter == "dataRate")
dataRate = parameter.toFloat();
else {
errorCode = 2;
#if DEBUG
Serial.print(F("\nError: Invalid parameter in *.ini file (2)"));
#endif
printError(0, 100);
}
return;
}
and the method using only char
void getData(char dType) {
char inChar;
char parameter[4];
char paramValue[8];
int count = 0;
if (dType == 'S')
myFile = SD.open("sysParam.txt");
else if (dType == 'F')
myFile = SD.open("flow.ini");
if (myFile) {
while (myFile.available()) {
inChar = myFile.read();
while (myFile.available() && inChar != '[') {
inChar = myFile.read();
}
for (int x = 0; x < 3; x++) {
parameter[x] = myFile.read();
}
parameter[3] = '\0';
inChar = myFile.read();
inChar = myFile.read();
while (myFile.available() && inChar != ']') {
paramValue[count] = inChar;
inChar = myFile.read();
count++;
}
paramValue[count] = '\0';
count = 0;
if (inChar == ']') {
Serial.print(F("\nParameter Name: "));
Serial.print(parameter);
Serial.print(F("\nParameter Value: "));
Serial.print(paramValue);
applySetting(parameter, paramValue);
parameter[0] = '\0';
paramValue[0] = '\0';
}
}
myFile.close();
}
else {
Serial.print(F("\nError opening systems parameter file"));
}
}
void applySetting (char parameter[], char paramValue[]) {
if (parameter[0] == 'p' && parameter[1] == 'H' && parameter[2] == 'L')
pH_lowerLimit = atof(paramValue);
else if (parameter[0] == 'p' && parameter[1] == 'H' && parameter[2] == 'U')
pH_upperLimit = atof(paramValue);
else if (parameter[0] == 'd' && parameter[1] == 'O' && parameter[2] == 'L')
DO_lowerLimit = atof(paramValue);
else if (parameter[0] == 'w' && parameter[1] == 'M' && parameter[2] == 'L')
wasteVolume = atof(paramValue);
else if (parameter[0] == 'r' && parameter[1] == 'M' && parameter[2] == 'L')
reactorVolume = atof(paramValue);
else if (parameter[0] == 'd' && parameter[1] == 'M' && parameter[2] == 'L')
decantVolume = atof(paramValue);
else if (parameter[0] == 's' && parameter[1] == 'S' && parameter[2] == 'R')
sampleRate = atof(paramValue);
else if (parameter[0] == 'd' && parameter[1] == 'S' && parameter[2] == 'R')
dataRate = atof(paramValue);
else if (parameter[0] == 'a' && parameter[1] == 'F' && parameter[2] == 'R')
acidFlowRate = atof(paramValue);
else if (parameter[0] == 'b' && parameter[1] == 'F' && parameter[2] == 'R')
baseFlowRate = atof(paramValue);
else if (parameter[0] == 'w' && parameter[1] == 'F' && parameter[2] == 'R')
wasteFlowRate = atof(paramValue);
else if (parameter[0] == 'd' && parameter[1] == 'F' && parameter[2] == 'R')
dilutionFlowRate = atof(paramValue);
else if (parameter[0] == 'f' && parameter[1] == 'F' && parameter[2] == 'R')
feedFlowRate = atof(paramValue);
else {
errorCode = 2;
Serial.print(F("\nInvalid parameter in file"));
printError(0, 100);
}
}
What I'm doing is reading a file that has the following format [parameter,parameterValue]
parameter will always be 3 characters, the parameter value will differ from parameter to parameter in length.
I also realize that I am sending a char to the function in example #2. Thats because I had to rewrite the function because I am storing different setpoints in different files. For the types of setpoints it makes sense to do it that way.
Both sets of code work fine, no issues taking in the data.
Which one is more efficient? Does it matter? I'm think I have some understanding of the issues with memory fragmentation and stack overflow, but yet again I think I could be completely wrong.
Thanks for the help!