1
votes

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

2
How does the code read the data from the analog-to-digital converter? Maybe it is not able to read it as fast as you think....wallyk
I read all the values from de ADC, save them in a vector and then transmit vector trough serial port. Shouldn't be a problem about reading the adc because it's independent.Emanuel Gómez Arn

2 Answers

0
votes

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.

0
votes

Thank you very much! I did what you said about my arduino program and after solving that, I was still not getting the entire amount of data. So the the problem was in Qt. How you perfectly explain, the serial buffer was accumulating the values too fast, so the slot function "fillDataBuffer()" was too slow to process the arriving data. I simplified that function:

void Ventana::fillDataBuffer()
{
    dataIndex++;
    buffer.append(serial.readAll());
}

After saving all the values in the QByteArray buffer, I process the data separately.

Thanks again man. Your answer was really helpful.