Hello everyone!
I am attempting to use Qt to create a GUI for an RGB lighting system. Everything is going pretty well, but I've run into trouble with Serial programming. Specifically, I have some spurious characters after the ones I 'should' get.
Following the following links as guides, I tried to tackle reading and writing for a Qt using the qextserialport library:
(Arduino / library) http://forum.arduino.cc/index.php/topic,20987.0.html
(library API) http://docs.qextserialport.googlecode.com/git/1.2/qextserialport.html
My Arduino code is a fairly straightforward "echo"
unsigned long serial_speed = 9600;
void setup() {
Serial.begin(serial_speed);
}
void loop() {
if (Serial.available() > 0) {
Serial.write(Serial.read());
}
delay(50);
}
My Qt code is maybe a little bit less straightforward, but here are the essentials. Setup (assuming default Serial settings from Serial.begin() - Arduino Reference , no parity bit, one stop, 8 chars ):
MySerialPort QextSerialPort;
void ConnectToPort()
{
QString portname = "/dev/tty.usbmodem621"; // or whatever the case may be,
MySerialPort = new QextSerialPort(portname, QextSerialPort::EventDriven);
this->MySerialPort->setBaudRate(BAUD9600);
this->MySerialPort->setFlowControl(FLOW_OFF);
this->MySerialPort->setParity(PAR_NONE);
this->MySerialPort->setDataBits(DATA_8);
this->MySerialPort->setStopBits(STOP_1);
this->MySerialPort->setTimeout(500);
if (this->MySerialPort->open(QIODevice::ReadWrite) == true) {
// this next line just connects the serial port to a function for handling communication.
// every time Qt thinks we have a character, the function gets called
connect(MySerialPort, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
}
else {
// error handling code here, not important to my issue
}
}
The code for sending:
void SendRGB(void)
{
if (!MySerialPort->isOpen()) { ConnectToPort();}
if (!MySerialPort->isWritable()) { qDebug("Could not write!"); }
int NumColors = 3;
char rgb[NumColors] = {76 , 34 , 77}; // values are unimportant, just for debugging
printf("Writing:[ ");
for(int i=0; i < NumColors; i++)
{
printf(" %d ",rgb[i]);
MySerialPort->write(&(rgb[i]),1); // write a single character
}
printf(" ] \n");
MySerialPort->flush(); // wait for all the characters to get to the port
}
Finally, the reading code:
void onReadyRead()
{
QByteArray result;
unsigned int numExpected = WidgetRGB::NumColors;
unsigned int bytesAvailable = this->MySerialPort->bytesAvailable();
if (bytesAvailable < numExpected) { return; }
result.resize(bytesAvailable);
this->MySerialPort->read(result.data(), bytesAvailable);
printf("\t Read: [%d]: ",bytesAvailable);
for (unsigned int j=0; j< bytesAvailable; j++)
{
printf("[%d], ", (unsigned char) result.data()[j]);
}
printf("\n");
}
The problem is the output:
Writing:[ 76 34 77 ] // this is good!
Read: [3]: [76], [34], [77], // hurrah! We got them back!
Read: [3]: [10], [96], [206], // wait, what?
Read: [3]: [191], [95], [255], // noooooooo!
I did a little looking at an ASCII table ( http://www.cdrummond.qc.ca/cegep/informat/professeurs/alain/images/ASCII1.GIF ) -- the only one I cam make sense of is the '10', which is a Line feed. Pretty unclear what the rest are. Here are some things I tried:
- Changing the Baud Rate
- Adding different timeouts and waits
- ... but nothing helped!
My question is really two part (1) Are these spurious characters intended? I suppose I could look into the Serial source code, but it doesn't seem like others are having difficulties on the net. (2) Are there any (elegant) ways around this? I know I could just 'assume' I only need 3 characters, and just gobble up the remaining, but that seems pretty tacky.
Sorry for the length! Happy to address any questions. Note that I heavily simplified the Qt code to make it easier for you all!