I'm working on a C++ program to communicate with an Arduino that's running an automated system. I'm using the serial library from this:
https://playground.arduino.cc/Interfacing/CPPWindows
I'm trying to send the Arduino a string which it will then parse into a command that will tell it how the system should move. The code for reading the command from the serial is this:
`void serialEvent() {
while (Serial.available()) {
char in = (char)Serial.read();
input.concat(in);
}
int endChar = input.indexOf('\r');
if (endChar != -1) {
//inputLog.concat(input);
//inputLog.concat('\n');
String command = input.substring(0,endChar);
command.toLowerCase();
input.remove(0, endChar+1);
String keyword = command.substring(0,4);
if(keyword == "move"){
int i = command.indexOf('x');
if (i != -1) {
endChar = command.indexOf(i, ',');
xMove = command.substring(i + 1, endChar).toFloat();
}
i = command.indexOf('y');
if (i != -1) {
endChar = command.indexOf(i, ',');
yMove = command.substring(i + 1, endChar).toFloat();
}
} else if (keyword == "stop") {
xMove = 0;
yMove = 0;
} else if (keyword == "xpos") {
Serial.print("X: ");
Serial.println(xPos);
} else if (keyword == "ypos") {
Serial.print("Y: ");
Serial.println(yPos);
} else if (keyword == "getp") {
Serial.print("X: ");
Serial.print(xPos);
Serial.print(", Y: ");
Serial.println(yPos);
} else if (keyword == "setx") {
xPos = command.substring(4).toFloat();
} else if (keyword == "sety") {
yPos = command.substring(4).toFloat();
} else if (keyword == "setp") {
int i = command.indexOf('x');
if (i != -1) {
endChar = command.indexOf(i, ',');
xPos = command.substring(i + 1, endChar).toFloat();
}
i = command.indexOf('y');
if (i != -1) {
endChar = command.indexOf(i, ',');
yPos = command.substring(i + 1, endChar).toFloat();
}
} else if (keyword == "getl") {
Serial.println(inputLog);
inputLog = "";
} else {
Serial.println("error: 1");
return;
}
Serial.println("ok\r");
//Serial.print(nc);
}
}`
This part seems to be running correctly, because I can run it with the Arduino Serial Monitor and it works. Here is a short test of the code I wrote in C++:
while (SP->IsConnected())
{
string outputData = "";
cin >> outputData;
outputData.append(pcr);
//outputData.append(pnc);
writeResult = SP->WriteData((char*)outputData.c_str(), outputData.length());
//writeResult = writeResult && SP->WriteData(pnc, 1);
//writeResult = writeResult & SP->WriteData(pcr, 1);
while (true) {
Sleep(500);
char incomingData[256] = "";
readResult = SP->ReadData(incomingData, dataLength);
//printf("Bytes read: (0 means no data available) %i\n", readResult);
//incomingData[readResult] = 0;
input.append(incomingData, 0, readResult);
check_ok = input.find(pcr);
check_error = input.find(error);
if (check_ok != string::npos || check_error != string::npos || readResult == 0) {
cout << "Receiving: " << input << '\n';
input.clear();
break;
}
}
}
The variable, pcr is defined earlier in the code as a pointer to the carriage return character, which the Arduino uses to identify the end of a command. My results of running this code is that the Arduino seems to read off the first command and execute it; however, it also reads off several gibberish characters, most of which equate to -52 as a numerical value. Any following commands don't seem to do anything and the arduino continues getting the gibberish characters. Additionally it seems that the ReadData function in C++ works fine. Does anyone know why this occurs? Is the Arduino's serial buffer getting corrupted by the WriteData function somehow?
Solved
I appear to have found the issue. The statement outputData(pcr) needed to be outputData(pcr, 0, 1) because the pointer was not null terminating. Thus the string was appending extra characters until it reached a null character.