I have an App where I send Hex-Strings to my ESP32. I would like these strings, as they are, to be sent via an RS232 to TTL module, that is connected to my ESP, to a scaler.
On my App side I am sending this command:
"\\e\\x34\\x54\\x45\\x53\\x54\\r" //This translates to ascii ESC4TESTCarriageReturn
It needs double escaped characters in order to actually send a single backslash.
On my microcontroller side I am doing:
//This reads the incoming BT message
String message = SerialBT.readStringUntil('\n');
//This sends the message, converted to a char *
Serial2.write(message.c_str());
In theory, I am receiving the correct string as you can see in the serial monitor output:
BT Message received: \e\x34\x54\x45\x53\x54\r
The command to be sent via rs232: \e\x34\x54\x45\x53\x54\r
Error: E10 //This indicates that the message could not be processed by the receiver
However, if I send the message staright up like this, predefined in my microcontroller code I get the correct response from the receiver:
Serial2.write("\e\x34\x54\x45\x53\x54\r");
------ Output ------
Test4 //This indicates that Testpattern 4 was selected
I am not that familiar with c++ so I am probably doing something obviously wrong, maybe anyone knows, how I can convert the received BT-Message to an actual message that can be sent over Serial2.
Edit: So basically my question is, how can I achieve a transaltion of the string that I am receiving via bluetooth (\e\x34\x54\x45\x53\x54\r) to be converted as it is, into a Hex-string that is interpreted correctly by the microcontroller and is therefore correctly sent over rs232.
The solution is to write an own parser. Since you say you control the BT sender side, you don't need all of the common capabilities of the C++ standard.
We see these different kinds of substrings for single characters:
"\e"
for '\e'
;"\x##"
for '\x##'
, "##" being a two-digit hex number;"\r"
for '\r'
.This is a small test sketch for a straight-forward solution:
void setup() {
while (!Serial);
String message = "\\e\\x34\\x54\\x45\\x53\\x54\\r";
Serial.println(message);
String toSend = unescape(message);
for (int c : toSend) {
Serial.print(c, HEX);
}
Serial.println();
}
void loop() {
}
String unescape(String &escaped) {
String unescaped;
for (size_t index = 0; index < escaped.length(); index++) {
if (escaped[index] == '\\') {
index++;
switch (escaped[index]) {
case 'e':
unescaped += '\e';
break;
case 'x':
index++;
{
char hex = strtol(escaped.substring(index, index + 2).c_str(), 0, 16);
unescaped += hex;
}
index++;
break;
case 'r':
unescaped += '\r';
break;
default:
break;
}
}
}
return unescaped;
}
Please note that this simple suggestion has some minor issues you don't want in professional software:
unescape()
. Actually, it silently returns an incomplete or erroneous result, if the input has errors.String
that is slow and bulky.Use it as a starting point for your own better solution.