Visualizzazione post con etichetta QtCustomPlot. Mostra tutti i post
Visualizzazione post con etichetta QtCustomPlot. Mostra tutti i post

domenica 19 aprile 2020

QTCustomPlot da dati CSV

Un progettino semplice per graficare dati derivanti da un file CSV (si tratta di un progetto satellite di un progetto Android con cui, tramite applicazione, vengono salvati i dati di accelerazione)



Come libreria per plottare i dati ho usato QTCustomPlot per la semplicita' di zoom/pan mentre per la lettura di CSV e' stata impiegata QtCSV

Il codice e' disponibile su GitHub. E' possibile zoom/pan ed avere le coordinate del puntatore

Per impostare QTCustomPlot su QtCreator si devono imporate i file qtcustomplot.cpp/ qtcustomplot.h, si aggiunge al file .pro  QT += printsupport, si trascina sul form un QWidget, tasto destro Promote To e si fa il promote a QtCustomPlot (il metodo e' cambiato rispetto al precedente post https://debiaonoldcomputers.blogspot.com/2013/11/software-per-progetto-force-gauge.html)

======================================================
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qcustomplot.h"

#include "variantdata.h"
#include "reader.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QString filePath = "/home/luca/ss/7.csv";

    QList<QStringList> readData = QtCSV::Reader::readToList(filePath,";");

    QVector<double> x(readData.size()), y(readData.size());

    //l.resize(readData.size());

  for ( int i = 0; i < readData.size(); ++i )
  {
      x[i] = readData.at(i).value(1).toDouble()-1587149254484;
      y[i] = readData.at(i).value(2).toDouble();

  }
   //Abilita Drag e Zoom
    ui->customPlot->setInteraction(QCP::iRangeDrag,true);
    ui->customPlot->setInteraction(QCP::iRangeZoom,true);


    ui->customPlot->addGraph();
    ui->customPlot->graph(0)->setData(x,y);
    ui->customPlot->graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20)));
    ui->customPlot->graph(0)->setPen(QPen(Qt::blue));
    connect(ui->customPlot,SIGNAL(mousePress(QMouseEvent *)),SLOT (clickedGraph(QMouseEvent*)));
    connect(ui->customPlot,SIGNAL(mouseMove(QMouseEvent *)),SLOT (MouseGraph(QMouseEvent*)));

    ui->customPlot->addGraph();

    ui->customPlot->xAxis->setLabel("Time");
    ui->customPlot->yAxis->setLabel("Acc");

    //double x_min = *std::min_element(x.constBegin(), x.constEnd());
    //double x_max = *std::max_element(x.constBegin(), x.constEnd());
    //double y_min = *std::min_element(y.constBegin(), y.constEnd());
    //double y_max = *std::max_element(y.constBegin(), y.constEnd());
    //ui->customPlot->xAxis->setRange(x_min, x_max);
    //ui->customPlot->yAxis->setRange(y_min, y_max);

    ui->customPlot->rescaleAxes();
    ui->customPlot->replot();
    //qDebug() << ui->customPlot->xAxis->pixelToCoord(mouseEvent->pos().x()) << ui->customPlot->yAxis->pixelToCoord(mouseEvent->pos().y());
}

void MainWindow::clickedGraph(QMouseEvent *event)
{
    QPoint point = event->pos();
    qDebug() << ui->customPlot->xAxis->pixelToCoord(point.x());
    qDebug() << ui->customPlot->yAxis->pixelToCoord(point.y());

}

void MainWindow::MouseGraph(QMouseEvent *event)
{
    QPoint point = event->pos();
    qDebug() << ui->customPlot->xAxis->pixelToCoord(point.x());
    qDebug() << ui->customPlot->yAxis->pixelToCoord(point.y());

    QVariant xi = ui->customPlot->xAxis->pixelToCoord(point.x());
    QVariant yi = ui->customPlot->yAxis->pixelToCoord(point.y());

    ui->xmouse->setText(xi.toString());
    ui->ymouse->setText(yi.toString());


}


MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_horizontalSlider_valueChanged(int value)
{
}

mercoledì 20 novembre 2013

Software per progetto Force Gauge

Il progetto Force Guage sta arrivando al suo termine
L'hardware finale e' stato montato nella sua versione finale
-Arduino Due
-Ethernet Shield
-Amplifier Shield (autoprodotto)

adesso si passa al codice


per Arduino e' stato riutilizzato quasi tutto il codice di questo post
C'e' da annotare che (evindenziato in giallo)
1) per usare il comando itoa in Arduino Due si deve aggiungere  #include "itoa.h"
2) per far funzionare il convertitore analogico digitale di Arduino due a 12 bit lo si deve richiedere esplicitamente con il comando analogReadResolution

Codice Arduino
------------------------------------------
#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include "itoa.h"

byte ardmac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ardip(192, 168, 0, 2);

byte Server[]  = { 192,168,0,1 };  
unsigned int porta = 7755;    
unsigned int localPort = 8888;      // local port to listen on

int sensorPin = A3;    
int sensorValue = 0;  

EthernetUDP Udp;

char buf[12]; // "-2147483648\0"

void setup() {
  Ethernet.begin(ardmac,ardip);
  Udp.begin(localPort);
  analogReadResolution(12);
}

void loop() {
    sensorValue = analogRead(sensorPin);    
    Udp.beginPacket(Server, porta);
    Udp.write(itoa(sensorValue, buf, 10));
    Udp.endPacket();
    delay(100);
}
----------------------------------------

per il frontend di rappresentazione realtime dei dati e' stato scritto un programmino in Qt che implementa un server UDP e mostra i dati mediante la libreria QCustomplot

Codice Qt (4.8.5)
file .pro (le modifiche sono in giallo)
------------------------------------------
QT      += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = geolab
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp \
    qcustomplot.cpp

HEADERS  += mainwindow.h \
    qcustomplot.h

FORMS    += mainwindow.ui
------------------------------------------

in azzurro le righe di codice relative al server UDP mentre in giallo quelle relative alla visualizzazione del grafico

mainwindow.h
------------------------------------------
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtNetwork>
#include <QVector>
#include "qcustomplot.h"


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private slots:
    void on_pushButton_clicked();
    void ricevi();

private:
    Ui::MainWindow *ui;
    QUdpSocket *udpSocket;

 };

#endif // MAINWINDOW_H
------------------------------------------
mainwindow.cpp
-------------------------------------------
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>
#include <QUdpSocket>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

{
    ui->setupUi(this);

    ui->widget->addGraph();
    ui->widget->xAxis->setLabel("x");
    ui->widget->yAxis->setLabel("y");
    ui->widget->xAxis->setRange(0, 10);
    ui->widget->yAxis->setRange(0, 10);
    ui->widget->replot();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    udpSocket = new QUdpSocket(this);
    QString ip = "192.168.0.1";
    udpSocket->bind(QHostAddress("192.168.0.1"), 7755);
    connect(udpSocket, SIGNAL(readyRead()),
               this, SLOT(ricevi()));

}


void MainWindow::ricevi(){
    while (udpSocket->hasPendingDatagrams()) {
           QByteArray datagram;
           datagram.resize(udpSocket->pendingDatagramSize());
           QHostAddress sender;
           quint16 senderPort;

           udpSocket->readDatagram(datagram.data(), datagram.size(),
                                   &sender, &senderPort);

           qDebug() <<datagram;
           ui->widget->graph(0)->addData(i,datagram.toDouble());
           ui->widget->graph(0)->rescaleValueAxis(true);
           ui->widget->graph(0)->rescaleKeyAxis(true);

           ui->widget->replot();
           QString valore = datagram;
           ui->label->setText("Lettura istantanea : "+valore);

       }
}
-------------------------------------------


Geologi

  E so anche espatriare senza praticamente toccare strada asfaltata