Implemented the remaining file loading formats (busmaster log, CRTD), switched the way signals are connected on the main window, hooked up frame count, auto scroll, and clear frame button
This commit is contained in:
+149
-12
@@ -7,11 +7,33 @@
|
||||
#include "canframemodel.h"
|
||||
#include "utility.h"
|
||||
|
||||
/*
|
||||
This first order of business is to attempt to gain feature parity (roughly) with GVRET-PC so that this
|
||||
can replace it as a cross platform solution.
|
||||
|
||||
Here are things yet to do
|
||||
- Support saving frames
|
||||
- Add flow view - ability to see bits change over time
|
||||
- Implement the rest of the file loading formats
|
||||
- Add frame counter to main screen and a way to auto scroll
|
||||
- Ability to send frames via playback mechanism (people use this so get it working!)
|
||||
- Ability to use programmatic frame sending interface (only I use it and it's complicated but helpful)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
connect(ui->btnConnect, SIGNAL(clicked(bool)), this, SLOT(connButtonPress()));
|
||||
connect(ui->actionOpen_Log_File, SIGNAL(triggered(bool)), this, SLOT(handleLoadFile()));
|
||||
connect(ui->actionGraph_Dta, SIGNAL(triggered(bool)), this, SLOT(showGraphingWindow()));
|
||||
connect(ui->actionFrame_Data_Analysis, SIGNAL(triggered(bool)), this, SLOT(showFrameDataAnalysis()));
|
||||
connect(ui->btnClearFrames, SIGNAL(clicked(bool)), this, SLOT(clearFrames()));
|
||||
|
||||
model = new CANFrameModel();
|
||||
ui->canFramesView->setModel(model);
|
||||
|
||||
@@ -50,13 +72,85 @@ MainWindow::~MainWindow()
|
||||
void MainWindow::addFrameToDisplay(CANFrame &frame, bool autoRefresh = false)
|
||||
{
|
||||
model->addFrame(frame, autoRefresh);
|
||||
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
|
||||
if (autoRefresh)
|
||||
{
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::clearFrames()
|
||||
{
|
||||
model->clearFrames();
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
}
|
||||
|
||||
//CRTD format from Mark Webb-Johnson / OVMS project
|
||||
/*
|
||||
Sample data in CRTD format
|
||||
1320745424.000 CXX OVMS Tesla Roadster cando2crtd converted log
|
||||
1320745424.000 CXX OVMS Tesla roadster log: charge.20111108.csv
|
||||
1320745424.002 R11 402 FA 01 C3 A0 96 00 07 01
|
||||
1320745424.015 R11 400 02 9E 01 80 AB 80 55 00
|
||||
1320745424.066 R11 400 01 01 00 00 00 00 4C 1D
|
||||
1320745424.105 R11 100 A4 53 46 5A 52 45 38 42
|
||||
1320745424.106 R11 100 A5 31 35 42 33 30 30 30
|
||||
1320745424.106 R11 100 A6 35 36 39
|
||||
1320745424.106 CEV Open charge port door
|
||||
1320745424.106 R11 100 9B 97 A6 31 03 15 05 06
|
||||
1320745424.107 R11 100 07 64
|
||||
|
||||
tokens:
|
||||
0 = timestamp
|
||||
1 = line type
|
||||
2 = ID
|
||||
3-x = The data bytes
|
||||
*/
|
||||
|
||||
void MainWindow::loadCRTDFile(QString filename)
|
||||
{
|
||||
QFile *inFile = new QFile(filename);
|
||||
CANFrame thisFrame;
|
||||
QByteArray line;
|
||||
|
||||
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
|
||||
line = inFile->readLine(); //read out the header first and discard it.
|
||||
|
||||
while (!inFile->atEnd()) {
|
||||
line = inFile->readLine();
|
||||
if (line.length() > 2)
|
||||
{
|
||||
QList<QByteArray> tokens = line.split(' ');
|
||||
thisFrame.timestamp = (int64_t)(tokens[0].toDouble() * 1000);
|
||||
if (tokens[1] == "R11" || tokens[1] == "R29")
|
||||
{
|
||||
thisFrame.ID = tokens[2].toInt(NULL, 16);
|
||||
if (tokens[1] == "R29") thisFrame.extended = true;
|
||||
else thisFrame.extended = false;
|
||||
thisFrame.bus = 0;
|
||||
thisFrame.len = tokens.length() - 3;
|
||||
for (int d = 0; d < thisFrame.len; d++)
|
||||
{
|
||||
if (tokens[d + 3] != "")
|
||||
{
|
||||
thisFrame.data[d] = tokens[d + 3].toInt(NULL, 16);
|
||||
}
|
||||
else thisFrame.data[d] = 0;
|
||||
}
|
||||
addFrameToDisplay(thisFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
inFile->close();
|
||||
model->sendRefresh();
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
|
||||
|
||||
}
|
||||
|
||||
//The "native" file format for this program
|
||||
void MainWindow::loadNativeCSVFile(QString filename)
|
||||
{
|
||||
QFile *inFile = new QFile(filename);
|
||||
@@ -97,7 +191,8 @@ void MainWindow::loadNativeCSVFile(QString filename)
|
||||
}
|
||||
inFile->close();
|
||||
model->sendRefresh();
|
||||
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
|
||||
}
|
||||
|
||||
void MainWindow::loadGenericCSVFile(QString filename)
|
||||
@@ -133,14 +228,63 @@ void MainWindow::loadGenericCSVFile(QString filename)
|
||||
}
|
||||
inFile->close();
|
||||
model->sendRefresh();
|
||||
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
|
||||
}
|
||||
|
||||
//busmaster log file
|
||||
/*
|
||||
tokens:
|
||||
0 = timestamp
|
||||
1 = Transmission direction
|
||||
2 = Channel
|
||||
3 = ID
|
||||
4 = Type (s = standard, I believe x = extended)
|
||||
5 = Data byte length
|
||||
6-x = The data bytes
|
||||
*/
|
||||
void MainWindow::loadLogFile(QString filename)
|
||||
{
|
||||
QFile *inFile = new QFile(filename);
|
||||
CANFrame thisFrame;
|
||||
QByteArray line;
|
||||
|
||||
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
|
||||
line = inFile->readLine(); //read out the header first and discard it.
|
||||
|
||||
while (!inFile->atEnd()) {
|
||||
line = inFile->readLine();
|
||||
if (line.startsWith("***")) continue;
|
||||
if (line.length() > 1)
|
||||
{
|
||||
QList<QByteArray> tokens = line.split(' ');
|
||||
thisFrame.timestamp = Utility::GetTimeMS();
|
||||
thisFrame.ID = tokens[3].right(tokens[3].length() - 2).toInt(NULL, 16);
|
||||
if (tokens[4] == "s") thisFrame.extended = false;
|
||||
else thisFrame.extended = true;
|
||||
thisFrame.bus = tokens[2].toInt() - 1;
|
||||
thisFrame.len = tokens[5].toInt();
|
||||
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
|
||||
}
|
||||
addFrameToDisplay(thisFrame);
|
||||
}
|
||||
inFile->close();
|
||||
model->sendRefresh();
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
|
||||
}
|
||||
|
||||
//log file from microchip tool
|
||||
/*
|
||||
tokens:
|
||||
0 = timestamp
|
||||
1 = Transmission direction
|
||||
2 = ID
|
||||
3 = Data byte length
|
||||
4-x = The data bytes
|
||||
*/
|
||||
void MainWindow::loadMicrochipFile(QString filename)
|
||||
{
|
||||
QFile *inFile = new QFile(filename);
|
||||
@@ -163,15 +307,6 @@ void MainWindow::loadMicrochipFile(QString filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
tokens:
|
||||
0 = timestamp
|
||||
1 = Transmission direction
|
||||
2 = ID
|
||||
3 = Data byte length
|
||||
4-x = The data bytes
|
||||
*/
|
||||
if (!inComment)
|
||||
{
|
||||
QList<QByteArray> tokens = line.split(';');
|
||||
@@ -191,7 +326,8 @@ void MainWindow::loadMicrochipFile(QString filename)
|
||||
}
|
||||
inFile->close();
|
||||
model->sendRefresh();
|
||||
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
|
||||
|
||||
}
|
||||
|
||||
@@ -348,6 +484,7 @@ void MainWindow::procRXChar(unsigned char c)
|
||||
rx_state = IDLE;
|
||||
rx_step = 0;
|
||||
addFrameToDisplay(buildFrame, true);
|
||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ private slots:
|
||||
void readSerialData();
|
||||
void showGraphingWindow();
|
||||
void showFrameDataAnalysis();
|
||||
void clearFrames();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
+59
-69
@@ -11,7 +11,7 @@
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@@ -23,7 +23,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
<string>SavvyCAN</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<widget class="QTableView" name="canFramesView">
|
||||
@@ -32,7 +32,7 @@
|
||||
<x>20</x>
|
||||
<y>10</y>
|
||||
<width>675</width>
|
||||
<height>400</height>
|
||||
<height>421</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -85,6 +85,61 @@
|
||||
<string>Connect To Dongle</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>720</x>
|
||||
<y>160</y>
|
||||
<width>71</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string># of frames:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnClearFrames">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>710</x>
|
||||
<y>180</y>
|
||||
<width>201</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear Frames</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbNumFrames">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>810</x>
|
||||
<y>160</y>
|
||||
<width>55</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="cbAutoScroll">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>710</x>
|
||||
<y>250</y>
|
||||
<width>201</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto scroll window</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
@@ -186,72 +241,7 @@
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>actionOpen_Log_File</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>handleLoadFile()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>507</x>
|
||||
<y>299</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>btnConnect</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>connButtonPress()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>820</x>
|
||||
<y>103</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>463</x>
|
||||
<y>249</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionGraph_Dta</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>showGraphingWindow()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>463</x>
|
||||
<y>249</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionFrame_Data_Analysis</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>showFrameDataAnalysis()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>463</x>
|
||||
<y>249</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<connections/>
|
||||
<slots>
|
||||
<slot>handleLoadFile()</slot>
|
||||
<slot>connButtonPress()</slot>
|
||||
|
||||
Reference in New Issue
Block a user