#ifndef MAINWINDOW_H #define MAINWINDOW_H #include < QDial > #include < QSerialPort > #include < QSerialPortInfo > #include < QMainWindow > #include "filterlpf.h" #include "stat_proc.h" #include "frequency_dom.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; // Port opening global. vars .. QSerialPort *esp32; filterLPF* LPF; stat_proc* HIST; stat_proc* HIST2; frequency_dom* FFT; QByteArray serialData; QString serialBuffer; QVectorti,s; // time, signal QVector x_vec,y_vec; // processed time signal ... QVector y_hist; // probability vector QVector xf, yf; // QVector x_b, y_b, t_b; // buffered measurement // ESP32 specific IDENTIFICATION static const int ESP32_VENDOR = 4292; static const int ESP32_PID = 60000; private slots: int on_sliderMoved(); void on_submitPresets(); // serial related:: void scan_ports(); void read_serial_data(); void stop_serial_connection(); // plotting related:: void plot_rt_input(QVector , QVector ); void plot_rt_input_processed(QVector , QVector ); void plot_rt_hist(QVector ,QVector ); void plot_rt_hist_2(QVector ,QVector ); // action control void interrupter(); // label setter void set_hist_labels(double, double, double); void on_pushButton_released(); }; #endif // MAINWINDOW_H
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); ui->hSliderBaud->setMinimum(1); ui->hSliderBaud->setMaximum(8); ui->hSliderBaud->setValue(8); //|||||||| Set Default Baud Rate to 115200 ui->lblBitRate->setText(QString("%1").arg(115200)); ui->edtBufferSize->setText("1800"); ui->edtVectorSize->setText("250"); ui->listWidget->addItem("Application ready... "); // set dB slider ui->dialSGain->setMinimum(-30); ui->dialSGain->setMaximum(30); ui->dialSGain->setValue(0); //||| Initialize serial port... //||| PLOT SETUPS // setup the plot_1 ui->plot_1->addGraph(0); ui->plot_1->graph(0)->setPen(QPen(Qt::darkBlue, 0.8)); ui->plot_2->addGraph(0); ui->plot_2->graph(0)->setPen(QPen(Qt::darkRed, 0.7)); // MEASUREMENT SECTION //BUFFERING int BSize = ui->edtBufferSize->text().toInt(); // take the value from edit window ui->pBarBuffering->setMinimum(0); ui->pBarBuffering->setMaximum(BSize); ui->radLPF->setAutoExclusive(false); ui->radPP->setAutoExclusive(false); ui->radHist->setAutoExclusive(false); //|||||CONNECTIONS connect(ui->hSliderBaud, SIGNAL(valueChanged(int)), SLOT(on_sliderMoved())); connect(ui->cmdSubmit, SIGNAL(clicked()), SLOT(on_submitPresets())); connect(ui->cmdStopSerial, SIGNAL(clicked()), SLOT(stop_serial_connection())); }// end of constructor MainWindow::~MainWindow() { delete ui; delete esp32; delete LPF; delete FFT; }
//[1] baud rate .. int MainWindow::on_sliderMoved() { ui->listWidget->takeItem(ui->listWidget->currentRow()); // baud rate presets: // {9600, 14400, 19200, 38400, 57600, 115200}; /* QSerialPort::Baud1200 1200 1200 baud. QSerialPort::Baud2400 2400 2400 baud. QSerialPort::Baud4800 4800 4800 baud. QSerialPort::Baud9600 9600 9600 baud. QSerialPort::Baud19200 19200 19200 baud. QSerialPort::Baud38400 38400 38400 baud. QSerialPort::Baud57600 57600 57600 baud. QSerialPort::Baud115200 115200 115200 baud. */ int baud[] = {1200, 2400, 4800, 9600, 19200, 38400, 57600,115200}; // reading baud rate from slider .. int w = ui->hSliderBaud->value(); ui->lblBitRate->setText(QString("%1").arg(baud[w-1])); int baudRate = baud[w-1]; // output to application window ... QString output = "Baud rate has been set to: " + QString::number(baudRate) + " bits/s"; ui->listWidget->addItem(output); return baud[w-1]; } //[2] ... when serial setup is pressed .. void MainWindow::on_submitPresets() { QString bufferSize = ui->edtBufferSize->text(); QString VectorSize = ui->edtVectorSize->text(); ui->listWidget->takeItem(ui->listWidget->currentRow()); QString output = "Number of symbols in a buffer: " + bufferSize+ " (signs)\n"; output +="Size of vector: " + VectorSize; ui->listWidget->clear(); ui->listWidget->addItem(output); on_sliderMoved(); scan_ports(); } //[3] ... san the ports
void MainWindow::scan_ports() { qInfo()<<"ports scanning.. "; /* * TESTING CODE FOR OPEN PORTS */ qDebug() << "Descirption available ports:" << QSerialPortInfo::availablePorts().length() <<"\n"; foreach(const QSerialPortInfo& serialPortInfo, QSerialPortInfo::availablePorts() ) { qDebug() << "||||||||||||||||||||||||||||||||||||||||Serial ports information: \n"; qDebug() << "No.of available ports:" << QSerialPortInfo::availablePorts().length(); qDebug() << "Has vendor ID :" << serialPortInfo.hasVendorIdentifier(); qDebug() << "Vendor ID :" << serialPortInfo.vendorIdentifier(); qDebug() << "Has Product ID :" << serialPortInfo.hasProductIdentifier(); qDebug() << "Product ID :" << serialPortInfo.productIdentifier(); } QString port_info = "No. Available ports: " +QString::number( QSerialPortInfo::availablePorts().length()); foreach(const QSerialPortInfo& serialPortInfo, QSerialPortInfo::availablePorts() ) { port_info += "\nHas vendor ID \t: " + QString::number( serialPortInfo.hasVendorIdentifier()) ; port_info += "\nVendor \t: " + QString::number( serialPortInfo.vendorIdentifier()); port_info += "\nHas Product ID\t: " + QString::number( serialPortInfo.hasProductIdentifier()); port_info += "\nProduct ID\t: " + QString::number( serialPortInfo.productIdentifier()); } ui->listWidget->addItem(port_info); //|||| DETECT THE ESP32 MODEL bool esp32_available =false; QString espPortName; // for each available of serial ports foreach(const QSerialPortInfo& serialPortInfo, QSerialPortInfo::availablePorts()) { if(serialPortInfo.hasProductIdentifier() && serialPortInfo.hasVendorIdentifier()) { // if hardvare has vendor and product id if(serialPortInfo.productIdentifier() == ESP32_PID && serialPortInfo.vendorIdentifier() == ESP32_VENDOR) { // confirm there is ESP 32 at the port esp32_available = true; qDebug() << "\t\t ESP 32 ... microcontroller found"; espPortName = serialPortInfo.portName(); qDebug() << "\t\t At the active port:" << espPortName; ui->listWidget->addItem("ESP32 Found at port: " + espPortName); } } } //||| IF ESP32 HAS BEEN DETECTED if(esp32_available) { // now open and configure ESP32 port ... qDebug()<< "Found ESP port .. \n "; int BRATE = on_sliderMoved(); qInfo()<<"Baud Rate : " << BRATE; esp32 = new QSerialPort(); esp32->setPortName(espPortName); esp32->open(QSerialPort::ReadOnly); switch (BRATE) { case 1200: esp32->setBaudRate(QSerialPort::Baud1200); break; case 2400: esp32->setBaudRate(QSerialPort::Baud2400); break; case 4800: esp32->setBaudRate(QSerialPort::Baud4800); break; case 9600: esp32->setBaudRate(QSerialPort::Baud9600); break; case 19200: esp32->setBaudRate(QSerialPort::Baud19200); break; case 38400: esp32->setBaudRate(QSerialPort::Baud38400); break; case 57600: esp32->setBaudRate(QSerialPort::Baud57600); break; case 115200: esp32->setBaudRate(QSerialPort::Baud115200); break; default: esp32->setBaudRate(QSerialPort::Baud115200); break; } esp32->setDataBits(QSerialPort::Data8); esp32->setFlowControl(QSerialPort::NoFlowControl); esp32->setParity(QSerialPort::NoParity); esp32->setStopBits(QSerialPort::OneStop); //|||NOW START READING DATA QObject::connect(esp32, SIGNAL(readyRead()), this, SLOT(read_serial_data())); //| this is where you call readSerial() LPF = new filterLPF(); //LPF->pingMe(); // histogram processing HIST = new stat_proc(); HIST2 = new stat_proc(); ui->plot_3->addGraph(); ui->plot_3->addGraph(); ui->plot_4->addGraph(); // this par was never utilized ... FFT = new frequency_dom(); } else { qDebug() << "Could not find the correct port for esp \n "; QMessageBox::information(this, "Serial Port Error", "Couldn't open seral port of a device ... "); } } //:: end of fn
//[4] Real- time processing //||||||||||||| //||||||||||||| //||||||||||||| //||||||||||||| //||||||||||||| void MainWindow::read_serial_data() { // PRESETS //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // SET LABEL TO Input processing plot if(ui->radPP->isChecked()){ ui->lblInputProc->setText("ON");} else if( !ui->radLPF->isChecked()){ui->lblInputProc->setText("OFF");} // RED THE GAIN //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| double gain = ui->dialSGain->value(); //| gain in dB ui->lblGain->setText(QString::number(gain)); //| set the user input to the screen clock_t c1, c2; // start the clock //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //|||| Buffer size is set in UI and here is to be read again ... QString b_size = ui->edtBufferSize->text(); int BUFFER_SIZE = b_size.toDouble(); //||| int CLR_L= ui->lblValuesBuffer->text().toInt(); // when to pop front the value from the vectro QString clr_l = ui->edtVectorSize->text(); int clear_size = clr_l.toInt(); serialData = esp32->readAll(); serialBuffer += QString::fromStdString(serialData.toStdString()); //| accumulating to buffer static int i = 0; //| static counter of buffers static int j = 0; //| static counter of index values in a buffer c1 = clock(); // sart clock //|||| BUFFERING TO BUFFER SIZE if(serialBuffer.size()>BUFFER_SIZE) { i++; // count the buffers in total QStringList li = serialBuffer.split("*"); // splitting sign // read how many symbols are in the buffer and plot to UI ui->lblBuffer->setText(QString::number(serialBuffer.length())); ui->lblValuesBuffer->setText(QString::number(li.length())); ui->lblCountBuffers->setText(QString::number(i)); // Push the values from the list to vectors for(int k = 0; k < li.length(); k++) { double value = li[k].toDouble(); //========================================================================================= //| POST PROCESSING CHAIN //|........................................................................................ //| //| o----->| GAIN | o----> | Sampling FREQ| o----> | LPF | o---> | STAT | //| //========================================================================================= if(ui->radPP->isChecked()) { //|| "X -Axis" //|| IF TIME DOMAIN ON/OFF ... if(ui->radTimSignal->isChecked()) { ui->lblDom->setText("time"); double dt = 1/ ui->edtFS->text().toDouble(); x_vec.push_back((double)j*dt); }else if(ui->radTimSignal->isCheckable()) { ui->lblDom->setText("samples"); x_vec.push_back((double)j); } //|| "Y - Axis" //|| FOR SIGNAL Filtering ... //|| checek weather checke: if filter is on ... and if cutoff frequency is provided double gain_db = ui->dialSGain->value(); ui->lcdRead->display(QString::number(gain_db)); double GAIN = pow(10,gain_db/10.0); // FILTER LPF if(ui->radLPF->isChecked() && ui->edtFC->text().isEmpty() == false && ui->edtFS->text().isEmpty()==false) { double fc, fs, f_value; // pick up the value from the UI fc = ui->edtFC->text().toDouble(); // entered by the user ... fs = ui->edtFS->text().toDouble(); // filtering of a signal LPF->setCoeffs(fc, fs); f_value = LPF->filter(value, fc, fs); y_vec.push_back( LPF->gain(f_value,GAIN)); //|| - STATISTICAL MEASUREMENT PROCESSING ... //|| //|| FOR STAT PROCESSING:: UI - Inputs taken //|| //||========================================================================================= double min, max, N; // show the inputs .......................................... N = ui->edtStatN->text().toDouble(); min = ui->edtStatMIN->text().toDouble(); max = ui->edtStatMAX->text().toDouble(); // show the inputs to parameter labels ui->lbl_stat_classes->setText(QString::number(N)); ui->lbl_stat_min->setText(QString::number(min)); ui->lbl_stat_max->setText(QString::number(max)); // calculate class and step 'd' double span = max - min; double d = span/N; // show class and step to parameter labels ui->lblHSpan ->setText(QString::number(span)); ui->lblCWidth->setText(QString::number(d)); //||========================================================================================= //|| do statistics on filtered values ... double val = LPF->gain(f_value,GAIN); ui->lblBuffFull->setText(QString::number(HIST->x.size())); if(ui->radHist->isChecked()) { set_hist_labels(N, min, max); double buff_max = ui->edtSamples->text().toDouble(); // buffer maximum ui->pBarBuffering->setMaximum(buff_max); //HIST->hist(val, ui->edtStatN->text().toDouble(), min, max); HIST2->hist(val, ui->edtStatN->text().toDouble(), min, max); ui->pBarBuffering->setValue(HIST2->x.size()); if(buff_max == HIST2->x.length()) { interrupter(); } else if(HIST2->x.length() > buff_max) // if number exceeds the given size .. clean hist vector "NAsty error !" { HIST2->x.clear(); HIST2->h.clear(); } }else if(ui->radHist->isCheckable()) // when measurement turned off , clean histogram vectors { HIST2->x.clear(); HIST2->h.clear(); } } else { //|| Only processing is on ...ie. GAIN/ NO FILTERING //|| //||========================================================================================= y_vec.push_back( value*GAIN); //|| take the user values from UI double N = ui->edtStatN->text().toDouble(); // take number of bins double min = ui->edtStatMIN->text().toDouble(); // take minimum double max = ui->edtStatMAX->text().toDouble(); // take maximum double buff_max = ui->edtSamples->text().toDouble(); // buffer maximum set_hist_labels(N, min, max); // set them around the plot_3 if(ui->radHist->isChecked()) { HIST->hist(value*GAIN, N, min, max); ui->lblBuffFull->setText(QString::number(HIST->x.size())); ui->pBarBuffering->setMaximum(buff_max); ui->pBarBuffering->setValue(HIST->x.size()); // when buffer is filled if(buff_max == HIST->x.length()) { // interrupt all, to plot and clear vectors // reconnect.. then proceed interrupter(); } else if(HIST->x.length() > buff_max) { HIST->x.clear(); HIST->h.clear(); } } else if(ui->radHist->isCheckable()) { HIST->x.clear(); HIST->h.clear(); } } // CLEAN VECTORS WHEN FULL if(x_vec.length()>clear_size && y_vec.length()>clear_size) { x_vec.pop_front(); y_vec.pop_front(); } } else if(ui->radPP->isCheckable()) { // if pre-processing has been turned off ... ui->lblDom->setText("samples"); } //========================================================================================= // NON PROCESSED VALUES //========================================================================================= s.push_back(value); j++; // push the signal value to the vector 's' ti.push_back((double)j); // write an index to the time vector if(s.length()>clear_size && ti.length()>clear_size) { s.pop_front(); ti.pop_front(); } }// end of vector manipulations ... //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //||| BUFFER CLEANING serialBuffer.clear(); li.clear(); //||| CLOCK measurment end/ time for a buffer ... c2 = clock(); double t_buffer = (double)(c2-c1)/CLOCKS_PER_SEC; ui->lblBtime->setText(QString::number(t_buffer)); //||| Plotting the results to plot_1 plot_rt_input(ti, s); // if radio button is checked .. plot either same inputs // either processed rt inputs ... if( ui->radPP->isChecked()){ plot_rt_input_processed(x_vec,y_vec); }else if(!ui->radPP->isChecked()) { plot_rt_input_processed(ti,s); } } }
//||| CLOSE SERIAL CONNECTION void MainWindow::stop_serial_connection() { esp32->close(); // close the port if(HIST != nullptr) { delete HIST; qInfo()<< "Histogram deleted..."; } if(HIST2 != nullptr) { delete HIST2; qInfo()<< "Histogram 2 deleted..."; } if(LPF!= nullptr) { qInfo()<< "LPF deleted"; delete LPF; } if(esp32 != nullptr) { qInfo()<< "port deleted"; delete esp32; } if(FFT != nullptr) { qInfo()<<"frequency domain object deleted ... "; delete FFT; } ti.clear(); s.clear(); ui->listWidget->clear(); ui->listWidget->addItem("Serial connection stopped... "); }
// INTERRUPTER OF MEASUREMENT ... void MainWindow::interrupter() { esp32->close(); if(!HIST->x.isEmpty()) // ako je histogram 1 pun, isplotaj, pobrisi ga { //qInfo()<<"Highest histogram value is befor plotting :" << HIST->histMaxVal(); plot_rt_hist(HIST->x, HIST->h); HIST->x.clear(); HIST->h.clear(); } if(! HIST2->x.isEmpty()) { // HIST 2 has been used //plot_rt_hist_2(HIST->x, HIST->h); plot_rt_hist_2(HIST2->x, HIST2->h); HIST->x.clear(); HIST->h.clear(); } scan_ports(); }
// PLOTTING FUNCTIONS void MainWindow::plot_rt_input(QVectorti, QVector s) { ui->plot_1->graph(0)->setData(ti, s); ui->plot_1->xAxis2->setVisible(true); ui->plot_1->xAxis2->setTickLabels(false); ui->plot_1->yAxis2->setVisible(true); ui->plot_1->yAxis2->setTickLabels(false); ui->plot_1->yAxis->setLabel("Input: x"); ui->plot_1->xAxis->setLabel("[sample] "); ui->plot_1->rescaleAxes(); double max_val = *std::max_element(s.constBegin(), s.constEnd()); ui->plot_1->yAxis->setRange(-3*max_val, 3*max_val); ui->plot_1->replot(); ui->plot_1->update(); } void MainWindow::plot_rt_hist(QVector x, QVector h ) { ui->plot_3->graph(0)->setData(x, h); ui->plot_3->graph(0)->setLineStyle((QCPGraph::LineStyle)2); ui->plot_3->xAxis2->setVisible(true); ui->plot_3->xAxis2->setTickLabels(false); ui->plot_3->yAxis2->setVisible(true); ui->plot_3->yAxis2->setTickLabels(false); ui->plot_3->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); ui->plot_3->legend->setVisible(false); ui->plot_3->yAxis->setLabel("Histogram"); ui->plot_3->xAxis->setLabel(" "); ui->plot_3->rescaleAxes(); ui->plot_3->yAxis->setRange(-0.1*HIST->histMaxVal(), HIST->histMaxVal()*1.2); ui->plot_3->replot(); ui->plot_3->update(); } void MainWindow:: plot_rt_hist_2(QVector x,QVector h) { ui->plot_4->graph(0)->setPen(QPen(Qt::red)); ui->plot_4->graph(0)->setData(x, h); ui->plot_4->graph(0)->setLineStyle((QCPGraph::LineStyle)2); ui->plot_4->xAxis2->setVisible(true); ui->plot_4->xAxis2->setTickLabels(false); ui->plot_4->yAxis2->setVisible(true); ui->plot_4->yAxis2->setTickLabels(false); ui->plot_4->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); ui->plot_4->legend->setVisible(false); ui->plot_4->yAxis->setLabel("Histogram"); ui->plot_4->xAxis->setLabel(" "); ui->plot_4->rescaleAxes(); ui->plot_4->yAxis->setRange(-0.1*HIST2->histMaxVal(), HIST2->histMaxVal()*1.2); ui->plot_4->replot(); ui->plot_4->update(); } void MainWindow::plot_rt_input_processed(QVector x, QVector y) { ui->plot_2->graph(0)->setData(x, y); ui->plot_2->xAxis2->setVisible(true); ui->plot_2->xAxis2->setTickLabels(false); ui->plot_2->yAxis2->setVisible(true); ui->plot_2->yAxis2->setTickLabels(false); ui->plot_2->yAxis->setLabel("Output: y"); ui->plot_2->xAxis->setLabel(ui->lblDom->text()+"[s]"); double max_val = *std::max_element(s.constBegin(), s.constEnd()); ui->plot_2->rescaleAxes(); ui->plot_2->yAxis->setRange(-3*max_val, 3*max_val); ui->plot_2->replot(); ui->plot_2->update(); } void MainWindow::set_hist_labels(double N, double min, double max) { double span = max - min; ui->lblHSpan->setText(QString::number(span)); ui->lbl_stat_classes->setText(QString::number(N)); ui->lbl_stat_min->setText(QString::number(min)); ui->lbl_stat_max->setText(QString::number(max)); ui->lblCWidth->setText(QString::number(span/N)); } void MainWindow::on_pushButton_released() { MainWindow::close(); }
#ifndef FILTERLPF_H #define FILTERLPF_H #include < Object > #include < QDebug > // filter coefficients for BIQUAD type struct Coeff { double a1,a2; double b0,b1,b2; }; // difference equation of a filter ... struct DEQ { //set up the coefficients double b0,b1,b2; double a1,a2; // set up the x[n-1], x[n-2] ... double x1,x2; double y0,y1,y2; double process(const Coeff& fltCoeff, double x0) { // read in the coefficients b0 = fltCoeff.b0; b1 = fltCoeff.b1; b2 = fltCoeff.b2; a1 = fltCoeff.a1; a2 = fltCoeff.a2; y0 = b0*x0 + b1*x1 + b2*x2 - a1*y1 -a2*y2; x2 = x1; x1 = x0; y2 = y1; y1 = y0; return y0; } }; // filterLPF called from the heap ... class filterLPF : public QObject { Q_OBJECT private: #define PI 3.14159265358979323846; double a1,a2; double b0,b1,b2; public: explicit filterLPF(QObject *parent = nullptr); // constructor Coeff coeff; // has one structure of coefficients DEQ diffEq; // has one difference equation biquad system Coeff LPF_butter(double, double); // returns full filter structure void setCoeffs(double, double); // sets coefficients void getCoeffs(); // types the coefficients to console // run the difference equation double gain(double x0, double gain); // gain the signal after filtering double filter(double x0, double, double); // utilize the whole filter }; /* inside of MAIN thread ... use this as follows * Application note... * * #include "filterlpf.h" * * * // create somwhere ... filterLPF* LPF = new FilteLPF(); LPF->setCoeffs(10, 1e3); LPF->getCoeffs(); // if to be noticed some loop ...should take place for utilizing difference equation ... while() { double x = sin(12*PI*f*dt); double y1 = LPF-> filter(x, 10, 1e3); fitler the signal double y2 = LPF->gain(f_value,GAIN); amplify the stuff .. } delete LPF; */ #endif // FILTERLPF_H
#include "filterLPF.h" #include < cmath > filterLPF::filterLPF(QObject *parent) : QObject(parent) { qInfo()<< "Filter Object has been created"; } //||||| Calculate coefficients for the butterworth filter Coeff filterLPF::LPF_butter(double fc, double fs) { Coeff LPF; const double ita =1.0/ tan(M_PI*fc/fs); const double q=sqrt(2.0); LPF.b0 = 1.0 / (1.0 + q*ita + ita*ita); LPF.b1 = 2*LPF.b0; LPF.b2 = LPF.b0; LPF.a1 = -2.0 * (ita*ita - 1.0) * LPF.b0; LPF.a2 = (1.0 - q*ita + ita*ita) * LPF.b0; return LPF; } //||||| Set cofficients void filterLPF::setCoeffs(double fc, double fs) { Coeff K = LPF_butter( fc, fs); a1 = K.a1; a2 = K.a2; b0 = K.b0; b1 = K.b1; b2 = K.b2; } // GET Coefficients void filterLPF::getCoeffs() { qInfo()<< "a1" << this->a1; qInfo()<< "a2" << this->a2; qInfo()<< "b0" << this->b1; qInfo()<< "b1" << this->b1; qInfo()<< "b2" << this->b2; } // LPF utilization double filterLPF::filter(double x0, double fc, double fs) { return diffEq.process(LPF_butter(fc,fs), x0); } // GAINs the signal ... double filterLPF::gain(double x0, double factor) { double y0 = x0*factor; return y0; }
#ifndef STAT_PROC_H #define STAT_PROC_H #include < QObject > // now push the value throught the whole class ... // and count the correspondent number within each /* * histogram builder .. . i=0, 0-1 : * | bin_l = 0 | bin_h = 1 | d = 1 | 1-2 : **** | bin_l = 1 | bin_h = 2 | d = 1 | 2-3 : ********* 3-4 : *************** 4-5 : ****************** i*d, 5-6 : ******************* 6-7 : *************** 7-8 : ******** 8-9 : **** i=N, 9-10: * * */ class stat_proc : public QObject { Q_OBJECT public: QVector<double > // histogram values ... QVector<double > x; // bin centers .. double min, max, d, N; explicit stat_proc(QObject *parent = nullptr); void sayHello(); // ping and prove class exists .. void hist(double, int, double, double); // return histogram values to the double histMaxVal(); // return maximum value of histogram void typeHist(); // put the results into console... }; #endif // STAT_PROC_H
#include "stat_proc.h" #include < QDebug > #include < iostream > stat_proc::stat_proc(QObject *parent) : QObject(parent) { x.clear(); h.clear(); } void stat_proc::sayHello() { qInfo() << "Stat processor has been initialized.... "; } // histogram of values given to the ... void stat_proc::hist(double val, int N, double min, double max) { double span = max - min; double d = span/N; this->min = min; this->max = max; this->d = d; this->N = N; // fill the global vector h with zeros .. for(int i = 0; i < N; i++) { h.push_back(0.00); } double bin_l, bin_h, cbin; for(int i = 0; i < N; i++) { bin_l = min + i*d; // bin lower edge bin_h = bin_l +d; // bin higher edge cbin = (bin_h +bin_l) /2.0; // cbin .. center of bins ... x.push_back(cbin); if(val >= bin_l && val< bin_h) { h[i] += 1; } } } // type histogram from ... void stat_proc::typeHist() { double bin_h,bin_l, cbin; static int q = 0; q++; if(q==1) { qInfo() << "-------------------------------------------------"; qInfo() << "N :" << this->N ; qInfo() << "min :" << this->min; qInfo() << "max :" << this->max; qInfo() << "step:" << this->d; qInfo() << "-------------------------------------------------"; } for(int i = 0; isayHello(); HIST->hist(2.8, 20, -5, 5); HIST->hist(2.6, 20, -5, 5); HIST->hist(2.67, 20, -5, 5); HIST->hist(4.77, 20, -5, 5); HIST->typeHist(); * * * Stat processor has been initialized.... After streaming :: ------------------------------------------------- N : 20 min : -5 max : 5 step: 0.5 ------------------------------------------------- ------------------------------------------------- 1 | -5 : -4.5 || -4.75 3 || 2 | -4.5 : -4 || -4.25 3 || 3 | -4 : -3.5 || -3.75 3 || 4 | -3.5 : -3 || -3.25 2 || 5 | -3 : -2.5 || -2.75 3 || 6 | -2.5 : -2 || -2.25 4 || 7 | -2 : -1.5 || -1.75 18 || 8 | -1.5 : -1 || -1.25 202 || 9 | -1 : -0.5 || -0.75 711 || 10 | -0.5 : 0 || -0.25 1552 || 11 | 0 : 0.5 || 0.25 1880 || 12 | 0.5 : 1 || 0.75 1333 || 13 | 1 : 1.5 || 1.25 417 || 14 | 1.5 : 2 || 1.75 74 || 15 | 2 : 2.5 || 2.25 10 || 16 | 2.5 : 3 || 2.75 7 || 17 | 3 : 3.5 || 3.25 8 || 18 | 3.5 : 4 || 3.75 3 || 19 | 4 : 4.5 || 4.25 9 || 20 | 4.5 : 5 || 4.75 5 || */
(Reason: single thread cannot handle it anymore, it chockes the process .. )
#ifndef FREQUENCY_DOM_H #define FREQUENCY_DOM_H #include < QObject > #include < complex > #include < iostream > #include < valarray > #include < vector > #include < cmath > using namespace std; class frequency_dom : public QObject { Q_OBJECT public: explicit frequency_dom(QObject *parent = nullptr); const double PI_ = 3.141592653589793238460; QVector < double > f; QVector < double > y; void dft(); }; #endif // FREQUENCY_DOM_H
#include "frequency_dom.h" #include < QDebug > frequency_dom::frequency_dom(QObject *parent) : QObject(parent) { } void frequency_dom::dft() { // defintely need FFT here ... something fast // non of three procedure here has been working fast enough .. what to do ... threads ? // see here: FFT Candidates // ( that did not pass the test ... and I did not use timers ! :< ) }