arduinoserial-portarduino-unoccd

My Qt app does not recieve all the data sent by arduino


I'll go right to the point. My arduino reads values from the adc port and send them via serial port(values from 0 to 255). I save them in a byte type vector. After sending an specific signal to arduino, it starts to send to Qt app the data saved in the vector. Everything is working except that the arduino should send 800 values and the app receives less values than that. If I set the serial baud rate to 9600, I get 220 values. If, instead, I set the baud rate to 115200, I get only 20 values. Can you guys help me to fix this? I would like to use 115200 baud rate, because I need a good trasmision speed at this project(Real time linear CCD). I'll leave some code below:

Arduino code:

void sendData(void)
{
    int x;

    for (x = 0; x < 800; ++x)
    {
        Serial.print(buffer[x]);
    }
}

This is the function that sends the values. I think is enough information, so I summarized it. If you need more code, please let me know.

Qt serial port setting code:

...

// QDialog windows private variables and constants
QSerialPort serial;
QSerialPortInfo serialInfo;
QList<QSerialPortInfo> listaPuertos;
bool estadoPuerto;
bool dataAvailable;

const QSerialPort::BaudRate BAUDRATE = QSerialPort::Baud9600;
const QSerialPort::DataBits DATABITS = QSerialPort::Data8;
const QSerialPort::Parity PARITY = QSerialPort::NoParity;
const QSerialPort::StopBits STOPBITS = QSerialPort::OneStop;
const QSerialPort::FlowControl FLOWCONTROL = QSerialPort::NoFlowControl;

const int pixels = 800;
QVector<double> data;
unsigned int dataIndex;
QByteArray values;
double maximo;

...

// Signal and slot connection.
QObject::connect(&serial, SIGNAL(readyRead()), this,SLOT(fillDataBuffer()));

...

// Method called when there's data available to read at the serial port.

void Ventana::fillDataBuffer()
{
    dataIndex++;
    data.append(QString::fromStdString(serial.readAll().toStdString()).toDouble());
    if(data.at(dataIndex-1) > maximo) maximo = data.at(dataIndex-1);

    /* The following qDebug is the one I use to test the recieved values,
     * where I check that values. */

    qDebug() << data.at(dataIndex-1);
}

Thanks and sorry if it's not so clear, it has been an exhausting day :P


Solution

  • Ok... I see two probelms here:

    1. Arduino side: you send your data in a decimal form (so x = 100 will be sent as 3 characters - 1, 0 and 0. You have no delimiter between your data, so how your receiver will know that it received value 100 not three values 1, 0 and 0? Please see my answer here for further explanation on how to send ADC data from Arduino.
    2. QT side: There is no guarantee on the moment when readyRead() signal will be triggered. It may be immediately after first sample arrives, but it may be raised after there are already couple of samples inside the serial port buffer. If that happens, your method fillDataBuffer() may process string 12303402 instead of four separate strings 123, 0, 340 and 2, because between two buffer reads four samples arrived. The bigger the baudrate, the more samples will arrive between the reads, which is why you observe less values with a bigger baud rate.

    Solution for both of your problems is to append some delimiting byte for your data, and split the string in the buffer on that delimiting byte. If you don't want to have maximum data throughput, you can just do

    Serial.print(buffer[x]);
    Serial.print('\n');
    

    and then, split incoming string on \n character.