I'm trying to chase down why, when I run these commands, my code hangs on my Mega 2560 and I'm wondering if it is because I'm using Strings instead of cstrings?
I'm using Strings because I'm familiar with that due to a .net background and I'm reluctant to switch to cstrings due to unfamiliarity and what appears to be the need to define the array size in advance, however I've read where people have seen strange behavior from Strings and if the following behavior is an example of that?
When I run the commands below and uncomment a line inside of loop() ( Serial.println(" end of (serialInString.startsWith(write:))"); ) the program will freeze up. When I comment it out, the program works as expected.
Does this appear to be due to using Strings? If so, how hard is it to convert over everything to cstrings?
Commands
write:weighttarget=12
read:weighttarget
write:weighttarget=14
read:weighttarget
Code
#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <TimeLib.h>
#include <string.h>
#include <TinyGPS++.h>
#include <Time.h>
//SoftwareSerial BTSerial(12, 13); // RX , TX
#define BTSerial Serial1
String serialInString;
boolean newData = false;
boolean newBtData = false;
unsigned long btLastSendTimeStamp;
bool isSpecialChar(char chr)
{
if (chr == ':')
{
return true;
}
else if (chr == '=')
{
return true;
}
else if (chr == '-')
{
return true;
}
else
{
return false;
}
}
bool validateDataType(String dataType, char* data) // true is indeed 1, and false is 0.
{
if (dataType == "string")
{
//String stringToTest = "isthisanactualstring";
//for (int i = 0; i < stringLength; i++)
for (int i = 0; i < strlen(data); i++)
{
if (isAlpha(data[i]))
{
// continue
//Serial.print(i);
//Serial.print(" - ");
//Serial.println(data[i]);
}
else
{
//Serial.print(i);
//Serial.print("? - ");
//Serial.println(data[i]);
return false;
}
}
return true;
}
else if (dataType == "int")
{
for (int i = 0; i < strlen(data); i++)
{
if (isDigit(data[i]))
{
// continue
//Serial.print(i);
//Serial.print(" - ");
//Serial.println(data[i]);
}
else
{
//Serial.print(i);
//Serial.print("? - ");
//Serial.println(data[i]);
return false;
}
}
//Serial.println("About to return true for int");
return true;
}
else if (dataType == "float")
{
int decimalPointCount = 0;
for (int i = 0; i < strlen(data); i++)
{
if (isDigit(data[i]))
{
// continue
//Serial.print(i);
//Serial.print(" - ");
//Serial.println(data[i]);
}
else if (data[i] == '.')
{
decimalPointCount++;
if (decimalPointCount > 1)
{
//Serial.print(i);
//Serial.print("? - ");
//Serial.println(data[i]);
return false;
}
//Serial.print(i);
//Serial.print(" - ");
//Serial.println(data[i]);
}
else
{
//Serial.print(i);
//Serial.print("? - ");
//Serial.println(data[i]);
return false;
}
}
if (decimalPointCount != 1)
{
return false;
}
else
{
return true;
}
}
else if (dataType == "time")
{
Serial.println("dataType == 'time'");
Serial.print("data: "); Serial.println(data);
int colonCount = 0;
for (int i = 0; i < strlen(data); i++)
{
if (isDigit(data[i]))
{
// continue
Serial.print(i);
Serial.print(" - ");
Serial.println(data[i]);
}
else if (data[i] == ':')
{
colonCount++;
if (colonCount > 1) // will need to make it > 2 if including seconds
{
//Serial.print(i);
//Serial.print("? - ");
//Serial.println(data[i]);
return false;
}
Serial.print(i);
Serial.print(" - ");
Serial.println(data[i]);
}
else
{
Serial.print(i);
Serial.print("? - ");
Serial.println(data[i]);
return false;
}
}
if (colonCount != 1) // will need to make it > 2 if including seconds
{
return false;
}
else
{
return true;
}
}
} // validateDataType
int getEePromAddress(String settingName)
{
int returnValue;
//Serial.print("getEePromAddress() settingName: "); Serial.println(settingName);
if (settingName == "automation")
{
returnValue = 20;
}
else if (settingName == "empty")
{
returnValue = 30;
}
else if (settingName == "full")
{
returnValue = 40;
}
else if (settingName == "alldays")
{
returnValue = 50;
}
else if (settingName == "alldaystime")
{
returnValue = 60;
}
else if (settingName == "sundays")
{
returnValue = 70;
}
else if (settingName == "sundaytime")
{
returnValue = 80;
}
else if (settingName == "mondays")
{
returnValue = 90;
}
else if (settingName == "mondaytime")
{
returnValue = 100;
}
else if (settingName == "tuesdays")
{
returnValue = 110;
}
else if (settingName == "tuesdaytime")
{
returnValue = 120;
}
else if (settingName == "wednesdays")
{
returnValue = 130;
}
else if (settingName == "wednesdaytime")
{
returnValue = 140;
}
else if (settingName == "thursdays")
{
returnValue = 150;
}
else if (settingName == "thursdaytime")
{
returnValue = 160;
}
else if (settingName == "fridays")
{
returnValue = 170;
}
else if (settingName == "fridaytime")
{
returnValue = 180;
}
else if (settingName == "saturdays")
{
returnValue = 190;
}
else if (settingName == "saturdaytime")
{
returnValue = 200;
}
else if (settingName == "chime")
{
returnValue = 210;
}
else if (settingName == "weighttarget")
{
returnValue = 220;
}
else
{
returnValue = -1;
}
return returnValue;
}
String eePromReadAllAddresses()
{
String returnValue = "";
String s_EEPromValue = "";
int startAddress = 20;
int endAddress = 210;
int addressPadding = 10;
for (int i = startAddress; i <= endAddress; i = (i + addressPadding))
{
String s_eepromReadAll = eePromReadAnyType(i);
s_EEPromValue = eePromReadAnyType(i);
//Serial.print(i); Serial.print(" s_EEPromValue: "); Serial.println(s_EEPromValue);
returnValue += s_EEPromValue + "|";
}
return returnValue;
}
String eePromReadAnyType(int eeAddress)
{
//Serial.print("function: "); Serial.println("eePromReadAnyType");
int eeAddressIndexer = eeAddress;
String returnValue;
char chr;
int maxeeAddressToReadTo = (eeAddress + 10);
//Serial.print("eeAddressIndexer: "); Serial.println(eeAddressIndexer);
//Serial.print("maxeeAddressToReadTo: "); Serial.println(maxeeAddressToReadTo);
do
{
chr = EEPROM.read(eeAddressIndexer);
if ((chr != '\0') && ((isAlphaNumeric(chr)) || isSpecialChar(chr)))
{
//Serial.print("eeAddressIndexer: "); Serial.println(eeAddressIndexer);
//Serial.print("eePromReadAnyType: "); Serial.println(chr);
returnValue += chr;
}
eeAddressIndexer = (eeAddressIndexer + 1);
} while ((chr != '\0') && (eeAddressIndexer <= maxeeAddressToReadTo));
return returnValue;
}
String getSettingValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++)
{
//Serial.println(data.charAt(i));
if (data.charAt(i) == separator || i == maxIndex)
{
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
} // getSettingValue
void eePromWriteAnyType(int eeAddress, String eeValue)
{
Serial.print("eepromWriteAnyType"); Serial.print(" -- eeAddress: "); Serial.print(eeAddress); Serial.print(", eeValue: "); Serial.println(eeValue);
char c_eeValue[eeValue.length()]; // instantiate character array
eeValue.toCharArray(c_eeValue, (eeValue.length() + 1));
Serial.print("c_eeValue: "); Serial.println(c_eeValue);
int indexer = 0;
for (int i = 0; i < strlen(c_eeValue); i++)
{
//Serial.println(c_eeValue[i]);
Serial.print("char: "); Serial.print(c_eeValue[i]); Serial.print(", written to address: "); Serial.println(eeAddress + i);
EEPROM.write((eeAddress + i), c_eeValue[i]);
indexer = (eeAddress + i);
}
Serial.print("slash 0 written to address: "); Serial.println(indexer + 1);
EEPROM.write((indexer + 1), '\0');
Serial.println("Exiting function eePromWriteAnyType()");
}
void setup()
{
Serial.begin(9600);
BTSerial.begin(9600);
while (!Serial)
{
; // Wait for serial to connect
}
while (!BTSerial)
{
; // Wait for BTSerial to connect
}
delay(2000);
Serial.println("");
Serial.println(" ***** Pet Assistant ***** ");
Serial.println("");
btLastSendTimeStamp = millis();
}
void loop()
{
while(Serial.available()>0 && newData == false)
{
serialInString = Serial.readStringUntil('\n\r');
Serial.print("New serial data: "); Serial.println(serialInString);
newData = true;
delay(15);
if (serialInString.equals("readall"))
{
Serial.println("command = readall");
Serial.println(eePromReadAllAddresses());
}
if (serialInString.startsWith("read:"))
{
Serial.print("startsWith(read:) :"); Serial.println(serialInString);
String s_settingNameToRead = getSettingValue(serialInString, ':', 1);
Serial.print("s_settingNameToRead: "); Serial.println(s_settingNameToRead);
int getEepromAddr = getEePromAddress(s_settingNameToRead);
Serial.print("getEepromAddr: "); Serial.println(getEepromAddr);
String s_eepromReadAnyType = eePromReadAnyType(getEepromAddr);
Serial.print("s_eepromReadAnyType: "); Serial.println(s_eepromReadAnyType);
}
if (serialInString.startsWith("write:"))
{
Serial.print("startsWith(write:) : "); Serial.println(serialInString);
String s_settingToWriteUnparsed = getSettingValue(serialInString, ':', 1);
Serial.print("s_settingToWriteUnparsed: "); Serial.println(s_settingToWriteUnparsed);
String s_settingNameToWrite = getSettingValue(s_settingToWriteUnparsed, '=', 0);
Serial.print("s_settingNameToWrite: "); Serial.println(s_settingNameToWrite);
String s_settingValueToWrite = getSettingValue(s_settingToWriteUnparsed, '=', 1);
Serial.print("s_settingValueToWrite: "); Serial.println(s_settingValueToWrite);
int getEepromAddr = getEePromAddress(s_settingNameToWrite);
if (getEepromAddr != -1)
{
eePromWriteAnyType(getEepromAddr, s_settingValueToWrite);
Serial.println("right after eePromWriteAnyType");
//String s_eepromReadAnyType = eePromReadAnyType(getEepromAddr);
//Serial.print("s_eepromReadAnyType: "); Serial.println(s_eepromReadAnyType);
}
Serial.println(" end of (serialInString.startsWith(write:))"); // somehow this hoses the entire setup function and the code never starts
}
if (serialInString.startsWith("validate:"))
{
Serial.print("startsWith(validate:) :"); Serial.println(serialInString);
String s_settingDataTypeAndValue = getSettingValue(serialInString, ':', 1);
Serial.print("s_settingDataTypeAndValue: "); Serial.println(s_settingDataTypeAndValue);
String s_dataType = getSettingValue(s_settingDataTypeAndValue, '=', 0);
Serial.print("s_dataType: "); Serial.println(s_dataType);
String s_dataValue = getSettingValue(s_settingDataTypeAndValue, '=', 1);
Serial.print("s_dataValue: "); Serial.println(s_dataValue);
validateDataType(s_dataType, s_dataValue.c_str());
Serial.print("validateDataType: "); Serial.println(validateDataType(s_dataType, s_dataValue.c_str()));
}
newData = false;
Serial.println("Exiting while(Serial.available()>0 && newData == false)");
}
delay(5);
newData = false;
newBtData = false;
} // loop