Пример #1
0
void CSerialController::ipTimerCallback(const ros::TimerEvent& e)
{
  struct ifaddrs * ifAddrStruct=NULL;
  struct ifaddrs * ifa=NULL;
  void * tmpAddrPtr=NULL;

  getifaddrs(&ifAddrStruct);
  bool ip_found=false;

  setLCD(std::string("PC connected        "));
/*
  char hostname[40];
  unsigned int hostnameLen=40;

  gethostname(hostname,hostnameLen);
  printf("Hostname: %s\n",hostname);
*/
  if(sendHostname)
  {
    char hostname[40];
    unsigned int hostnameLen=40;
  
    gethostname(hostname,hostnameLen);
    //printf("Hostname: %s\n",hostname);
    std::string host_string("1H: ");
    host_string+=std::string(hostname);
    setLCD(host_string);
  }
  else
  {
    for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
    {
      if (ifa ->ifa_addr->sa_family==AF_INET)
      { // check it is IP4
        // is a valid IP4 Address
        tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
        char addressBuffer[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
        std::string ip_string;
        if(strncmp(ifa->ifa_name,"eth",3)==0 || strncmp(ifa->ifa_name,"wlan",4)==0 || strncmp(ifa->ifa_name,"ath",3)==0)
        {
          //printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer);
          ip_string="1IP: "+std::string(addressBuffer)+"        ";
          setLCD(ip_string);
          ip_found=true;
          break;
        }
      }
    }
    if(!ip_found)
    {
      setLCD(std::string("1IP: Not connected    "));
    }
  }
  if (ifAddrStruct!=NULL) freeifaddrs(ifAddrStruct);
  sendHostname=!sendHostname;
}
Пример #2
0
void eSystemSettings::doMenu(eWidget* lcdTitle, eWidget* lcdElement)
{
	setLCD(lcdTitle, lcdElement);
	show();
	exec();
	hide();
}
Пример #3
0
void ExtraOSDSetup::doMenu(eWidget* lcdTitle, eWidget* lcdElement)
{
	setLCD(lcdTitle, lcdElement);
	show();
	exec();
	hide();
}
Пример #4
0
void eZapScan::doMenu(eWidget* lcdTitle, eWidget* lcdElement)
{
	setLCD(lcdTitle, lcdElement);
	show();
	exec();
	hide();
}
Пример #5
0
void eParentalSetup::doMenu(eWidget* lcdTitle, eWidget* lcdElement)
{
	setLCD(lcdTitle, lcdElement);
	show();
	exec();
	hide();
}
Пример #6
0
void eSoftwareUpdate::doMenu(eWidget* lcdTitle, eWidget* lcdElement)
{
	setLCD(lcdTitle, lcdElement);
	show();
	exec();
	hide();
}
Пример #7
0
void MainWindow::downloadDataDone()
{
    // Display timers in status bar.
    timeSendingElapsed = timerSending->elapsed();
    setLCD(true);

    // Validate data and fill the "values" vector.
    controller->validateAndFillValues();

    // Draw the table view.
    controller->generateKeys(plotXAxis_maxRange);
    controller->buildCurrCharDataModel();

    // Draw the sensors plots.
    for (int sensor = 0; sensor < controller->getNumSensors(); sensor++) {
        if ( ui->plot_sensors->axisRect(sensor)->axis(QCPAxis::atBottom)->range().size() > (plotXAxis_maxRange - plotXAxis_minRange) )
            ui->plot_sensors->axisRect(sensor)->axis(QCPAxis::atBottom)->setRange(plotXAxis_minRange, plotXAxis_maxRange);
        else
            ui->plot_sensors->axisRect(sensor)->axis(QCPAxis::atBottom)->setRange(plotXAxis_minRange,
                                                                                  plotXAxis_minRange + ui->plot_sensors->axisRect(sensor)->axis(QCPAxis::atBottom)->range().size());

        for (int row = 0; row < controller->getNumRowsCurrCharDataModel(); row++)
            ui->plot_sensors->graph(sensor)->addData(controller->getCurrCharKey(row), controller->getCurrCharValue(row, sensor));

        ui->plot_sensors->graph(sensor)->rescaleValueAxis();
        ui->plot_sensors->axisRect(sensor)->axis(QCPAxis::atLeft)->setRangeUpper(0xFFFF);
        if (ui->plot_sensors->axisRect(sensor)->axis(QCPAxis::atLeft)->range().lower < 0)
            ui->plot_sensors->axisRect(sensor)->axis(QCPAxis::atLeft)->setRangeLower(0);
    }
    ui->plot_sensors->replot();

    // Draw the center of mass plot.
    if ( ui->plot_CoM->axisRect()->axis(QCPAxis::atBottom)->range().size() > (plotXAxis_maxRange - plotXAxis_minRange) )
        ui->plot_CoM->axisRect()->axis(QCPAxis::atBottom)->setRange(plotXAxis_minRange, plotXAxis_maxRange);
    else
        ui->plot_CoM->axisRect()->axis(QCPAxis::atBottom)->setRange(plotXAxis_minRange,
                                                                              plotXAxis_minRange + ui->plot_CoM->axisRect()->axis(QCPAxis::atBottom)->range().size());

    for (int row = 0; row < controller->getNumRowsCurrCharDataModel(); row++)
        ui->plot_CoM->graph()->addData(controller->getCurrCharKey(row), controller->getCurrCharCoM(row));

    ui->plot_CoM->replot();

    // Draw the controls.
    ui->plot_horizontalDrag->setRange(plotXAxis_minRange + ui->plot_sensors->axisRect()->axis(QCPAxis::atBottom)->range().size() / 2,
                                      plotXAxis_maxRange - ui->plot_sensors->axisRect()->axis(QCPAxis::atBottom)->range().size() / 2);
    ui->plot_horizontalDrag->setValue(ui->plot_sensors->axisRect()->axis(QCPAxis::atBottom)->range().lower +
                                      ui->plot_sensors->axisRect()->axis(QCPAxis::atBottom)->range().size() / 2);
    ui->plot_horizontalDrag->setEnabled(true);
}
Пример #8
0
void MainWindow::on_stopAcquisition_clicked()
{
    /* Stop acquisition */
    controller->stopAcquisition(ui->sendDataSynchronously->isChecked());

    /* Get the time elapsed */
    timerAcquisition->stop();
    timeAcquisitionElapsed = controller->getElapsedTime();
    setLCD(true);

    plotXAxis_maxRange = (double) timeAcquisitionElapsed/1000;

    // If we were receiving the data synchronously.
    if (ui->sendDataSynchronously->isChecked()) {
        int delay = 0;
        while (delay++ < 10000) {
        }
        downloadDataDone();
    }
}
Пример #9
0
void setCitroenBerlingoTU3JPConfiguration(DECLARE_ENGINE_PARAMETER_F) {
	engineConfiguration->engineType = CITROEN_TU3JP;

	/**
	 * Base engine setting
	 */
	setOperationMode(engineConfiguration, FOUR_STROKE_CRANK_SENSOR);
	engineConfiguration->trigger.type = TT_TOOTHED_WHEEL_60_2;
	engineConfiguration->globalTriggerAngleOffset = 114;
	engineConfiguration->specs.cylindersCount = 4;
	engineConfiguration->specs.displacement = 1.360;
	engineConfiguration->specs.firingOrder = FO_1_THEN_3_THEN_4_THEN2;
	engineConfiguration->ignitionMode = IM_WASTED_SPARK;
	engineConfiguration->injectionMode = IM_BATCH;
	engineConfiguration->crankingInjectionMode = IM_SIMULTANEOUS;
	engineConfiguration->rpmHardLimit = 5000;
	engineConfiguration->cranking.rpm = 600;

//	memcpy(config->ve2RpmBins, rpmSteps, sizeof(rpmSteps));

	/**
	* Cranking fuel setting
	* TODO: they recomend using something like -40C for low point and +80C for high point
	*/
	engineConfiguration->cranking.baseFuel = 15;

	/**
	 * Algorithm Alpha-N setting
	 */
	setAlgorithm(LM_ALPHA_N PASS_ENGINE_PARAMETER);
	setFuelLoadBin(0, 100 PASS_ENGINE_PARAMETER);
	setFuelRpmBin(800, 7000 PASS_ENGINE_PARAMETER);
	setTimingRpmBin(800, 7000 PASS_ENGINE_PARAMETER);

	/**
	 * Outputs
	 */

	// Frankenstein lo-side output #1: PC14 Igniter 1-4
	// Frankenstein lo-side output #2: PC15 Igniter 2-3
	// Frankenstein lo-side output #3: PE6  Injector 1-4
	// Frankenstein lo-side output #4: PC13 Injector 2-3
	// Frankenstein lo-side output #5: PE4
	// Frankenstein lo-side output #6: PE5
	// Frankenstein lo-side output #7: PE2
	// Frankenstein lo-side output #8: PE3
	// Frankenstein lo-side output #9: PE0	Fan
	// Frankenstein lo-side output #10: PE1	MIL
	// Frankenstein lo-side output #11: PB8	Main relay
	// Frankenstein lo-side output #12: PB9	Fuel pump

	boardConfiguration->ignitionPins[0] = GPIOC_14;
	boardConfiguration->ignitionPins[1] = GPIO_UNASSIGNED;
	boardConfiguration->ignitionPins[2] = GPIOC_15;
	boardConfiguration->ignitionPins[3] = GPIO_UNASSIGNED;

	engineConfiguration->injector.flow = 137; //SIEMENS DEKA VAZ20734
	boardConfiguration->injectionPins[0] = GPIOE_6;
	boardConfiguration->injectionPins[1] = GPIOC_13;
	boardConfiguration->injectionPins[2] = GPIO_UNASSIGNED;
	boardConfiguration->injectionPins[3] = GPIO_UNASSIGNED;

	boardConfiguration->fanPin = GPIOE_0;
	boardConfiguration->fanPinMode = OM_DEFAULT;

	boardConfiguration->malfunctionIndicatorPin = GPIOE_1;
	boardConfiguration->malfunctionIndicatorPinMode = OM_DEFAULT;

	boardConfiguration->mainRelayPin = GPIOB_8;

	boardConfiguration->fuelPumpPin = GPIOB_9;
	boardConfiguration->fuelPumpPinMode = OM_DEFAULT;

	setLCD(boardConfiguration);


//	boardConfiguration->o2heaterPin = GPIOC_13;
//	boardConfiguration->logicAnalyzerPins[1] = GPIO_UNASSIGNED;

	/**
	 * Inputs
	 */

	// See https://docs.google.com/spreadsheet/ccc?key=0Arl1FeMZcfisdEdGdUlHdWh6cVBoSzFIbkxqa1QtZ3c
	// Frankenstein analog input #1: PA1		adc1	MAP
	// Frankenstein analog input #2: PA3		adc3	TPS
	// Frankenstein analog input #3: PC3		adc13	IAT
	// Frankenstein analog input #4: PC1		adc11	CLT
	// Frankenstein analog input #5: PA0		adc0	vBatt
	// Frankenstein analog input #6: PC2		adc12	WBO
	// Frankenstein analog input #7: PA4		adc4
	// Frankenstein analog input #8: PA2		adc2
	// Frankenstein analog input #9: PA6		adc6
	// Frankenstein analog input #10: PA7		adc7
	// Frankenstein analog input #11: PC4		adc14
	// Frankenstein analog input #12: PC5|PA8	adc15	Speed Sensor

	/**
	 * MAP <BOSCH 0 261 230 057>
	 */
	engineConfiguration->map.sensor.hwChannel = EFI_ADC_1;
	engineConfiguration->map.sensor.type = MT_CUSTOM;
	engineConfiguration->map.sensor.valueAt0 = 10;
	engineConfiguration->map.sensor.valueAt5 = 110;
	/**
	 * TPS <MAGNETI MARELLI>
	 */
	engineConfiguration->tpsAdcChannel = EFI_ADC_3;
	engineConfiguration->tpsMin = 108; // convert 12to10 bit (ADC/4)
	engineConfiguration->tpsMax = 812; // convert 12to10 bit (ADC/4)
	/**
	 * IAT <OEM ECU>
	 */
	engineConfiguration->iat.adcChannel = EFI_ADC_13;
	setThermistorConfiguration(&engineConfiguration->iat, -20.0, 15600.0, 23.0, 2250.0, 92.0, 240.0);
	engineConfiguration->iat.config.bias_resistor = 2660;
	/**
	* CLT <LADA Samara>
	*/
	engineConfiguration->clt.adcChannel = EFI_ADC_11;
	setThermistorConfiguration(&engineConfiguration->clt, -20.0, 28680.0, 25.0, 2796.0, 100.0, 177.0);
	engineConfiguration->iat.config.bias_resistor = 2660;
	/**
	 * vBatt
	 */
	engineConfiguration->vbattAdcChannel = EFI_ADC_0;
	engineConfiguration->vbattDividerCoeff = ((float) (2.6 + 10.1)) / 2.6 * 2;
	/**
	* WBO Innovate LC-1
	*/
	engineConfiguration->afr.hwChannel = EFI_ADC_12;
	/**
	* Speed Sensor
	*/
	boardConfiguration->vehicleSpeedSensorInputPin = GPIOA_8;
	engineConfiguration->hasVehicleSpeedSensor = true;
	/**
	* Other
	*/
//	engineConfiguration->mafAdcChannel = GPIO_UNASSIGNED;

	copyFuelTable(tps_fuel_table, config->fuelTable);
	copyTimingTable(tps_advance_table, config->ignitionTable);

}
Пример #10
0
/*****************************************************************************
* Function Name: MainWindow()
******************************************************************************
* Summary:
*   Create and initialize every items used by the main window.
*
* Parameters:
*   Parent.
*
* Return:
*   Address of the new MainWindow.
*
* Note:
*   Using a Model-Controller-View approach.
*
*****************************************************************************/
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    // Create the controller
    try {
        controller = new MV_Controller(this);
    }
    catch(int e) {
        throw e;
    }

    // .ui form
    ui->setupUi(this);


    // Window title
    this->setWindowTitle("CapSense data acquisition");


    // COMBOBOX: Characteristic selection
    for (int i = 0; i < controller->getNumServices(); i++) {
        for (int j = 0; j < controller->getNumCharacteristics(i); j++) {
            if ( !controller->isCharacteristicNameEmpty(i, j) )
                ui->characteristicSelection->addItem(controller->getCharacteristicName(i, j),
                                                     qVariantFromValue((void *)controller->getCharacteristicAddress(i, j)));
        }
    }
    if (ui->characteristicSelection->count() > 0)
        controller->setCurrChar( (Characteristic *)ui->characteristicSelection->currentData().value<void *>() );


    // PUSH BUTTON: Start acquisition
    ui->startAcquisition->setEnabled(false);

    // PUSH BUTTON: Stop acquisition
    ui->stopAcquisition->setEnabled(false);

    // PUSH BUTTON: Download data
    ui->downloadData->setEnabled(false);

    // PUSH BUTTON: Clear
    if (ui->characteristicSelection->count() > 0)
        ui->clear->setEnabled(true);


    // LCD NUMBER: Elapsed time (acquisition)
    lcdTimer = new QLabel;
    timerAcquisition = new QTimer();
    timerAcquisition->setInterval(1000);
    connect(timerAcquisition, SIGNAL(timeout()), this, SLOT(setLCD()));

    timerSending = new QTime();

    lcdTimer->setText("Acquisition: 00:00.000\tSending: 00:00:000");

    ui->statusBar->addWidget(lcdTimer);


    // LABELS: Status
    ui->Ind_Ready_Acq->setVisible(false);
    ui->Ind_Acq->setVisible(false);
    ui->Ind_Ready_Send->setVisible(false);
    ui->Ind_Send->setVisible(false);


    // PROGRESS BARS: Sensors' last values
    int max = 0xFFFF;
    ui->sensor0->setRange(0, max);
    ui->sensor0->setValue(0);
    ui->value_sensor0->setText(QString::number(0));
    ui->sensor1->setRange(0, max);
    ui->sensor1->setValue(0);
    ui->value_sensor1->setText(QString::number(0));
    ui->sensor2->setRange(0, max);
    ui->sensor2->setValue(0);
    ui->value_sensor2->setText(QString::number(0));
    ui->sensor3->setRange(0, max);
    ui->sensor3->setValue(0);
    ui->value_sensor3->setText(QString::number(0));
    ui->sensor4->setRange(0, max);
    ui->sensor4->setValue(0);
    ui->value_sensor4->setText(QString::number(0));
    ui->sensor5->setRange(0, max);
    ui->sensor5->setValue(0);
    ui->value_sensor5->setText(QString::number(0));
    ui->sensor6->setRange(0, max);
    ui->sensor6->setValue(0);
    ui->value_sensor6->setText(QString::number(0));
    ui->sensor7->setRange(0, max);
    ui->sensor7->setValue(0);
    ui->value_sensor7->setText(QString::number(0));
    ui->sensor8->setRange(0, max);
    ui->sensor8->setValue(0);
    ui->value_sensor8->setText(QString::number(0));
    ui->sensor9->setRange(0, max);
    ui->sensor9->setValue(0);
    ui->value_sensor9->setText(QString::number(0));


    // CHECKBOX: Send data synchronously
    ui->sendDataSynchronously->setChecked(false);
    on_sendDataSynchronously_clicked();


    // TABLEVIEW: All sensors' values
    ui->sensorsTable->setModel( controller->getCurrCharDataModelAddress() );


    // PLOT: Chart for each sensor
    ui->plot_sensors->plotLayout()->clear();
    ui->plot_sensors->setAntialiasedElements(QCP::aeAll);

    QPen *pen = new QPen();
    pen->setColor(Qt::black);
    pen->setWidth(3);

    QVector<QCPAxisRect *> sensor;
    sensor.resize(controller->getNumSensors());
    QVector<QCPGraph *> sensorGraph;
    sensorGraph.resize(controller->getNumSensors());
    QCPMarginGroup *marginGroup = new QCPMarginGroup(ui->plot_sensors);

    // Global X Axis
    QCPAxisRect *X_Axis = new QCPAxisRect(ui->plot_sensors);
    X_Axis->axis(QCPAxis::atBottom)->setTickLabelType(QCPAxis::ltDateTime);
    X_Axis->axis(QCPAxis::atBottom)->setDateTimeFormat("mm:ss.zzz");
    X_Axis->axis(QCPAxis::atBottom)->setAutoTicks(true);
    X_Axis->axis(QCPAxis::atBottom)->setAutoTickLabels(true);
    X_Axis->axis(QCPAxis::atBottom)->setAutoTickStep(true);
    X_Axis->axis(QCPAxis::atBottom)->setAutoTickCount(4);
    X_Axis->axis(QCPAxis::atBottom)->setAutoSubTicks(true);
    X_Axis->axis(QCPAxis::atBottom)->grid()->setVisible(false);
    X_Axis->axis(QCPAxis::atLeft)->setVisible(false);

    // Sensors' plot
    for (int i = 0; i < controller->getNumSensors(); i++) {
        sensor[i] = new QCPAxisRect(ui->plot_sensors);

        // Y Axis
        sensor[i]->axis(QCPAxis::atLeft)->setRangeUpper(0xFFFF);
        sensor[i]->axis(QCPAxis::atLeft)->setAutoTicks(true);
        sensor[i]->axis(QCPAxis::atLeft)->setAutoTickStep(true);
        sensor[i]->axis(QCPAxis::atLeft)->setAutoTickCount(3);
        sensor[i]->axis(QCPAxis::atLeft)->setAutoSubTicks(true);
        sensor[i]->axis(QCPAxis::atLeft)->setTickLabels(true);
        sensor[i]->axis(QCPAxis::atLeft)->setLabel( "Sensor " + QString::number(i+1) );

        // X Axis
        sensor[i]->axis(QCPAxis::atBottom)->setTickLabelType(QCPAxis::ltDateTime);
        sensor[i]->axis(QCPAxis::atBottom)->setDateTimeFormat("mm:ss.zzz");
        sensor[i]->axis(QCPAxis::atBottom)->setAutoTicks(true);
        sensor[i]->axis(QCPAxis::atBottom)->setAutoTickStep(true);
        sensor[i]->axis(QCPAxis::atBottom)->setAutoTickCount(4);
        sensor[i]->axis(QCPAxis::atBottom)->setAutoSubTicks(true);
        sensor[i]->axis(QCPAxis::atBottom)->setTickLabels(true);

        // Full Axes Box
        sensor[i]->setupFullAxesBox();
        connect(sensor[i]->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), sensor[i]->axis(QCPAxis::atTop), SLOT(setRange(QCPRange)));
        connect(sensor[i]->axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), sensor[i]->axis(QCPAxis::atRight), SLOT(setRange(QCPRange)));

        // Horizontal drag and zoom
        sensor[i]->setRangeDrag(Qt::Horizontal);
        sensor[i]->setRangeZoom(Qt::Horizontal);
        ui->plot_sensors->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
        connect(sensor[i]->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), X_Axis->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));

        // Add plot to widget
        ui->plot_sensors->plotLayout()->addElement(i, 0, sensor[i]);
        sensor[i]->setMarginGroup(QCP::msLeft, marginGroup);

        // Graph
        sensorGraph[i] = ui->plot_sensors->addGraph(sensor[i]->axis(QCPAxis::atBottom), sensor[i]->axis(QCPAxis::atLeft));
        sensorGraph[i]->setPen(*pen);
        sensorGraph[i]->setLineStyle(QCPGraph::lsLine);
    }

    // Use the Global X Axis to control the range of all the plots (for the horizontal drag event)
    for (int i = 0; i < controller->getNumSensors(); i++)
        connect(X_Axis->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), sensor[i]->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    connect(X_Axis->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange, QCPRange)), this, SLOT(onXRangeChanged(QCPRange, QCPRange)));

    // Horizontal drag slider
    ui->plot_horizontalDrag->setRange(plotXAxis_minRange + X_Axis->axis(QCPAxis::atBottom)->range().size() / 2,
                                      plotXAxis_maxRange - X_Axis->axis(QCPAxis::atBottom)->range().size() / 2);
    ui->plot_horizontalDrag->setValue(X_Axis->axis(QCPAxis::atBottom)->range().lower + X_Axis->axis(QCPAxis::atBottom)->range().size() / 2);
    connect(ui->plot_horizontalDrag, SIGNAL(sliderMoved(int)), this, SLOT(onHorizontalDragChanged(int)));


    // PLOT: Center of mass
    ui->plot_CoM->plotLayout()->clear();
    ui->plot_CoM->setAntialiasedElements(QCP::aeAll);

    QCPAxisRect *CoM_AxisRect = new QCPAxisRect(ui->plot_CoM);
    QCPMarginGroup *marginGroupCoM = new QCPMarginGroup(ui->plot_CoM);

    // Y Axis
    CoM_AxisRect->axis(QCPAxis::atLeft)->setRangeUpper(NUM_SENSORS+0.5);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setRangeLower(0.5);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setAutoTicks(true);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setAutoTickStep(false);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setTickStep(1);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setAutoTickCount(NUM_SENSORS);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setAutoSubTicks(false);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setTickLabels(true);
    CoM_AxisRect->axis(QCPAxis::atLeft)->setLabel("Center of mass");

    // X Axis
    CoM_AxisRect->axis(QCPAxis::atBottom)->setTickLabelType(QCPAxis::ltDateTime);
    CoM_AxisRect->axis(QCPAxis::atBottom)->setDateTimeFormat("mm:ss.zzz");
    CoM_AxisRect->axis(QCPAxis::atBottom)->setAutoTicks(true);
    CoM_AxisRect->axis(QCPAxis::atBottom)->setAutoTickStep(true);
    CoM_AxisRect->axis(QCPAxis::atBottom)->setAutoTickCount(4);
    CoM_AxisRect->axis(QCPAxis::atBottom)->setAutoSubTicks(true);
    CoM_AxisRect->axis(QCPAxis::atBottom)->setTickLabels(true);
    CoM_AxisRect->axis(QCPAxis::atBottom)->setLabel("Time");

    // Full Axes Box
    CoM_AxisRect->setupFullAxesBox();
    connect(CoM_AxisRect->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), CoM_AxisRect->axis(QCPAxis::atTop), SLOT(setRange(QCPRange)));
    connect(CoM_AxisRect->axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), CoM_AxisRect->axis(QCPAxis::atRight), SLOT(setRange(QCPRange)));

    // Horizontal drag and zoom
    CoM_AxisRect->setRangeDrag(Qt::Horizontal);
    CoM_AxisRect->setRangeZoom(Qt::Horizontal);
    ui->plot_CoM->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    connect(CoM_AxisRect->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), X_Axis->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    connect(X_Axis->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), CoM_AxisRect->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));

    // Add plot to widget
    ui->plot_CoM->plotLayout()->addElement(0, 0, CoM_AxisRect);
    CoM_AxisRect->setMarginGroup(QCP::msLeft, marginGroupCoM);

    // Graph
    QCPGraph *CoM_Graph;
    CoM_Graph = ui->plot_CoM->addGraph(CoM_AxisRect->axis(QCPAxis::atBottom), CoM_AxisRect->axis(QCPAxis::atLeft));
    CoM_Graph->setPen(*pen);
    CoM_Graph->setLineStyle(QCPGraph::lsLine);

    // Horizontal drag slider
    ui->plotCoM_horizontalDrag->setRange(plotXAxis_minRange + X_Axis->axis(QCPAxis::atBottom)->range().size() / 2,
                                      plotXAxis_maxRange - X_Axis->axis(QCPAxis::atBottom)->range().size() / 2);
    ui->plotCoM_horizontalDrag->setValue(X_Axis->axis(QCPAxis::atBottom)->range().lower + X_Axis->axis(QCPAxis::atBottom)->range().size() / 2);
    connect(ui->plotCoM_horizontalDrag, SIGNAL(sliderMoved(int)), ui->plot_horizontalDrag, SLOT(setValue(int)));
    connect(ui->plotCoM_horizontalDrag, SIGNAL(sliderMoved(int)), this, SLOT(onHorizontalDragChanged(int)));


    // Subscribe to notifications
    controller->subscribeToSensorsNotifications(true, false);
    controller->subscribeToStatusNotifications(false, true);

    // First read of the status flags
    controller->readStatusFlags();
}