Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F120722937
mainwindow.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Jul 6, 13:55
Size
7 KB
Mime Type
text/x-c
Expires
Tue, Jul 8, 13:55 (2 d)
Engine
blob
Format
Raw Data
Handle
27209173
Attached To
R2671 HHRI-software
mainwindow.cpp
View Options
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <climits>
#include <QMessageBox>
#include <QDebug>
#include <QInputDialog>
#include <QSerialPortInfo>
#include <QList>
#include "../Firmware/src/definitions.h"
const int SYNCVAR_LIST_ITEM_SIZE = SYNCVAR_NAME_SIZE + 3;
const double ENCODER_STEPS_TO_UM = 0.050;
const double GRAPH_TIME_SPAN = 10.0; // [s].
const int UPDATE_PERIOD = 50; // [ms].
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
//
ui->setupUi(this);
//
encoderVarIndex = -1;
lastEncoderValue = 0.0;
encoderOffset = 0.0;
// Setup the graph widget.
ui->grapher->addGraph();
ui->grapher->xAxis->setTickLabelType(QCPAxis::ltDateTime);
ui->grapher->xAxis->setDateTimeFormat("hh:mm:ss");
ui->grapher->xAxis->setLabel("Time [s]");
ui->grapher->yAxis->setRange(-10000.0, 10000.0);
ui->grapher->yAxis->setLabel("Position [um]");
// Connect the signals to the slots.
connect(ui->zeroButton, SIGNAL(clicked(bool)), this, SLOT(zero()));
connect(ui->clearButton, SIGNAL(clicked(bool)), this, SLOT(clearDisplay()));
// Ask for the COM port.
QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
QString comPortName;
for(int i=ports.size()-1; i >= 0; i--)
{
// Remove from the list all the serial COM ports that are not the CP210x
// USB-to-serial chip.
if(!ports[i].description().contains("CP210x"))
ports.removeAt(i);
}
if(ports.size() == 0)
{
QMessageBox::critical(this, "HRI2_PC_Controller", "No COM port.");
exit(0);
}
else if(ports.size() == 1)
comPortName = ports[0].portName();
else
{
QStringList portsDescriptions;
bool ok;
for(int i=0; i<ports.size(); i++)
portsDescriptions.append(ports[i].portName() + " - " + ports[i].description());
QString portChoice = QInputDialog::getItem(this, "HRI2_PC_Controller", "Serial port:", portsDescriptions, 0, false, &ok);
int portIndex = portsDescriptions.indexOf(portChoice);
if(portIndex == -1 || !ok)
exit(0);
comPortName = ports[portIndex].portName();
}
// Setup the serial port.
serial.setPortName(comPortName);
serial.setBaudRate(UART_BAUDRATE);
serial.setDataBits(QSerialPort::Data8);
serial.setFlowControl(QSerialPort::NoFlowControl);
serial.setParity(QSerialPort::NoParity);
connect(&serial, SIGNAL(readyRead()), this, SLOT(onReceivedData()));
qDebug() << "Opening the serial COM port...";
if(serial.open(QIODevice::ReadWrite))
qDebug() << "COM port opened successfully.";
else
{
QMessageBox::critical(this, "Error", "Can't open the COM port.");
exit(0);
}
// Setup the display update timer.
connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateDisplay()));
updateTimer.setSingleShot(false);
updateTimer.start(UPDATE_PERIOD);
// Request the variables list.
sendPacket(PC_MESSAGE_GET_VARS_LIST);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::sendPacket(quint8 messageType, QByteArray dataBytes)
{
QByteArray txBuffer;
txBuffer.append((1<<7) + messageType);
for(int i=0; i<dataBytes.size(); i++)
{
txBuffer.append(((quint8)dataBytes[i]) >> 4); // MSB.
txBuffer.append(((quint8)dataBytes[i]) & 0xf); // LSB.
}
serial.write(txBuffer);
serial.waitForBytesWritten(-1);
}
void MainWindow::onReceivedData()
{
QByteArray rxData = serial.readAll();
//qDebug() << "RX:" << byteBufferToBinaryString(rxData);
for(int i=0; i<rxData.size(); i++)
{
quint8 rxByte = rxData[i];
if(rxByte & (1<<7)) // The start byte has the most significant bit high.
{
rxCurrentMessageType = (rxByte & ~(1<<7)); // Remove the start bit.
rxBytesCount = 0;
}
else // The data bytes have the most significant byte low.
{
rxBytesCount++;
if(rxBytesCount % 2 == 1) // First half of the data byte has been received.
firstHalfByte = rxByte; // Store it until the second half arrives.
else // Second half of the data byte has been received.
{
int dataBytesReady = rxBytesCount/2;
rxDataBytesBuffer[dataBytesReady-1] = (firstHalfByte<<4) + (rxByte & 0xf);
switch(rxCurrentMessageType)
{
case STM_MESSAGE_VARS_LIST:
if(dataBytesReady >= 1)
{
quint8 nVars = rxDataBytesBuffer[0];
if(dataBytesReady == 1 + nVars * SYNCVAR_LIST_ITEM_SIZE)
{
for(int i=0; i<nVars; i++)
{
QString varName((char*)&rxDataBytesBuffer[1+i*SYNCVAR_LIST_ITEM_SIZE]);
if(varName == "raw_encoder")
{
encoderVarIndex = i;
// Setup the streaming.
QByteArray ba;
ba.append((quint8)1);
ba.append((quint8)1);
ba.append((quint8)encoderVarIndex);
sendPacket(PC_MESSAGE_SET_STREAMED_VAR, ba);
qDebug() << "Variable found.";
break;
}
}
}
}
break;
case STM_MESSAGE_STREAMING_PACKET:
if(dataBytesReady == 1 + 4 + 4)
{
if(rxDataBytesBuffer[0] == 1)
{
// Decode the encoder value.
qint32 rawEncoderValue; // [steps].
memcpy(&rawEncoderValue, &rxDataBytesBuffer[5], 4);
lastEncoderValue = ENCODER_STEPS_TO_UM * (double)rawEncoderValue;
}
}
break;
case STM_MESSAGE_DEBUG_TEXT:
if(dataBytesReady > 0 &&
rxDataBytesBuffer[dataBytesReady-1] == '\0')
{
qDebug() << QString((const char*)rxDataBytesBuffer);
rxCurrentMessageType = 0;
}
break;
default: // Ignore.
break;
}
}
}
}
}
void MainWindow::zero()
{
encoderOffset = lastEncoderValue;
}
void MainWindow::updateDisplay()
{
double offsettedEncoderValue = lastEncoderValue - encoderOffset;
// Get the time.
double time = ((double)QDateTime::currentMSecsSinceEpoch()) / 1000.0;
//time = fmod(time, 60.0);
// Update the label widget.
ui->probeLabel->setText(QString::number(offsettedEncoderValue, 'f', 3) + " um");
// Update the graph widget.
ui->grapher->graph(0)->addData(time,
offsettedEncoderValue);
ui->grapher->graph(0)->removeDataBefore(time - GRAPH_TIME_SPAN);
ui->grapher->xAxis->setRange(time - GRAPH_TIME_SPAN,
time);
double minVal = std::numeric_limits<double>::max();
double maxVal = std::numeric_limits<double>::lowest();
QCPDataMap* graphData = ui->grapher->graph(0)->data();
for(auto it = graphData->begin(); it != graphData->end(); ++it)
{
double val = (*it).value;
if(val > maxVal)
maxVal = val;
if(val < minVal)
minVal = val;
}
ui->grapher->yAxis->setRange(minVal, maxVal);
ui->grapher->replot();
}
void MainWindow::clearDisplay()
{
ui->grapher->graph(0)->clearData();
}
Event Timeline
Log In to Comment