Plot live data on QtChart



  • Hello Everyone,

    I want to plot live data which i am reading from a sensor and want to plot it on QtChart. I can read the data but dont know how to plot or pass the values to QtChart. Please help, thanks in advance


  • Lifetime Qt Champion

    Hi,

    Do you have something like the QtChart QMLOscilloscope in mind ?



  • @SGaist

    Yes i want to use only Qtchart, I havent used QML till now so dont know how it works. How can i plot it in Qtchart?
    I want somthing like this just instead of microphone as input i want my sensor as the input see the link below
    http://doc.qt.io/qt-5/qtcharts-audio-example.html


  • Moderators

    @rockon209 Then use your sensor as input.



  • @jsulm
    Ya that obvious but how i can do that i was not able to pass the values form sensor to QtChart i can read the data from sensor and i am getting it in a varaible now how to pass it to Qtchart?????
    For e.g.
    read the data and store it in a double variable
    double tempSensor= readSignal Sensor(tempChannel);


  • Moderators

    @rockon209 like in the example:

    qint64 XYSeriesIODevice::writeData(const char * data, qint64 maxSize)
    {
        qint64 range = 2000;
        QVector<QPointF> oldPoints = m_series->pointsVector();
        QVector<QPointF> points;
        int resolution = 4;
    
        if (oldPoints.count() < range) {
            points = m_series->pointsVector();
        } else {
            for (int i = maxSize/resolution; i < oldPoints.count(); i++)
                points.append(QPointF(i - maxSize/resolution, oldPoints.at(i).y()));
        }
    
        qint64 size = points.count();
        for (int k = 0; k < maxSize/resolution; k++)
            points.append(QPointF(k + size, ((quint8)data[resolution * k] - 128)/128.0));
    
        m_series->replace(points);
        return maxSize;
    }
    

    in your case instead of char* data you have a double.



  • @jsulm
    ya but i was not able to understand the code, what i am doing in my code is i am reading every on second from the sensor and i store it to the variable and then immediately i want to pass it to Qtchart and again read the sensor after one second how i can so it with the above code i new to this data acquisition


  • Moderators

    @rockon209 Change the code from the example, so it matches your requirements:

    qint64 XYSeriesIODevice::writeData(const double data, qint64 maxSize)
    {
    // Adjust here as well as needed
    }
    

    Then call writeData every time you get new value from sensor.
    To read sensor every second use QTimer.



  • @jsulm
    thanks for the reply but i have a question in the above code how the microphone data is pass to this writeData function if const char* data varaible has the info of the microphone data how is it pass to const char* data varaible??? I am not able to understand


  • Moderators

    @rockon209 In the example they implement a device:

    m_device = new XYSeriesIODevice(m_series, this);
    m_device->open(QIODevice::WriteOnly);
    
    m_audioInput->start(m_device);
    

    XYSeriesIODevice is a QIODevice which is writing incoming char* data to the chart. The data is coming from m_audioInput.
    In your case you do not need to implement a device: just use a QTimer to read your sensor each second and write the data to the chart in a similar way as in the example.



  • @jsulm
    ok thanks for the explanation
    but it is confusing because in XYSeriesIODevice class have m_series as XYseries and widget class has m_series as Qlineseries
    and tried your above suggestion i am getting the following error
    error: invalid types 'double[int]' for array subscript
    points.append(QPointF(k + size, ((quint8)tempSensor[resolution * k] - 128)/128.0));


  • Moderators

    @rockon209 said in Plot live data on QtChart:

    QPointF

    Can you show the whole method?



  • @jsulm
    with timer i call the following function every second
    void test:: readTemp()
    {
    double tempSensor= readSignal Sensor(tempChannel);
    writeData();
    }
    void test::writeData()
    {
    qint64 range = 2000;
    QVector<QPointF> oldPoints = m_series->pointsVector();
    QVector<QPointF> points;
    int resolution = 4;
    qint64 maxSize;

    if (oldPoints.count() < range) {
        points = m_series->pointsVector();
    } else {
        for (int i = maxSize/resolution; i < oldPoints.count(); i++)
            points.append(QPointF(i - maxSize/resolution, oldPoints.at(i).y()));
    }
    
    qint64 size = points.count();
    
    for (int k = 0; k < maxSize/resolution; k++)
        points.append(QPointF(k + size, ((quint8)tempSensor[resolution * k] - 128)/128.0));
    
    m_series->replace(points);
    

    //return maxSize;
    }


  • Moderators

    @rockon209 said in Plot live data on QtChart:

    double tempSensor= readSignal Sensor(tempChannel);

    this is not going to work - you store the temperature in a local variable!

    Also, this is wrong if tempSensor isn't an array:

    points.append(QPointF(k + size, ((quint8)tempSensor[resolution * k] - 128)/128.0));
    

    As I said you need to adjust the code for your needs...



  • @jsulm
    then how to make array as i am reading from the sensor every second and getting only one value.


  • Moderators

    @rockon209 You don't need any array:

    void test:: readTemp()
    {
    writeData( readSignal Sensor(tempChannel));
    }
    
    void test::writeData(const double tempSensor)
    {
    qint64 range = 2000;
    QVector<QPointF> oldPoints = m_series->pointsVector();
    QVector<QPointF> points;
    int resolution = 4;
    qint64 maxSize;
    
    if (oldPoints.count() < range) {
        points = m_series->pointsVector();
    } else {
        for (int i = maxSize/resolution; i < oldPoints.count(); i++)
            points.append(QPointF(i - maxSize/resolution, oldPoints.at(i).y()));
    }
    
    qint64 size = points.count();
    points.append(QPointF(k + size, ((quint8)tempSensor - 128)/128.0));
    m_series->replace(points);
    }


  • @jsulm
    i am getting following error and the application is shutting down
    terminate called after throwing an instance of 'std::bad_alloc'
    what(): std::bad_alloc


  • Moderators

    @rockon209 Please debug you app to see where it crashes...



  • @jsulm
    when i read the sensor data it crashes


  • Moderators

    @rockon209 Then find out why and fix it...



  • @jsulm
    do you know how maxSize value is calculated because i my code maxsize value is very very very big and in think that is the problem


  • Moderators

    @rockon209 In the code in the example it is passed as parameter:

    qint64 XYSeriesIODevice::writeData(const char * data, qint64 maxSize)
    

    In your code you don't assign anything to it so it has arbitrary value.


Log in to reply