I'vve been having a problem with garbage characters and strange data coming through a serial connection I'm trying to set up between an arduino and a raspi. The arduino is used to gather data from various sensors and transmits it to the raspi as a comma separated line, once per "frame" (not ideal, but still more than fast enough for my needs)
When using the arduino serial interface on my windows machine, or when using "sudo screen /dev/ttyACM0 115200,cs8" on the raspberrypi, the data comes through fine, so I am reasonably sure that the arduino is not the problem.
I have the following code to make a connection on the raspi side:
int serial::openPort(std::string portName)
{
int serialPort;
serialPort = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (serialPort == -1)
{
std::cout << "open_port: Unable to open " << portName;
}
else
{
struct termios portOptions;
//set up the port so reading nothing returns immediately, instead of blocking
fcntl(serialPort, F_SETFL, FNDELAY);
// Fetch the current port settings
tcgetattr(serialPort, &portOptions);
// Flush the port's buffers (in and out) before we start using it
tcflush(serialPort, TCIOFLUSH);
// Set the input and output baud rates
cfsetispeed(&portOptions, B115200);
cfsetospeed(&portOptions, B115200);
// c_cflag contains a few important things- CLOCAL and CREAD, to prevent
// this program from "owning" the port and to enable receipt of data.
// Also, it holds the settings for number of data bits, parity, stop bits,
// and hardware flow control.
portOptions.c_cflag |= CLOCAL;
portOptions.c_cflag |= CREAD;
// Set up the frame information.
portOptions.c_cflag &= ~PARENB;
portOptions.c_cflag &= ~CSTOPB;
portOptions.c_cflag &= ~CSIZE;
portOptions.c_cflag |= CS8;
// Now that we've populated our options structure, let's push it back to the
// system.
tcsetattr(serialPort, TCSANOW, &portOptions);
// Flush the buffer one more time.
tcflush(serialPort, TCIOFLUSH);
}
return serialPort;
}
And the following should read all of the data in the buffer:
std::string serial::readData(int serialPort)
{
char buffer[64];
int bytesRead = 0;
std::string returnString;
do
{
bytesRead = read(serialPort, buffer, sizeof(buffer));
if(bytesRead > 0)
returnString.append(buffer, bytesRead);
} while (bytesRead == sizeof(buffer));
return returnString;
}
which is then processed in this loop: (I am only using the last "frame" of data that is coming in, because the data from the arduino comes in much faster than I can display it on the raspi)
gaugeDataBuffer += serial::readData(port);
std::cout << gaugeDataBuffer;
while(true)
{
newLineLocation = gaugeDataBuffer.find("\r\n");
if (newLineLocation == std::string::npos)
break;
gaugeDataStrings = utility::split(gaugeDataBuffer.substr(0, newLineLocation), ',');
gaugeDataBuffer = gaugeDataBuffer.substr(newLineLocation + 2);
}
The problem here, is when the data gets pushed to the console (the cout in the last code block), it is sometimes mangled. I would expect a nice orderly series of lines of data, but sometimes I get strange control characters, letters, data lines that are truncated, etc.
I have a feeling that it is happening in the second to last code block, where I am appending any new data to the returnstring, but am unsure if that is the case, or how to fix it.
Any help would be greatly appreciated.