3281 lines
123 KiB
C++
3281 lines
123 KiB
C++
#include "unioncom.h"
|
||
#include "ui_unioncom.h"
|
||
#include "ProjectSettings.h"
|
||
#include <QSerialPort>
|
||
#include "QDialogButtonBox"
|
||
|
||
QWidget* init(QWidget *parent)
|
||
{
|
||
return new UnionCOM(parent);
|
||
}
|
||
|
||
//////////////
|
||
//Оглавление//
|
||
//////////////
|
||
/*
|
||
Прототипы статичных функций - строка №51
|
||
|
||
Callback функции - строка №83
|
||
|
||
Инициализация программы - строка №223
|
||
|
||
Очистка логгера от сообщений - строка №349
|
||
|
||
Включение и отключение Modbus - строка №369
|
||
|
||
Настройки подключения в зависимости от типа - строка №408
|
||
|
||
Подключение устройства или com-порта - строка №478
|
||
|
||
Отключение устройства или com-порта - строка №687
|
||
|
||
Приём данных - строка №794
|
||
|
||
Загрузка файла - строка №1487
|
||
|
||
Базовые функции отправки данных - строка №1647
|
||
|
||
Отправка команды из строки - строка №1765
|
||
|
||
Отправка пакета байтов, задаваемых на форме в HEX - строка №1970
|
||
|
||
Отправка файла - строка №2187
|
||
|
||
Работа с макросами - строка №2428
|
||
*/
|
||
|
||
UnionCOM *com_target;
|
||
CanUsb *wCan = nullptr;
|
||
USettingsRS *wRS = nullptr;
|
||
union_modbus *ModbusMaster = nullptr;
|
||
union_modbus_slave *ModbusSlave = nullptr;
|
||
|
||
unsigned div_up(unsigned x, unsigned y) {return (x - 1) / y + 1;}
|
||
|
||
///////////////////////////////
|
||
//Прототипы статичных функций//
|
||
///////////////////////////////
|
||
|
||
static void turnOnSendFile();
|
||
static void turnOnCMDTX();
|
||
static void turnOnCMDHEXTX();
|
||
static void turnOnMcrsTX(int index);
|
||
|
||
|
||
static void stepToStartMCRS1();
|
||
static void stepToStartMCRS2();
|
||
static void stepToStartMCRS3();
|
||
static void stepToStartMCRS4();
|
||
static void stepToStartMCRS5();
|
||
static void stepToStartMCRS6();
|
||
static void stepToStartMCRS7();
|
||
static void stepToStartMCRS8();
|
||
static void stepToStartMCRS9();
|
||
static void stepToStartMCRS10();
|
||
static void stepToStartMCRS11();
|
||
static void stepToStartMCRS12();
|
||
static void stepToStartMCRS13();
|
||
static void stepToStartMCRS14();
|
||
static void stepToStartMCRS15();
|
||
void (*funcptr[])(){stepToStartMCRS1, stepToStartMCRS2, stepToStartMCRS3,
|
||
stepToStartMCRS4, stepToStartMCRS5, stepToStartMCRS6,
|
||
stepToStartMCRS7, stepToStartMCRS8, stepToStartMCRS9,
|
||
stepToStartMCRS10, stepToStartMCRS11, stepToStartMCRS12,
|
||
stepToStartMCRS13, stepToStartMCRS14, stepToStartMCRS15};
|
||
static void canReaderThread(UnionCOM* obj);
|
||
|
||
////////////////////
|
||
//Callback функции//
|
||
////////////////////
|
||
|
||
//Callback функция из библиотеки SlCan, обрабатывающая изменения состояния устройства slcan.
|
||
static void __stdcall Device_Callback(HSLCAN cbDevice, DWORD dwIndex, DWORD dwOperation, PVOID pContext, DWORD dwContextSize)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Изменение состояния устройства slcan.");
|
||
qDebug() << msg;
|
||
//dwIndex - номер устройства в списке устройств.
|
||
if(dwIndex!=0)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] dwIndex = %1.").arg(dwIndex);
|
||
qDebug() << msg;
|
||
}
|
||
//pContext - указатель на контекст устройства.
|
||
if(pContext!=nullptr)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] pContext = %1.").arg((long long int)pContext);
|
||
qDebug() << msg;
|
||
}
|
||
//dwContextSize - размер контекста устройства в байтах.
|
||
if(dwContextSize!=0)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] dwContextSize = %1.").arg(dwContextSize);
|
||
qDebug() << msg;
|
||
}
|
||
static bool DevOp_Close;
|
||
//Пополнение в списке доступных для работы устройств.
|
||
if(dwOperation == SLCAN_DEVOP_CREATE)
|
||
{
|
||
wCan->Refresh();
|
||
if(wCan->GetCount()==0)
|
||
{
|
||
com_target->gotors();
|
||
}
|
||
}
|
||
//Открытие устройства для работы.
|
||
else if(dwOperation == SLCAN_DEVOP_OPEN)
|
||
{
|
||
com_target->Connect_Notification();
|
||
}
|
||
//Закрытие устройства для работы в нормальных условиях.
|
||
else if(dwOperation == SLCAN_DEVOP_CLOSE)
|
||
{
|
||
com_target->Disconnect_Notification();
|
||
//Флаг необходим, т.к. после отключения Callback функция сработает повторно с операцией SLCAN_DEVOP_DESTROYHANDLE.
|
||
DevOp_Close=1;
|
||
}
|
||
//Закрытие (в том числе - аварийное) устройства.
|
||
else if(dwOperation == SLCAN_DEVOP_DESTROYHANDLE)
|
||
{
|
||
if(com_target->device == cbDevice)
|
||
{
|
||
//Очистка буффера отправляемых фреймов
|
||
SlCan_DevicePurge(com_target->device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR);
|
||
SlCan_DeviceClose(com_target->device);
|
||
com_target->AfterDisconnection();
|
||
if(DevOp_Close==0)
|
||
{
|
||
//Уведомление о аварийном отключении устройства.
|
||
com_target->Emergency_Disconnect_Notification();
|
||
}
|
||
DevOp_Close=0;
|
||
}
|
||
//Обновление списка устройств.
|
||
wCan->Refresh();
|
||
if(wCan->GetCount()==0)
|
||
{
|
||
com_target->gotors();
|
||
}
|
||
}
|
||
//Выбывание устройства из списка доступных устройств.
|
||
else if(dwOperation == SLCAN_DEVOP_DESTROY)
|
||
{
|
||
wCan->Refresh();
|
||
if(wCan->GetCount()==0)
|
||
{
|
||
com_target->gotors();
|
||
}
|
||
}
|
||
}
|
||
|
||
///Callback функция изменения состояния списка устройств slcan.
|
||
static void __stdcall DeviceList_Callback(HSLCAN cbDevice, DWORD dwIndex, PVOID pContext, DWORD dwContextSize)
|
||
{
|
||
//cbDevice - ссылнка на устройство
|
||
//Если параметр равен 0xFFFFFFFF, то это означает, что список устройств изменился.
|
||
if((unsigned long long int)cbDevice==0xffffffff)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Изменение состояние списка устройств slcan.");
|
||
qDebug() << msg;
|
||
}
|
||
//Если параметр не равен 0xFFFFFFFF, то это означает,
|
||
//что вновь подключенное устройство уже добавлено
|
||
//в спиок и с ним можно работать, например,
|
||
//открыть и передавать и принимать фреймы.
|
||
else
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] cbDevice = %1.").arg((unsigned long long int)cbDevice);
|
||
qDebug() << msg;
|
||
}
|
||
//dwIndex - номер устройства в списке устройств.
|
||
//Может принимать значение 0xFFFFFFFF.
|
||
if(dwIndex!=0)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] dwIndex = %1.").arg(dwIndex);
|
||
qDebug() << msg;
|
||
}
|
||
//pContext - указатель на контекст устройства.
|
||
if(pContext!=nullptr)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] pContext = %1.").arg((long long int)pContext);
|
||
qDebug() << msg;
|
||
}
|
||
//dwContextSize - размер контекста устройства в байтах.
|
||
if(dwContextSize!=0)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] dwContextSize = %1.").arg(dwContextSize);
|
||
qDebug() << msg;
|
||
}
|
||
//Обновление списка доступных устройств.
|
||
wCan->Refresh();
|
||
if(wCan->GetCount()==0)
|
||
{
|
||
com_target->gotors();
|
||
}
|
||
}
|
||
|
||
static const int THREAD_COUNT = QThread::idealThreadCount();
|
||
|
||
///////////////////////////
|
||
//Инициализация программы//
|
||
///////////////////////////
|
||
|
||
UnionCOM::UnionCOM(QWidget *parent) :
|
||
QWidget(parent),
|
||
ui(new Ui::UnionCOM)
|
||
{
|
||
ui->setupUi(this);
|
||
com_target=this;
|
||
Init();
|
||
}
|
||
|
||
UnionCOM::~UnionCOM()
|
||
{
|
||
if(ui->buttonDisconnect->isEnabled())
|
||
{
|
||
on_buttonDisconnect_clicked();
|
||
}
|
||
delete ui;
|
||
}
|
||
|
||
void UnionCOM::Init()
|
||
{
|
||
m_serial = new QSerialPort(this);
|
||
SettingWidget();
|
||
AfterDisconnection();
|
||
ui->widgetsModbus->hide();
|
||
//HEX поля для ввода байтов.
|
||
{
|
||
HEXByteField[0] = ui->HEXByte_0;
|
||
HEXByteField[1] = ui->HEXByte_1;
|
||
HEXByteField[2] = ui->HEXByte_2;
|
||
HEXByteField[3] = ui->HEXByte_3;
|
||
HEXByteField[4] = ui->HEXByte_4;
|
||
HEXByteField[5] = ui->HEXByte_5;
|
||
HEXByteField[6] = ui->HEXByte_6;
|
||
HEXByteField[7] = ui->HEXByte_7;
|
||
}
|
||
//Кнопки макросов.
|
||
{
|
||
McrsButtons[0] = ui->buttonMacros_01;
|
||
McrsButtons[1] = ui->buttonMacros_02;
|
||
McrsButtons[2] = ui->buttonMacros_03;
|
||
McrsButtons[3] = ui->buttonMacros_04;
|
||
McrsButtons[4] = ui->buttonMacros_05;
|
||
McrsButtons[5] = ui->buttonMacros_06;
|
||
McrsButtons[6] = ui->buttonMacros_07;
|
||
McrsButtons[7] = ui->buttonMacros_08;
|
||
McrsButtons[8] = ui->buttonMacros_09;
|
||
McrsButtons[9] = ui->buttonMacros_10;
|
||
McrsButtons[10] = ui->buttonMacros_11;
|
||
McrsButtons[11] = ui->buttonMacros_12;
|
||
McrsButtons[12] = ui->buttonMacros_13;
|
||
McrsButtons[13] = ui->buttonMacros_14;
|
||
McrsButtons[14] = ui->buttonMacros_15;
|
||
}
|
||
//Кнопки остановки переодической отправки макросов.
|
||
{
|
||
McrsStopButtons[0] = ui->buttonStopMacros_01;
|
||
McrsStopButtons[1] = ui->buttonStopMacros_02;
|
||
McrsStopButtons[2] = ui->buttonStopMacros_03;
|
||
McrsStopButtons[3] = ui->buttonStopMacros_04;
|
||
McrsStopButtons[4] = ui->buttonStopMacros_05;
|
||
McrsStopButtons[5] = ui->buttonStopMacros_06;
|
||
McrsStopButtons[6] = ui->buttonStopMacros_07;
|
||
McrsStopButtons[7] = ui->buttonStopMacros_08;
|
||
McrsStopButtons[8] = ui->buttonStopMacros_09;
|
||
McrsStopButtons[9] = ui->buttonStopMacros_10;
|
||
McrsStopButtons[10] = ui->buttonStopMacros_11;
|
||
McrsStopButtons[11] = ui->buttonStopMacros_12;
|
||
McrsStopButtons[12] = ui->buttonStopMacros_13;
|
||
McrsStopButtons[13] = ui->buttonStopMacros_14;
|
||
McrsStopButtons[14] = ui->buttonStopMacros_15;
|
||
}
|
||
//Стартовые значения макросов.
|
||
{
|
||
for(int i = 0; i < 15; i++)
|
||
{
|
||
//Имя макроса по умолчанию - название кнопки. "М" + номер макроса.
|
||
MacrosMain[i].Name = McrsButtons[i]->text();
|
||
//Поле макроса
|
||
MacrosMain[i].Mcrs.clear();
|
||
//Макрос задаётся в HEX или символами. По умолчанию - символы.
|
||
MacrosMain[i].IsHEX = Qt::Unchecked;
|
||
MacrosMain[i].DLC = 8;
|
||
//Отправляется ли макрос раз в N период. По умолчанию - нет.
|
||
MacrosMain[i].IsPeriod = Qt::Unchecked;
|
||
//Количество отправок за одну передачу. По умолчанию - 1.
|
||
MacrosMain[i].Count = 1;
|
||
//Период в мс. По умолчанию - 1.
|
||
MacrosMain[i].Period = 1;
|
||
}
|
||
}
|
||
//Выключаются кнопки макросов при запуске приложения.
|
||
{
|
||
for(int i = 0; i < 15; i++)
|
||
{
|
||
McrsStopButtons[i]->setEnabled(FALSE);
|
||
notTimeToStopPeriodMcrs[i]=FALSE;
|
||
}
|
||
}
|
||
//Создаются таймеры для периодических макросов.
|
||
{
|
||
for(int index = 0; index < 15; index++)
|
||
{
|
||
McrsPeriodTransfer[index] = new QTimer(this);
|
||
McrsPeriodTransfer[index]->setSingleShot(TRUE);
|
||
connect(McrsPeriodTransfer[index], &QTimer::timeout, this, funcptr[index]);
|
||
}
|
||
}
|
||
ui->groupRXErrors->hide();
|
||
ui->groupTXErrors->hide();
|
||
tableInit();
|
||
|
||
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Инициализация завершена.");
|
||
qDebug()<<msg;
|
||
|
||
}
|
||
|
||
void UnionCOM::gotors()
|
||
{
|
||
ui->cboxTypeConnection->setCurrentIndex(1);
|
||
}
|
||
|
||
////////////////////////////////
|
||
//Очистка логгера от сообщений//
|
||
////////////////////////////////
|
||
void UnionCOM::appendToLogger(QString msgToLogger)
|
||
{
|
||
ui->logger->append(msgToLogger);
|
||
}
|
||
|
||
void UnionCOM::on_buttonClearLogger_clicked()
|
||
{
|
||
ui->logger->clear();
|
||
RxCanModel->removeRows(0, RxCanModel->rowCount());
|
||
RxCanRequesterModel->removeRows(0, RxCanRequesterModel->rowCount());
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Очистка логгера.";
|
||
counterOfLoggerMSG=0;
|
||
qDebug() << msg;
|
||
}
|
||
|
||
/////////////////////////////////
|
||
//Включение и отключение Modbus//
|
||
/////////////////////////////////
|
||
|
||
void UnionCOM::on_checkModbusEnabled_stateChanged(int arg1)
|
||
{
|
||
if(ui->checkModbusEnabled->checkState()==Qt::Checked)
|
||
{
|
||
ui->verticalSpacerModbus->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||
ui->widgetsModbus->show();
|
||
ModbusMaster = new union_modbus(nullptr);
|
||
ModbusSlave = new union_modbus_slave(nullptr);
|
||
ui->widgetsModbus->addTab(ModbusMaster, "Master");
|
||
ui->widgetsModbus->addTab(ModbusSlave, "Slave");
|
||
}
|
||
else
|
||
{
|
||
if(ModbusMaster!=nullptr)
|
||
{
|
||
ModbusMaster->close();
|
||
ModbusMaster->~union_modbus();
|
||
ModbusMaster = nullptr;
|
||
}
|
||
if(ModbusSlave!=nullptr)
|
||
{
|
||
ModbusSlave->close();
|
||
ModbusSlave->~union_modbus_slave();
|
||
ModbusSlave = nullptr;
|
||
}
|
||
ui->verticalSpacerModbus->changeSize(0, 50, QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||
ui->widgetsModbus->hide();
|
||
}
|
||
}
|
||
|
||
/////////////////////////
|
||
//Настройки подключения//
|
||
//в зависимости от типа//
|
||
/////////////////////////
|
||
|
||
//QT-слот, срабатывающий при изменении типа подключения.
|
||
void UnionCOM::on_cboxTypeConnection_currentIndexChanged(int index)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Изменение типа подключения. Текущий тип: ");
|
||
switch (index) {
|
||
case 0:
|
||
msg += "CAN.";
|
||
break;
|
||
case 1:
|
||
msg += "RS.";
|
||
break;
|
||
}
|
||
qDebug() << msg;
|
||
SettingWidget();
|
||
}
|
||
|
||
void UnionCOM::SettingWidget()
|
||
{
|
||
switch (ui->cboxTypeConnection->currentIndex()) {
|
||
case 0:
|
||
//CAN
|
||
//Если перед этим было открыто окно настроек для RS - оно закрывается.
|
||
{
|
||
if (wRS)
|
||
{
|
||
wRS->close();
|
||
delete wRS;
|
||
wRS=nullptr;
|
||
}
|
||
//Загрузка библиотеки и настраивание callback функций.
|
||
SlCan_Load(Device_Callback, DeviceList_Callback);
|
||
//Создание окна настроек CAN.
|
||
wCan = new CanUsb(ui->widget);
|
||
if(wCan->GetCount()==0)
|
||
{
|
||
ui->cboxTypeConnection->setCurrentIndex(1);
|
||
}
|
||
else
|
||
{
|
||
//Отображение окна
|
||
wCan->show();
|
||
}
|
||
break;
|
||
}
|
||
case 1:
|
||
//RS
|
||
//Если перед этим было открыто окно настроек для CAN - оно закрывается. Освобождается библиотека.
|
||
{
|
||
if (wCan)
|
||
{
|
||
SlCan_Free(FALSE);
|
||
wCan->close();
|
||
delete wCan;
|
||
wCan=nullptr;
|
||
}
|
||
}
|
||
//Создание окна настроек RS.
|
||
wRS = new USettingsRS(ui->widget);
|
||
//Отображение окна.
|
||
wRS->show();
|
||
break;
|
||
}
|
||
}
|
||
|
||
//////////////////////////
|
||
//Подключение устройства//
|
||
// или com-порта //
|
||
//////////////////////////
|
||
|
||
QString UnionCOM::errors_RS(int ConnectionError)
|
||
{
|
||
QString error_msg = QString::number(ConnectionError, 10);
|
||
error_msg += ": ";
|
||
switch (ConnectionError) {
|
||
case 0:
|
||
error_msg += "No error occurred.";
|
||
break;
|
||
case 1:
|
||
error_msg += "An error occurred while attempting to open an non-existing device.";
|
||
break;
|
||
case 2:
|
||
error_msg += "An error occurred while attempting to open an already opened device by another process or a user not having enough permission and credentials to open.";
|
||
break;
|
||
case 3:
|
||
error_msg += "An error occurred while attempting to open an already opened device in this object.";
|
||
break;
|
||
case 4:
|
||
error_msg += "Parity error detected by the hardware while reading data. This value is obsolete. We strongly advise against using it in new code.";
|
||
break;
|
||
case 5:
|
||
error_msg += "Framing error detected by the hardware while reading data. This value is obsolete. We strongly advise against using it in new code.";
|
||
break;
|
||
case 6:
|
||
error_msg += "Break condition detected by the hardware on the input line. This value is obsolete. We strongly advise against using it in new code.";
|
||
break;
|
||
case 7:
|
||
error_msg += "An I/O error occurred while writing the data.";
|
||
break;
|
||
case 8:
|
||
error_msg += "An I/O error occurred while reading the data.";
|
||
break;
|
||
case 9:
|
||
error_msg += "An I/O error occurred when a resource becomes unavailable, e.g. when the device is unexpectedly removed from the system.";
|
||
break;
|
||
case 10:
|
||
error_msg += "The requested device operation is not supported or prohibited by the running operating system.";
|
||
break;
|
||
case 11:
|
||
error_msg += "An unidentified error occurred.";
|
||
break;
|
||
case 12:
|
||
error_msg += "A timeout error occurred.";
|
||
break;
|
||
case 13:
|
||
error_msg += "This error occurs when an operation is executed that can only be successfully performed if the device is open.";
|
||
break;
|
||
}
|
||
return error_msg;
|
||
}
|
||
|
||
//QT-слот, обрабатывающий подключение устройства/порта в зависимости от выбранного типа подключения.
|
||
void UnionCOM::on_buttonConnect_clicked()
|
||
{
|
||
switch (ui->cboxTypeConnection->currentIndex()) {
|
||
case 0:
|
||
//CAN
|
||
openCAN();
|
||
break;
|
||
case 1:
|
||
//RS
|
||
openSerialPort();
|
||
break;
|
||
}
|
||
}
|
||
|
||
//Функция открытия устройства CAN.
|
||
void UnionCOM::openCAN()
|
||
{
|
||
//Если было подключено устройство - отключаем.
|
||
SlCan_DeviceClose(device);
|
||
//Получаем ссылку на новое устройство.
|
||
device = wCan->GetDevice();
|
||
//Получаем настройки устройства и сообщений.
|
||
int indx = wCan->GetBR();
|
||
//Получаем режим устройства.
|
||
SLCAN_MODE = wCan->GetMode();
|
||
br.BRP = 0x8000 + indx;
|
||
ID = wCan->GetID();
|
||
//Попытка открыть устройство.
|
||
if(SlCan_DeviceOpen(device))
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Настройка устройства CAN.";
|
||
qDebug() << msg;
|
||
//Настройка устройства.
|
||
//Устройство переходит в режим настройки.
|
||
SlCan_DeviceSetMode(device, SLCAN_MODE_CONFIG);
|
||
//Настройка битрейта.
|
||
SlCan_DeviceSetBitRate(device, &br);
|
||
//Настройка уровня генерации событий.
|
||
SlCan_DeviceSetEventLevel(device, SLCAN_EVT_LEVEL_ERRORS);
|
||
//
|
||
SlCan_DeviceSetStartTimeStamp(device, 0);
|
||
SlCan_DeviceSetTimeStampPeriod(device, 1);
|
||
//Устройство возвращается к работе.
|
||
SlCan_DeviceSetMode(device, SLCAN_MODE);
|
||
//Настройка сообщения.
|
||
outMsg.ID = ID;
|
||
outMsg.Info = SLCAN_MES_INFO_EXT;
|
||
outMsg.DataCount = 8;
|
||
//Перевод режима работы приложения с этапа настройки на этап работы с выбранным устройством.
|
||
AfterConnection();
|
||
timeFromRXErrorClear = new QTimer();
|
||
timeFromTXErrorClear = new QTimer();
|
||
connect(timeFromRXErrorClear, SIGNAL(timeout()), this, SLOT(rxErrorTimer_anotherSec()));
|
||
connect(timeFromTXErrorClear, SIGNAL(timeout()), this, SLOT(txErrorTimer_anotherSec()));
|
||
ui->spinRXErrorCount->setValue(0);
|
||
ui->spinTXErrorCount->setValue(0);
|
||
timeFromRXErrorClear->start(1000);
|
||
timeFromTXErrorClear->start(1000);
|
||
TimeToStopCANRead = FALSE;
|
||
QtConcurrent::run(canReaderThread, this);
|
||
ui->groupRXErrors->show();
|
||
ui->groupTXErrors->show();
|
||
}
|
||
else
|
||
{
|
||
//Ошибка при открытии.
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Не удалось подключиться к устройству.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
ui->logger->setTextColor(Qt::red);
|
||
msg += QString("[SYS] Не удалось подключиться к устройству.");
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
}
|
||
}
|
||
|
||
//Открытие порта RS.
|
||
void UnionCOM::openSerialPort()
|
||
{
|
||
wRS->device_connect();
|
||
//Настройки порта:
|
||
m_serial->setPortName(wRS->m_currentSettings.name);
|
||
m_serial->setBaudRate(wRS->m_currentSettings.baudRate);
|
||
m_serial->setDataBits(wRS->m_currentSettings.dataBits);
|
||
m_serial->setParity(wRS->m_currentSettings.parity);
|
||
m_serial->setStopBits(wRS->m_currentSettings.stopBits);
|
||
m_serial->setFlowControl(wRS->m_currentSettings.flowControl);
|
||
|
||
//Попытка открыть порт.
|
||
if (m_serial->open(QIODevice::ReadWrite)) {
|
||
//Успешно
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Устройство подключено.");
|
||
ui->logger->setTextColor(Qt::blue);
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
//Включается функция приёма сообщений.
|
||
connect(m_serial, &QSerialPort::readyRead, this, &UnionCOM::readData);
|
||
AfterConnection();
|
||
} else {
|
||
//Ошибка при открытии.
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Не удалось подключиться к устройству.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
ui->logger->setTextColor(Qt::red);
|
||
msg += QString("[SYS] Не удалось подключиться к устройству. Error №%1").arg(errors_RS(m_serial->error()));
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
}
|
||
}
|
||
|
||
//Уведомление о подключении устройства.
|
||
void UnionCOM::Connect_Notification()
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Устройство подключено.");
|
||
ui->logger->setTextColor(Qt::blue);
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
}
|
||
|
||
//Перевод приложения в режим работы с устройством.
|
||
void UnionCOM::AfterConnection()
|
||
{
|
||
switch (ui->cboxTypeConnection->currentIndex()) {
|
||
case 0: //CAN
|
||
{
|
||
wCan->AfterConnection();
|
||
if(wCan->GetMode()!=SLCAN_MODE_LISTENONLY)
|
||
{
|
||
ui->TXgridFrame->setEnabled(TRUE);
|
||
}
|
||
break;
|
||
}
|
||
case 1: //RS
|
||
{
|
||
wRS->AfterConnection();
|
||
ui->TXgridFrame->setEnabled(TRUE);
|
||
break;
|
||
}
|
||
}
|
||
ui->cboxTypeConnection->setEnabled(FALSE);
|
||
ui->buttonConnect->setEnabled(FALSE);
|
||
ui->buttonDisconnect->setEnabled(TRUE);
|
||
}
|
||
|
||
/////////////////////////
|
||
//Отключение устройства//
|
||
// или com-порта //
|
||
/////////////////////////
|
||
|
||
//QT-слот обработчик отключения от устройства/порта.
|
||
void UnionCOM::on_buttonDisconnect_clicked()
|
||
{
|
||
for(int i = 0; i < 15; i++)
|
||
{
|
||
if(MacrosMain[i].IsPeriod==Qt::Checked)
|
||
stopMcrs(i+1);
|
||
}
|
||
switch (ui->cboxTypeConnection->currentIndex()) {
|
||
case 0:
|
||
{
|
||
//CAN
|
||
//Очистка буффера отправляемых сообщений.
|
||
ui->groupRXErrors->hide();
|
||
ui->spinRXErrorCount->setValue(0);
|
||
ui->groupTXErrors->hide();
|
||
ui->spinTXErrorCount->setValue(0);
|
||
timeFromRXErrorClear->stop();
|
||
timeFromTXErrorClear->stop();
|
||
QTime time(0, 0, 0);
|
||
ui->timeEditRX->setTime(time);
|
||
ui->timeEditTX->setTime(time);
|
||
//SlCan_DevicePurge(device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR|SLCAN_PURGE_RX_ABORT|SLCAN_PURGE_RX_CLEAR);
|
||
stopCANReadThread();
|
||
//Отключение устройства.
|
||
SlCan_DeviceClose(device);
|
||
break;
|
||
}
|
||
case 1:
|
||
{
|
||
//RS
|
||
//Отключается функция приёма сообщений.
|
||
disconnect(m_serial, &QSerialPort::readyRead, this, &UnionCOM::readData);
|
||
//Если устройство открыто - отключение.
|
||
if (m_serial->isOpen())
|
||
m_serial->close();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Устройство отключено.");
|
||
ui->logger->setTextColor(Qt::blue);
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
break;
|
||
}
|
||
}
|
||
AfterDisconnection();
|
||
}
|
||
|
||
//Уведомление о отключении устройства.
|
||
void UnionCOM::Disconnect_Notification()
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Устройство отключено.");
|
||
ui->logger->setTextColor(Qt::blue);
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
}
|
||
|
||
//Уведомление о аварийном отключении устройства.
|
||
void UnionCOM::Emergency_Disconnect_Notification()
|
||
{
|
||
ui->logger->setTextColor(Qt::red);
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Устройство аварийно завершило работу.");
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
ui->groupRXErrors->hide();
|
||
ui->spinRXErrorCount->setValue(0);
|
||
ui->groupTXErrors->hide();
|
||
ui->spinTXErrorCount->setValue(0);
|
||
timeFromRXErrorClear->stop();
|
||
timeFromTXErrorClear->stop();
|
||
QTime time(0, 0, 0);
|
||
ui->timeEditRX->setTime(time);
|
||
ui->timeEditTX->setTime(time);
|
||
}
|
||
|
||
//Перевод приложения в режим настройки и выбора подключения.
|
||
void UnionCOM::AfterDisconnection()
|
||
{
|
||
switch (ui->cboxTypeConnection->currentIndex()) {
|
||
case 0:
|
||
//CAN
|
||
{
|
||
wCan->AfterDisconnection();
|
||
break;
|
||
}
|
||
case 1:
|
||
//RS
|
||
{
|
||
wRS->AfterDisconnection();
|
||
break;
|
||
}
|
||
}
|
||
ui->cboxTypeConnection->setEnabled(TRUE);
|
||
ui->buttonConnect->setEnabled(TRUE);
|
||
ui->buttonDisconnect->setEnabled(FALSE);
|
||
ui->TXgridFrame->setEnabled(FALSE);
|
||
}
|
||
|
||
////////////////
|
||
//Приём данных//
|
||
////////////////
|
||
void UnionCOM::deleteTopLine()
|
||
{
|
||
QTextCursor cursor = ui->logger->textCursor();
|
||
cursor.movePosition(QTextCursor::Start);
|
||
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 0);
|
||
cursor.select(QTextCursor::LineUnderCursor);
|
||
cursor.removeSelectedText();
|
||
cursor.deleteChar();
|
||
}
|
||
|
||
void UnionCOM::rxErrorTimer_clear()
|
||
{
|
||
QTime time(0, 0, 0);
|
||
ui->timeEditRX->setTime(time);
|
||
timeFromRXErrorClear->start(1000);
|
||
}
|
||
|
||
void UnionCOM::txErrorTimer_clear()
|
||
{
|
||
QTime time(0, 0, 0);
|
||
ui->timeEditTX->setTime(time);
|
||
timeFromTXErrorClear->start(1000);
|
||
}
|
||
|
||
void UnionCOM::rxErrorTimer_anotherSec()
|
||
{
|
||
QTime time = ui->timeEditRX->time().addSecs(1);
|
||
ui->timeEditRX->setTime(time);
|
||
}
|
||
|
||
void UnionCOM::txErrorTimer_anotherSec()
|
||
{
|
||
QTime time = ui->timeEditTX->time().addSecs(1);
|
||
ui->timeEditTX->setTime(time);
|
||
}
|
||
|
||
static void canReaderThread(UnionCOM* obj)
|
||
{
|
||
obj->canReadingInThread = TRUE;
|
||
obj->TimeToReadEvents();
|
||
}
|
||
|
||
//QString timeInterval(const QString& from, const QString& to, const QString& format = "hh:mm:ss:ms")
|
||
//{
|
||
// QDateTime fromDt = QDateTime::fromString(from, format);
|
||
// QDateTime toDt = QDateTime::fromString(to, format);
|
||
// if (fromDt.isValid() && toDt.isValid()) {
|
||
// QDateTime interval = QDateTime::fromMSecsSinceEpoch(toDt.toMSecsSinceEpoch() - fromDt.toMSecsSinceEpoch());
|
||
// return interval.toString(format);
|
||
// }
|
||
// return QString();
|
||
//}
|
||
|
||
bool UnionCOM::event(QEvent* event)
|
||
{
|
||
if (event->type() == QEvent::User)
|
||
{
|
||
if(counterOfLoggerMSG>=500)
|
||
{
|
||
deleteTopLine();
|
||
}
|
||
else
|
||
{
|
||
counterOfLoggerMSG++;
|
||
}
|
||
MyEvent* postedEvent = static_cast<MyEvent*>(event);
|
||
switch (postedEvent->msgType()) {
|
||
case NORMAL_MSG_TO_LOGGER:
|
||
ui->logger->setTextColor(Qt::black);
|
||
break;
|
||
case WARNING_TO_LOGGER:
|
||
ui->logger->setTextColor(Qt::red);
|
||
break;
|
||
case GHOST_TO_LOGGER:
|
||
ui->logger->setTextColor(Qt::gray);
|
||
break;
|
||
case TX_ERROR_EVENT:
|
||
ui->spinTXErrorCount->stepUp();
|
||
postedEvent->~MyEvent();
|
||
event->~QEvent();
|
||
return true;
|
||
case RX_ERROR_EVENT:
|
||
ui->spinRXErrorCount->stepUp();
|
||
postedEvent->~MyEvent();
|
||
event->~QEvent();
|
||
return true;
|
||
}
|
||
ui->logger->append(postedEvent->message());
|
||
ui->logger->setTextColor(Qt::black);
|
||
postedEvent->~MyEvent();
|
||
event->~QEvent();
|
||
return true;
|
||
}
|
||
if(event->type() == RxCanEvent::EventType)
|
||
{
|
||
int i;
|
||
RxCanEvent* postedEvent = static_cast<RxCanEvent*>(event);
|
||
unsigned long long periodtmp = postedEvent->time_stamp();
|
||
QTime Period(0, 0, 0);
|
||
for(i = 0; i < RxCanModel->rowCount(); i++)
|
||
{
|
||
if(RxCanModel->item(i, RX_CAN_GROUP_TABLE_ID_COLUMN)->text().toUInt(nullptr, 16)==postedEvent->msg().ID)
|
||
{
|
||
PSLCAN_TIMESTAMP per_tmp = new SLCAN_TIMESTAMP();
|
||
per_tmp->Value = periodtmp - RxCanModel->item(i, RX_CAN_GROUP_TABLE_TMPS)->text().toULongLong(nullptr, 10);
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_PERIOD_COLUMN, //(QStringLiteral("%1").arg(postedEvent->msg().ID, 8, 16, QLatin1Char('0')
|
||
new QStandardItem(QString("%1:%2:%3.%4.%5").arg(QString::number(microsecondToHours(per_tmp->Value)),
|
||
QStringLiteral("%1").arg(microsecondToMinutes(per_tmp->Value), 2, 10, QLatin1Char('0')),
|
||
QStringLiteral("%1").arg(microsecondToSeconds(per_tmp->Value), 2, 10, QLatin1Char('0')),
|
||
QStringLiteral("%1").arg(microsecondToMilliseconds(per_tmp->Value), 3, 10, QLatin1Char('0')),
|
||
QStringLiteral("%1").arg(per_tmp->Value%1000, 3, 10, QLatin1Char('0')))));
|
||
delete per_tmp;
|
||
// Period = Period.addMSecs((QTime::fromString(RxCanModel->item(i, RX_CAN_GROUP_TABLE_TIME_COLUMN)->text(), "hh:mm:ss.zzz")).msecsTo(postedEvent->time()));
|
||
// RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_PERIOD_COLUMN,
|
||
// new QStandardItem(Period.toString("hh:mm:ss.zzz")));
|
||
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp)));
|
||
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TIME_COLUMN,
|
||
new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz")));
|
||
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_COUNT_COLUMN,
|
||
new QStandardItem(QString::number(RxCanModel->item(i, RX_CAN_GROUP_TABLE_COUNT_COLUMN)->text().toInt(nullptr, 10)+1, 10)));
|
||
|
||
QStandardItem *E_Standard = new QStandardItem(true);
|
||
E_Standard->setCheckable(true);
|
||
if(postedEvent->msg().Info&0b1)
|
||
{
|
||
E_Standard->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
E_Standard->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_E_COLUMN, E_Standard);
|
||
QStandardItem *R_Standard = new QStandardItem(true);
|
||
R_Standard->setCheckable(true);
|
||
if(postedEvent->msg().Info&0b10)
|
||
{
|
||
R_Standard->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
R_Standard->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_R_COLUMN, R_Standard);
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10)));
|
||
QString Data;
|
||
for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) {
|
||
Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0'));
|
||
if((j+1)<postedEvent->msg().DataCount)
|
||
Data += " ";
|
||
}
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper()));
|
||
break;
|
||
}
|
||
}
|
||
if(i>=RxCanModel->rowCount())
|
||
{
|
||
RxCanModel->insertRow(i);
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_ID_COLUMN, new QStandardItem(QStringLiteral("%1").arg(postedEvent->msg().ID, 8, 16, QLatin1Char('0')).toUpper()));
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TIME_COLUMN,
|
||
new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz")));
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp)));
|
||
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_COUNT_COLUMN,
|
||
new QStandardItem("1"));
|
||
QStandardItem *E_Standard = new QStandardItem(true);
|
||
|
||
E_Standard->setCheckable(true);
|
||
if(postedEvent->msg().Info&0b1)
|
||
{
|
||
E_Standard->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
E_Standard->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_E_COLUMN, E_Standard);
|
||
QStandardItem *R_Standard = new QStandardItem(true);
|
||
R_Standard->setCheckable(true);
|
||
|
||
if(postedEvent->msg().Info&0b10)
|
||
{
|
||
R_Standard->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
R_Standard->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_R_COLUMN, R_Standard);
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10)));
|
||
|
||
QString Data;
|
||
for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) {
|
||
Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0'));
|
||
if((j+1)<postedEvent->msg().DataCount)
|
||
Data += " ";
|
||
}
|
||
RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper()));
|
||
Data.clear();
|
||
}
|
||
for(i = 0; i < RxCanRequesterModel->rowCount(); i++)
|
||
{
|
||
if(RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN)->text().toUInt(nullptr, 16)==postedEvent->msg().ID)
|
||
{
|
||
// Period = Period.addMSecs((QTime::fromString(RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN)->text(), "hh:mm:ss.zzz")).msecsTo(postedEvent->time()));
|
||
// RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN,
|
||
// new QStandardItem(Period.toString("hh:mm:ss.zzz")));
|
||
|
||
PSLCAN_TIMESTAMP per_tmp = new SLCAN_TIMESTAMP();
|
||
per_tmp->Value = periodtmp - RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_TMPS)->text().toULongLong(nullptr, 10);
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN,
|
||
new QStandardItem(QString("%1:%2:%3.%4.%5").arg(QString::number(microsecondToHours(per_tmp->Value)),
|
||
QStringLiteral("%1").arg(microsecondToMinutes(per_tmp->Value), 2, 10, QLatin1Char('0')),
|
||
QStringLiteral("%1").arg(microsecondToSeconds(per_tmp->Value), 2, 10, QLatin1Char('0')),
|
||
QStringLiteral("%1").arg(microsecondToMilliseconds(per_tmp->Value), 3, 10, QLatin1Char('0')),
|
||
QStringLiteral("%1").arg(per_tmp->Value%1000, 3, 10, QLatin1Char('0')))));
|
||
delete per_tmp;
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp)));
|
||
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN,
|
||
new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz")));
|
||
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN,
|
||
new QStandardItem(QString::number(RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN)->text().toInt(nullptr, 10)+1, 10)));
|
||
|
||
QStandardItem *E_Requester = new QStandardItem(true);
|
||
E_Requester->setCheckable(true);
|
||
if(postedEvent->msg().Info&0b1)
|
||
{
|
||
E_Requester->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
E_Requester->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN, E_Requester);
|
||
QStandardItem *R_Requester = new QStandardItem(true);
|
||
R_Requester->setCheckable(true);
|
||
if(postedEvent->msg().Info&0b10)
|
||
{
|
||
R_Requester->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
R_Requester->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN, R_Requester);
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10)));
|
||
QString Data;
|
||
for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) {
|
||
Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0'));
|
||
if((j+1)<postedEvent->msg().DataCount)
|
||
Data += " ";
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper()));
|
||
break;
|
||
}
|
||
}
|
||
if(i>=RxCanRequesterModel->rowCount())
|
||
{
|
||
RxCanRequesterModel->insertRow(i);
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp)));
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN, new QStandardItem(QStringLiteral("%1").arg(postedEvent->msg().ID, 8, 16, QLatin1Char('0')).toUpper()));
|
||
QStandardItem *RxCanRoute = new QStandardItem(true);
|
||
RxCanRoute->setCheckable(true);
|
||
Requester_ID eID;
|
||
eID.ID_All = postedEvent->msg().ID;
|
||
QString datatype;
|
||
switch (eID.Standard.DataType)
|
||
{
|
||
case 0:
|
||
datatype = "Широковещательные";
|
||
break;
|
||
case 1:
|
||
datatype = "Дискретные";
|
||
break;
|
||
case 2:
|
||
datatype = "Аналоговые";
|
||
break;
|
||
case 3:
|
||
datatype = "Modbus Coil";
|
||
break;
|
||
case 4:
|
||
datatype = "Modbus Discrete";
|
||
break;
|
||
case 5:
|
||
datatype = "Modbus Holding";
|
||
break;
|
||
case 6:
|
||
datatype = "Modbus Input";
|
||
break;
|
||
case 7:
|
||
datatype = "Ошибки";
|
||
break;
|
||
case 0xF:
|
||
datatype = "Пульс";
|
||
break;
|
||
default:
|
||
datatype = "Unknown";
|
||
break;
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DATATYPE, new QStandardItem(datatype));
|
||
datatype.clear();
|
||
datatype.~QString();
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_SENSORID, new QStandardItem(QString::number(eID.Standard.SensorID, 16).toUpper()));
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DEVICE, new QStandardItem(QString::number(eID.Standard.Device, 16).toUpper()));
|
||
QString sensortype;
|
||
switch (eID.Standard.DataType)
|
||
{
|
||
case 0:
|
||
switch (eID.Standard.SensorType) {
|
||
case 0:
|
||
sensortype = "Статус";
|
||
break;
|
||
case 1:
|
||
sensortype = "Запрос на вкл/выкл";
|
||
break;
|
||
case 2:
|
||
sensortype = "Рестарт устройств";
|
||
break;
|
||
case 3:
|
||
sensortype = "Установка времени";
|
||
break;}
|
||
break;
|
||
case 1:
|
||
switch (eID.Standard.SensorType) {
|
||
case 0:
|
||
sensortype = "Аварии";
|
||
break;
|
||
case 1:
|
||
sensortype = "Предупреждения";
|
||
break;
|
||
case 2:
|
||
sensortype = "Управляющие сигналы";
|
||
break;
|
||
case 3:
|
||
sensortype = "Флаги";
|
||
break;
|
||
case 4:
|
||
sensortype = "Рестарт устройства";
|
||
break;
|
||
case 5:
|
||
sensortype = "Изменение режима работы устройства";
|
||
break;
|
||
case 6:
|
||
sensortype = "Запрос перечня п-мтров на устройство";
|
||
break;}
|
||
break;
|
||
case 2:
|
||
switch (eID.Standard.SensorType) {
|
||
case 0:
|
||
sensortype = "Универсальный запрос";
|
||
break;
|
||
case 1:
|
||
sensortype = "Уставки";
|
||
break;
|
||
case 2:
|
||
sensortype = "Напряжение";
|
||
break;
|
||
case 3:
|
||
sensortype = "Ток";
|
||
break;
|
||
case 4:
|
||
sensortype = "Температура";
|
||
break;}
|
||
break;
|
||
case 3:
|
||
case 4:
|
||
case 5:
|
||
case 6:
|
||
sensortype = QString::number(eID.Modbus.CountReg, 10);
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_SENSORID, new QStandardItem(QString::number(eID.Modbus.CountReg, 16).toUpper()));
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DEVICE, new QStandardItem(QString::number(eID.Modbus.Device, 16).toUpper()));
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_SENSORTYPE, new QStandardItem(sensortype));
|
||
if(eID.Standard.Route)
|
||
{
|
||
RxCanRoute->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
RxCanRoute->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_ROUTE, RxCanRoute);
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN,
|
||
new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz")));
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN,
|
||
new QStandardItem("1"));
|
||
QStandardItem *E_Requester = new QStandardItem(true);
|
||
E_Requester->setCheckable(true);
|
||
if(postedEvent->msg().Info&0b1)
|
||
{
|
||
E_Requester->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
E_Requester->setCheckState(Qt::Unchecked);
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN, E_Requester);
|
||
|
||
QStandardItem *R_Requester = new QStandardItem(true);
|
||
R_Requester->setCheckable(true);
|
||
if(postedEvent->msg().Info&0b10)
|
||
{
|
||
R_Requester->setCheckState(Qt::Checked);
|
||
}
|
||
else
|
||
{
|
||
R_Requester->setCheckState(Qt::Unchecked);
|
||
}
|
||
QString Data;
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN, R_Requester);
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10)));
|
||
for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) {
|
||
Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0'));
|
||
if((j+1)<postedEvent->msg().DataCount)
|
||
Data += " ";
|
||
}
|
||
RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper()));
|
||
}
|
||
ui->loggertable->resizeColumnsToContents();
|
||
if(ui->requestBox->checkState()==Qt::Checked)
|
||
{
|
||
ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, false);
|
||
ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, true);
|
||
}
|
||
else
|
||
{
|
||
ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, true);
|
||
ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, false);
|
||
}
|
||
postedEvent->~RxCanEvent();
|
||
event->~QEvent();
|
||
return true;
|
||
}
|
||
return QWidget::event(event);
|
||
}
|
||
|
||
void UnionCOM::stopCANReadThread()
|
||
{
|
||
TimeToStopCANRead = TRUE;
|
||
}
|
||
|
||
//Функция чтения сообщений (доступна при работе по RS).
|
||
void UnionCOM::readData()
|
||
{
|
||
//Если идёт загрузка файла, то запускается/обновляется таймер,
|
||
//а полученные данные записываются в буффер.
|
||
if(UsartFileLoading)
|
||
{
|
||
TransferEndTimer->start(5000);
|
||
const QByteArray data = m_serial->readAll();
|
||
BufferForLoadFile += QString(data);
|
||
}
|
||
//Стандартный приём.
|
||
else
|
||
{
|
||
const QByteArray data = m_serial->readAll();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[RX]";
|
||
//Вывод полученного сообщения доступен в двух вариантах: символы и HEX код.
|
||
if(ui->checkRXHEX->checkState()!=Qt::Checked)
|
||
{
|
||
msg += " ";
|
||
msg += data;
|
||
}
|
||
else
|
||
{
|
||
msg += "[HEX] ";
|
||
for(int i = 0; i<data.size(); i++)
|
||
{
|
||
msg += (QString::number((byte)data[i], 16)).toUpper();
|
||
msg += " ";
|
||
}
|
||
}
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
}
|
||
}
|
||
|
||
//Функция обработки событий и приёма сообщений по CAN.
|
||
void UnionCOM::TimeToReadEvents()
|
||
{
|
||
do{
|
||
SlCan_DeviceReadEvents(device, 0, inputEvents, FRAMES, &cntrInput);
|
||
for(unsigned i = 0; i < cntrInput; i++)
|
||
{
|
||
switch(inputEvents[i].EventType)
|
||
{
|
||
case 0: //Принят CAN фрейм.
|
||
{
|
||
PSLCAN_TIMESTAMP per_t = new SLCAN_TIMESTAMP();
|
||
SlCan_DeviceGetTimeStamp(device, per_t);
|
||
RxCanEvent* rxCanEvent = new RxCanEvent(inputEvents[i].Msg, QTime::currentTime(), per_t->Value);
|
||
QCoreApplication::postEvent(this, rxCanEvent);
|
||
delete per_t;
|
||
if(ui->checkPushMsgToLogger->checkState()==Qt::Checked)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[RX]");
|
||
if(ui->checkRXHEX->checkState()==Qt::Checked)
|
||
{
|
||
msg += QString("[HEX]");
|
||
}
|
||
msg += QString(" ");
|
||
if(ui->checkRXHEX->checkState()!=Qt::Checked)
|
||
{
|
||
msg += QString::fromLocal8Bit((char*)inputEvents[i].Msg.Data, inputEvents[i].Msg.DataCount);
|
||
}
|
||
else
|
||
{
|
||
for(int j = 0; j < inputEvents[i].Msg.DataCount; j++)
|
||
{
|
||
msg += QString::number((int)inputEvents[i].Msg.Data[j], 16);
|
||
msg += " ";
|
||
}
|
||
}
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
msg.clear();
|
||
}
|
||
break;
|
||
}
|
||
case 1: //Начата передача CAN.
|
||
{
|
||
if(ui->checkEchoMode->checkState()==Qt::Checked)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[TX]");
|
||
if(ui->checkRXHEX->checkState()==Qt::Checked)
|
||
{
|
||
msg += QString("[HEX]");
|
||
}
|
||
msg += QString(" ");
|
||
if(ui->checkRXHEX->checkState()==Qt::Checked)
|
||
{
|
||
for (int k = 0; k < inputEvents[i].Msg.DataCount; k++)
|
||
{
|
||
msg += QString::number(inputEvents[i].Msg.Data[k], 16);
|
||
msg += " ";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
msg += QString::fromLocal8Bit((char*)inputEvents[i].Msg.Data, inputEvents[i].Msg.DataCount);
|
||
}
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
}
|
||
break;
|
||
}
|
||
case 2: //Передача CAN фрейма успешно завершена.
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Передача успешно завершена.");
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
break;
|
||
}
|
||
case 3: //Передача CAN фрейма отменена.
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Передача CAN фрейма отменена.");
|
||
MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
break;
|
||
}
|
||
case 4: //Изменилось состояние CAN контроллера.
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Изменилось состояние CAN контроллера.");
|
||
MyEvent* myEvent = new MyEvent(msg, GHOST_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
break;
|
||
}
|
||
case 5: //Изменилось значение одного из счётчика ошибок.
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Счётчик(-и) ошибок устройства изменился(-ись). RX: %1. TX: %2.").arg(QString::number(inputEvents[i].ErrCountRx), QString::number(inputEvents[i].ErrCountTx));
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
break;
|
||
}
|
||
case 6: //Произошла ошибка шины CAN.
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Произошла ошибка шины CAN.");
|
||
MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += " BUSMODE: ";
|
||
switch(inputEvents[i].BusMode)
|
||
{
|
||
case SLCAN_BUS_STATE_ERROR_ACTIVE:
|
||
msg += "SLCAN_BUS_STATE_ERROR_ACTIVE.";
|
||
break;
|
||
case SLCAN_BUS_STATE_ERROR_ACTIVE_WARN:
|
||
msg += "SLCAN_BUS_STATE_ERROR_ACTIVE_WARN.";
|
||
break;
|
||
case SLCAN_BUS_STATE_ERROR_PASSIVE:
|
||
msg += "SLCAN_BUS_STATE_ERROR_PASSIVE.";
|
||
break;
|
||
case SLCAN_BUS_STATE_BUSOFF:
|
||
msg += "SLCAN_BUS_STATE_BUSOFF.";
|
||
break;
|
||
}
|
||
msg += QString(tr(" ErrCountRX: %1.").arg(inputEvents[i].ErrCountRx));
|
||
msg += QString(tr(" ErrCountTX: %1.").arg(inputEvents[i].ErrCountTx));
|
||
switch(inputEvents[i].ErrType)
|
||
{
|
||
case SLCAN_EVT_ERR_TYPE_BIT:
|
||
msg += " SLCAN_EVT_ERR_TYPE_BIT.";
|
||
break;
|
||
case SLCAN_EVT_ERR_TYPE_FORM:
|
||
msg += " SLCAN_EVT_ERR_TYPE_FORM.";
|
||
break;
|
||
case SLCAN_EVT_ERR_TYPE_STUFF:
|
||
msg += " SLCAN_EVT_ERR_TYPE_STUFF.";
|
||
break;
|
||
case SLCAN_EVT_ERR_TYPE_OTHER:
|
||
msg += " SLCAN_EVT_ERR_TYPE_OTHER.";
|
||
break;
|
||
}
|
||
switch (inputEvents[i].ErrDir) {
|
||
case SLCAN_EVT_ERR_DIR_TX:
|
||
msg += " SLCAN_EVT_ERR_DIR_TX.";
|
||
break;
|
||
case SLCAN_EVT_ERR_DIR_RX:
|
||
msg += " SLCAN_EVT_ERR_DIR_RX.";
|
||
MyEvent* myEvent = new MyEvent(NULL, RX_ERROR_EVENT);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
break;
|
||
}
|
||
switch (inputEvents[i].ErrFrame){
|
||
case SLCAN_EVT_ERR_FRAME_SOF:
|
||
msg += " SLCAN_EVT_ERR_FRAME_SOF.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ID28_ID21:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ID28_ID21.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ID20_ID18:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ID20_ID18.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_SRTR:
|
||
msg += " SLCAN_EVT_ERR_FRAME_SRTR.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_IDE:
|
||
msg += " SLCAN_EVT_ERR_FRAME_IDE.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ID17_ID13:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ID17_ID13.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ID12_ID5:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ID12_ID5.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ID4_ID0:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ID4_ID0.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_RTR:
|
||
msg += " SLCAN_EVT_ERR_FRAME_RTR.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_RSRV0:
|
||
msg += " SLCAN_EVT_ERR_FRAME_RSRV0.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_RSRV1:
|
||
msg += " SLCAN_EVT_ERR_FRAME_RSRV1.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_DLC:
|
||
msg += " SLCAN_EVT_ERR_FRAME_DLC.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_DATA:
|
||
msg += " SLCAN_EVT_ERR_FRAME_DATA.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_CRC_SEQ:
|
||
msg += " SLCAN_EVT_ERR_FRAME_CRC_SEQ.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_CRC_DEL:
|
||
msg += " SLCAN_EVT_ERR_FRAME_CRC_DEL.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ACK_SLOT:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ACK_SLOT.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ACK_DEL:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ACK_DEL.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_EOF:
|
||
msg += " SLCAN_EVT_ERR_FRAME_EOF.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_INTER:
|
||
msg += " SLCAN_EVT_ERR_FRAME_INTER.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_AER_FLAG:
|
||
msg += " SLCAN_EVT_ERR_FRAME_AER_FLAG.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_PER_FLAG:
|
||
msg += " SLCAN_EVT_ERR_FRAME_PER_FLAG.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_TDB:
|
||
msg += " SLCAN_EVT_ERR_FRAME_TDB.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_ERR_DEL:
|
||
msg += " SLCAN_EVT_ERR_FRAME_ERR_DEL.";
|
||
break;
|
||
case SLCAN_EVT_ERR_FRAME_OVER_FLAG:
|
||
msg += " SLCAN_EVT_ERR_FRAME_OVER_FLAG.";
|
||
break;
|
||
}
|
||
qDebug() << msg;
|
||
break;
|
||
}
|
||
case 7: //Произошла ошибка арбитража.
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Произошла ошибка арбитража.");
|
||
MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}while(!TimeToStopCANRead);
|
||
canReadingInThread = FALSE;
|
||
}
|
||
|
||
//////////////////
|
||
//Загрузка файла//
|
||
//////////////////
|
||
|
||
//QT-слот для выгрузки файла.
|
||
void UnionCOM::on_buttonLoadFile_clicked()
|
||
{
|
||
switch (ui->cboxTypeConnection->currentIndex()) {
|
||
case 0: //CAN
|
||
{
|
||
SlCan_DevicePurge(device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR|SLCAN_PURGE_RX_ABORT|SLCAN_PURGE_RX_CLEAR);
|
||
stopCANReadThread();
|
||
fileName = QFileDialog::getSaveFileName(this, "Save File", "/home/", "Bin Files (*.bin);;All files (*.*)");
|
||
if(fileName.isEmpty())
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Отмена выгрузки файла.");
|
||
qDebug()<<msg;
|
||
return;
|
||
}
|
||
SlCan_DeviceSetMode(device, SLCAN_MODE_CONFIG);
|
||
SlCan_DeviceSetBitRate(device, &br);
|
||
SlCan_DeviceSetEventLevel(device, SLCAN_EVT_LEVEL_RX_MSG);
|
||
SlCan_DeviceSetMode(device, SLCAN_MODE);
|
||
SlCan_DevicePurge(device, SLCAN_PURGE_RX_CLEAR);
|
||
clearMSG();
|
||
QFile file(fileName);
|
||
fileName.clear();
|
||
bool FirstRX = false;
|
||
if(file.open(QFile::WriteOnly))
|
||
{
|
||
QString bufferToFile;
|
||
QByteArray vuffalo;
|
||
do{
|
||
cntrInput=0;
|
||
if(FirstRX)
|
||
SlCan_DeviceReadMessages(device, READDELAY, inputMsg, FRAMES, &cntrInput);
|
||
else
|
||
{
|
||
SlCan_DeviceReadMessages(device, READDELAY, inputMsg, FRAMES, &cntrInput);
|
||
if(cntrInput==0)
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Время ожидания вышло. Не удалось выгрузить файл.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Время ожидания вышло. Не удалось выгрузить файл.";
|
||
qDebug() << msg;
|
||
return;
|
||
}
|
||
FirstRX=TRUE;
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][RX] Принято пакетов: %1").arg(cntrInput);
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
for(DWORD i = 0; i < cntrInput; i++)
|
||
{
|
||
for(int j = 0; j < inputMsg[i].DataCount; j++)
|
||
{
|
||
int Current = i*8+j;
|
||
vuffalo[Current] = inputMsg[i].Data[j];
|
||
}
|
||
}
|
||
file.write(vuffalo);
|
||
vuffalo.clear();
|
||
QCoreApplication::processEvents();
|
||
}while(cntrInput==FRAMES);
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][RX] Файл выгружен в:");
|
||
qDebug()<<msg;
|
||
qDebug()<<file.fileName();
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][RX] Файл выгружен.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
file.close();
|
||
}
|
||
else
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Не удалось выгрузить файл.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Не удалось выгрузить файл.";
|
||
qDebug() << msg;
|
||
return;
|
||
}
|
||
SlCan_DeviceSetMode(device, SLCAN_MODE_CONFIG);
|
||
SlCan_DeviceSetBitRate(device, &br);
|
||
SlCan_DeviceSetEventLevel(device, SLCAN_EVT_LEVEL_ERRORS);
|
||
SlCan_DeviceSetMode(device, SLCAN_MODE);
|
||
TimeToStopCANRead = FALSE;
|
||
QtConcurrent::run(canReaderThread, this);
|
||
break;
|
||
}
|
||
case 1: //RS
|
||
{
|
||
fileName = QFileDialog::getSaveFileName(this, "Save File", "/home/", "Bin Files (*.bin);;All files (*.*)");
|
||
if(fileName.isEmpty())
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Отмена выгрузки файла.");
|
||
qDebug()<<msg;
|
||
return;
|
||
}
|
||
TransferEndTimer = new QTimer(this);
|
||
TransferEndTimer->setSingleShot(TRUE);
|
||
connect(TransferEndTimer, &QTimer::timeout, this, &UnionCOM::EndOfUSARTLoadFile);
|
||
UsartFileLoading = 1;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
//Функция, которая вызывается через 5 секунд после окончания передачи. Производится запись полученных байтов в файл.
|
||
void UnionCOM::EndOfUSARTLoadFile()
|
||
{
|
||
UsartFileLoading=0;
|
||
if(BufferForLoadFile.isEmpty())
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Время ожидания вышло. Не удалось выгрузить файл.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Время ожидания вышло. Не удалось выгрузить файл.";
|
||
qDebug() << msg;
|
||
return;
|
||
}
|
||
QFile file(fileName);
|
||
fileName.clear();
|
||
QByteArray Buffer;
|
||
Buffer.resize(BufferForLoadFile.size());
|
||
if(file.open(QFile::WriteOnly))
|
||
{
|
||
Buffer = BufferForLoadFile.toUtf8();
|
||
file.write(Buffer);
|
||
file.close();
|
||
BufferForLoadFile.clear();
|
||
TransferEndTimer->~QTimer();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][RX] Файл выгружен в:");
|
||
qDebug()<<msg;
|
||
qDebug()<<file.fileName();
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][RX] Файл выгружен.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
}
|
||
else
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Ошибка выгрузки файла: Не удалось создать и/или открыть файл.").arg(cntrInput);
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug()<<msg;
|
||
}
|
||
}
|
||
|
||
///////////////////
|
||
//Базовые функции//
|
||
//отправки данных//
|
||
///////////////////
|
||
|
||
//Функция обработки ошибки при передаче.
|
||
void UnionCOM::Device_Error(PSLCAN_STATE DeviceState)
|
||
{
|
||
//Если состояние устройства отличается от нормы:
|
||
if(DeviceState->BusMode)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Передача прервана. Устройство находится в состоянии ";
|
||
switch(DeviceState->BusMode) {
|
||
//CAN контроллер находится в состоянии ERROR ACTIVE.
|
||
//Значение одного из счетчиков ошибок больше или равно 96.
|
||
case SLCAN_BUS_STATE_ERROR_ACTIVE_WARN:
|
||
msg += "ERROR ACTIVE.";
|
||
break;
|
||
//CAN контроллер находится в состоянии ERROR PASSIVE
|
||
//Значение одного из счетчиков ошибок больше 127.
|
||
case SLCAN_BUS_STATE_ERROR_PASSIVE:
|
||
msg += "ERROR PASSIVE.";
|
||
break;
|
||
//CAN контроллер находится в состоянии BUS OFF.
|
||
//Контроллер переходит в это состояние
|
||
//при превышеии счетчика ошибок передачи значения 256.
|
||
case SLCAN_BUS_STATE_BUSOFF:
|
||
msg += "BUS OFF.";
|
||
break;
|
||
}
|
||
MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
//Очистка буфера устройства.
|
||
SlCan_DevicePurge(device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR);
|
||
do{
|
||
SlCan_DeviceReadEvents(device, 0, inputEvents, FRAMES, &cntrInput);
|
||
}while(cntrInput==FRAMES);
|
||
}
|
||
}
|
||
|
||
//Функция отправки сообщения по CAN.
|
||
BYTE UnionCOM::writeMSG()
|
||
{
|
||
BYTE WriteStatus;
|
||
//Попытка отправить сообщение.
|
||
if(SlCan_DeviceWriteMessages(device, &outMsg, 1, &WriteStatus))
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz][TX]");
|
||
//Если при отправке сообщения возникла ошибка, то происходит вывод ошибки в логгер.
|
||
if(WriteStatus){
|
||
TX_error_counter+=8;
|
||
ui->spinTXErrorCount->setValue(ui->spinTXErrorCount->value()+1);
|
||
switch (WriteStatus) {
|
||
case SLCAN_TX_STATUS_TIMEOUT:
|
||
msg += " Сообщения не переданы. Передача прервана из-за таймаута.";
|
||
break;
|
||
case SLCAN_TX_STATUS_BUSOFF:
|
||
msg += " Сообщения не переданы. "
|
||
"Передача прервана из-за ошибок на шине CAN и перехода CAN контроллера устройства в режим BUS OFF.";
|
||
break;
|
||
case SLCAN_TX_STATUS_ABORT:
|
||
msg += " Сообщения не переданы. Передача прервана внешней командой.";
|
||
break;
|
||
case SLCAN_TX_STATUS_NOT_ENA:
|
||
msg += " Сообщения не переданы. Передача запрещена.";
|
||
break;
|
||
case SLCAN_TX_STATUS_ERROR_ONE_SHOT:
|
||
msg += " Сообщение передавалось в режиме ONE SHOT и произошла ошибка.";
|
||
break;
|
||
case SLCAN_TX_STATUS_INVALID_MODE:
|
||
msg += " Сообщения не переданы. Режим устройства не поддерживает передачу.";
|
||
break;
|
||
case SLCAN_TX_STATUS_UNKNOWN:
|
||
msg += " Сообщения не переданы. Ошибка не известна.";
|
||
break;
|
||
}
|
||
MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
}
|
||
//Если передача прошла успешна, снижается счётчик ошибок.
|
||
else
|
||
{
|
||
if(TX_error_counter>0) TX_error_counter--;
|
||
}
|
||
//Считывается текущее состояние устройства.
|
||
SlCan_DeviceGetState(device, &DeviceState);
|
||
//Если устройство не находится в нормальном режиме работы или кол-во ошибок при отправке превышает порог, то обрабатывается ошибка устройства.
|
||
if(DeviceState.BusMode!=SLCAN_BUS_STATE_ERROR_ACTIVE && WriteStatus)
|
||
{
|
||
Device_Error(&DeviceState);
|
||
return 0x07;
|
||
}
|
||
//Выводится статус отправки сообщения. 0 - успех, остальное - ошибки.
|
||
return WriteStatus;
|
||
}
|
||
return 0x07;
|
||
}
|
||
//Функция очистки буффера сообщения по CAN.
|
||
|
||
void UnionCOM::clearMSG()
|
||
{
|
||
for(BYTE& byte: outMsg.Data){
|
||
byte = 0;
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Очистка буффера сообщения по CAN.");
|
||
qDebug() << msg;
|
||
}
|
||
|
||
//////////////////////////////
|
||
//Отправка команды из строки//
|
||
//////////////////////////////
|
||
|
||
//QT-слот для обработки отправления
|
||
//сообщения(-ий) из командной строки.
|
||
void UnionCOM::on_buttonSendCMD_clicked()
|
||
{
|
||
isTxIdle_CMD();
|
||
}
|
||
|
||
void UnionCOM::isTxIdle_CMD()
|
||
{
|
||
if(isIdle)
|
||
{
|
||
//Вызов функции отправки.
|
||
startCMDTX();
|
||
}
|
||
else
|
||
{
|
||
//Подключение функции отправки к сигналу о завершении.
|
||
QDialog *stopCurrentTX = new QDialog;
|
||
stopCurrentTX->setWindowTitle("Прервать текущую передачу?");
|
||
stopCurrentTX->setMinimumSize(260, 50);
|
||
stopCurrentTX->setMaximumSize(260, 50);
|
||
QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX);
|
||
stopCurrentTX->setLayout(layoutCTX);
|
||
QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX);
|
||
layoutCTX->addWidget(yesOrNo);
|
||
connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept);
|
||
connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject);
|
||
stopCurrentTX->exec();
|
||
if(stopCurrentTX->result()==QDialog::Accepted)
|
||
{
|
||
connect(this, SIGNAL(isTxFinished()), this, SLOT(stepToStartCMDTX));
|
||
userTXInterruption = TRUE;
|
||
}
|
||
delete stopCurrentTX;
|
||
}
|
||
}
|
||
|
||
void UnionCOM::stepToStartCMDTX()
|
||
{
|
||
if(userTXInterruption)
|
||
{
|
||
disconnect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartCMDTX));
|
||
userTXInterruption=FALSE;
|
||
}
|
||
startCMDTX();
|
||
}
|
||
|
||
void UnionCOM::startCMDTX()
|
||
{
|
||
switch (ui->cboxTypeConnection->currentIndex())
|
||
{
|
||
case 0:
|
||
{
|
||
QtConcurrent::run(turnOnCMDTX);
|
||
break;
|
||
}
|
||
case 1:
|
||
{
|
||
sendCMD_RS();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void turnOnCMDTX()
|
||
{
|
||
com_target->sendCMD_CAN();
|
||
}
|
||
|
||
void UnionCOM::sendCMD_CAN()
|
||
{
|
||
isIdle=FALSE;
|
||
//Считывается текст на отправку.
|
||
QString tx_data = ui->lineMSG->text();
|
||
//Если информации для отправки нет - проходит сигнал и выход из функции.
|
||
if(tx_data.size()==0)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Пустое поле ввода.");
|
||
MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
//Уведомление о начале передачи.
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
//CAN
|
||
int i;
|
||
//Перевод из QString Unicod в Ascii.
|
||
QByteArray buffer = tx_data.toLocal8Bit();
|
||
BYTE MSG_Status;
|
||
//Из строки символов формируются сообщения и отправляются.
|
||
for(i = 0; i<(tx_data.size()/8); i+=8)
|
||
{
|
||
outMsg.Data[0] = buffer[i];
|
||
outMsg.Data[1] = buffer[i+1];
|
||
outMsg.Data[2] = buffer[i+2];
|
||
outMsg.Data[3] = buffer[i+3];
|
||
outMsg.Data[4] = buffer[i+4];
|
||
outMsg.Data[5] = buffer[i+5];
|
||
outMsg.Data[6] = buffer[i+6];
|
||
outMsg.Data[7] = buffer[i+7];
|
||
//Попытка отправить сообщение.
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
//Если передать сообщение не удаётся, то происходит отмена отправки.
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
clearMSG();
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
//Очистка буффера сообщения.
|
||
clearMSG();
|
||
}
|
||
//Если остались символы, передаём их.
|
||
if(i!=tx_data.size())
|
||
{
|
||
int j;
|
||
//Формируется сообщение из оставшихся символов.
|
||
for(j = 0; (j+i)<tx_data.size(); j++)
|
||
{
|
||
outMsg.Data[j]=buffer[j+i];
|
||
}
|
||
//Задаётся количество оставшихся символов.
|
||
outMsg.DataCount = j;
|
||
//Попытка отправить сообщение.
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
//Если передать сообщение не удаётся, то происходит отмена отправки.
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
outMsg.DataCount = 8;
|
||
clearMSG();
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
//Очистка буффера сообщения.
|
||
clearMSG();
|
||
//Возвращение к стандартному количеству байт для отправки.
|
||
outMsg.DataCount = 8;
|
||
}
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
void UnionCOM::sendCMD_RS()
|
||
{
|
||
isIdle=FALSE;
|
||
//Считывается текст на отправку.
|
||
QString tx_data = ui->lineMSG->text();
|
||
//Если информации для отправки нет - проходит сигнал и выход из функции.
|
||
if(tx_data.size()==0)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Пустое поле ввода.");
|
||
ui->logger->setTextColor(Qt::red);
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
//Уведомление о начале передачи.
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
m_serial->write(tx_data.toUtf8(), tx_data.size());
|
||
m_serial->waitForBytesWritten();
|
||
if(ui->checkEchoMode->checkState()==Qt::Checked)
|
||
{
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[TX] ");
|
||
msg += tx_data;
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
}
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Передача успешно завершена.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
/////////////////////////////
|
||
// Отправка пакета байтов, //
|
||
//задаваемых на форме в HEX//
|
||
/////////////////////////////
|
||
|
||
//Функция для отслеживания кол-ва отправляемых байт в команде.
|
||
void UnionCOM::on_boxDataCount_currentIndexChanged(int index)
|
||
{
|
||
if(ui->checkHEXRTR->checkState()==Qt::Checked)
|
||
{
|
||
return;
|
||
}
|
||
index--;
|
||
for(int i = 0; i < 8; i++)
|
||
{
|
||
if(i > (index))
|
||
{
|
||
HEXByteField[i]->setEnabled(FALSE);
|
||
}
|
||
else
|
||
{
|
||
HEXByteField[i]->setEnabled(TRUE);
|
||
}
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Количество байтов для отправки изменилось. Текущее количество: %1.").arg(index+1);
|
||
qDebug()<<msg;
|
||
}
|
||
|
||
//QT-Слот для отправки 8 байт в HEX формате введённых в поля на форме.
|
||
void UnionCOM::on_buttonSendCMDHex_clicked()
|
||
{
|
||
isTxIdle_CMDHEX();
|
||
}
|
||
|
||
void UnionCOM::isTxIdle_CMDHEX()
|
||
{
|
||
if(isIdle)
|
||
{
|
||
//Вызов функции отправки
|
||
startCMDHEXTX();
|
||
}
|
||
else
|
||
{
|
||
//Подключение функции отправки к сигналу о завершении.
|
||
QDialog *stopCurrentTX = new QDialog;
|
||
stopCurrentTX->setWindowTitle("Прервать текущую передачу?");
|
||
stopCurrentTX->setMinimumSize(260, 50);
|
||
stopCurrentTX->setMaximumSize(260, 50);
|
||
QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX);
|
||
stopCurrentTX->setLayout(layoutCTX);
|
||
QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX);
|
||
layoutCTX->addWidget(yesOrNo);
|
||
connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept);
|
||
connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject);
|
||
stopCurrentTX->exec();
|
||
if(stopCurrentTX->result()==QDialog::Accepted)
|
||
{
|
||
connect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartCMDHEXTX));
|
||
userTXInterruption=TRUE;
|
||
}
|
||
delete stopCurrentTX;
|
||
}
|
||
}
|
||
|
||
void UnionCOM::stepToStartCMDHEXTX()
|
||
{
|
||
if(userTXInterruption)
|
||
{
|
||
disconnect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartCMDHEXTX));
|
||
userTXInterruption=FALSE;
|
||
}
|
||
startCMDHEXTX();
|
||
}
|
||
|
||
void UnionCOM::startCMDHEXTX()
|
||
{
|
||
switch (ui->cboxTypeConnection->currentIndex())
|
||
{
|
||
case 0:
|
||
{
|
||
QtConcurrent::run(turnOnCMDHEXTX);
|
||
break;
|
||
}
|
||
case 1:
|
||
{
|
||
sendCMD_RS();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void turnOnCMDHEXTX()
|
||
{
|
||
com_target->sendCMDHEX_CAN();
|
||
}
|
||
|
||
void UnionCOM::sendCMDHEX_CAN()
|
||
{
|
||
isIdle=FALSE;
|
||
int SizeOfHEXCMD = ui->boxDataCount->currentIndex();
|
||
char tx_data[SizeOfHEXCMD];
|
||
for(int i = 0; i < SizeOfHEXCMD; i++)
|
||
{
|
||
tx_data[i] = (BYTE)HEXByteField[i]->text().toInt(nullptr, 16);
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
//CAN
|
||
BYTE MSG_Status;
|
||
DWORD oldID = outMsg.ID;
|
||
outMsg.ID = ui->lineHEXID->text().toInt(nullptr, 16);
|
||
BYTE oldInfo = outMsg.Info;
|
||
if(ui->checkHEXEID->checkState()==Qt::Checked)
|
||
{
|
||
outMsg.Info = oldInfo|0b1;
|
||
}
|
||
else
|
||
{
|
||
outMsg.Info = oldInfo&0b11111110;
|
||
}
|
||
if(ui->checkHEXRTR->checkState()==Qt::Checked)
|
||
{
|
||
outMsg.Info = outMsg.Info|0b10;
|
||
short oldDataCount = outMsg.DataCount;
|
||
outMsg.DataCount=SizeOfHEXCMD;
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
clearMSG();
|
||
outMsg.DataCount = oldDataCount;
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
clearMSG();
|
||
outMsg.DataCount = oldDataCount;
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
outMsg.Info = outMsg.Info&0b11111101;
|
||
}
|
||
outMsg.DataCount=SizeOfHEXCMD;
|
||
for(int i = 0; i < SizeOfHEXCMD; i++)
|
||
{
|
||
outMsg.Data[i] = tx_data[i];
|
||
}
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
clearMSG();
|
||
outMsg.DataCount = 8;
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
clearMSG();
|
||
outMsg.DataCount = 8;
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
void UnionCOM::sendCMDHEX_RS()
|
||
{
|
||
isIdle=FALSE;
|
||
int SizeOfHEXCMD = ui->boxDataCount->currentIndex();
|
||
char tx_data[SizeOfHEXCMD];
|
||
for(int i = 0; i < SizeOfHEXCMD; i++)
|
||
{
|
||
tx_data[i] = (BYTE)HEXByteField[i]->text().toInt(nullptr, 16);
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
if(ui->checkEchoMode->checkState()==Qt::Checked)
|
||
{
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[TX][HEX]");
|
||
for(int i = 0; i < SizeOfHEXCMD; i++)
|
||
{
|
||
msg += QString::number(tx_data[i], 16);
|
||
msg += " ";
|
||
}
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
}
|
||
m_serial->write(tx_data, SizeOfHEXCMD);
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Передача успешно завершена.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
//////////////////
|
||
//Отправка файла//
|
||
//////////////////
|
||
|
||
//QT-слот для отправки файла.
|
||
void UnionCOM::on_buttonSendFile_clicked()
|
||
{
|
||
isTxIdle_FILE();
|
||
}
|
||
|
||
void UnionCOM::isTxIdle_FILE()
|
||
{
|
||
if(isIdle)
|
||
{
|
||
//Вызов функции отправки.
|
||
startSendFile();
|
||
}
|
||
else
|
||
{
|
||
QDialog *stopCurrentTX = new QDialog;
|
||
stopCurrentTX->setWindowTitle("Прервать текущую передачу?");
|
||
stopCurrentTX->setMinimumSize(260, 50);
|
||
stopCurrentTX->setMaximumSize(260, 50);
|
||
QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX);
|
||
stopCurrentTX->setLayout(layoutCTX);
|
||
QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX);
|
||
layoutCTX->addWidget(yesOrNo);
|
||
connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept);
|
||
connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject);
|
||
stopCurrentTX->exec();
|
||
if(stopCurrentTX->result()==QDialog::Accepted)
|
||
{
|
||
connect(this, SIGNAL(isTxFinished()), this, SLOT(stepToStartSendFile));
|
||
userTXInterruption = TRUE;
|
||
}
|
||
delete stopCurrentTX;
|
||
}
|
||
}
|
||
|
||
void UnionCOM::stepToStartSendFile()
|
||
{
|
||
if(userTXInterruption)
|
||
{
|
||
disconnect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartSendFile));
|
||
userTXInterruption=FALSE;
|
||
}
|
||
startSendFile();
|
||
}
|
||
|
||
void UnionCOM::startSendFile()
|
||
{
|
||
isIdle=FALSE;
|
||
//Открывается окно выбора файла.
|
||
fileName = QFileDialog::getOpenFileName(this, "Open File", "/home/", "Bin Files (*.bin);;All files (*.*)");
|
||
//Если произошла отмена выбора, то срабатывают оповещение и выход из функции.
|
||
if(fileName.isEmpty())
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Отмена отправки файла.");
|
||
qDebug()<<msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
switch(ui->cboxTypeConnection->currentIndex())
|
||
{
|
||
case 0:
|
||
{
|
||
QtConcurrent::run(turnOnSendFile);
|
||
break;
|
||
}
|
||
case 1:
|
||
{
|
||
sendFile_RS();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void turnOnSendFile()
|
||
{
|
||
com_target->sendFile_CAN();
|
||
}
|
||
|
||
//Функция отправки файла.
|
||
void UnionCOM::sendFile_CAN()
|
||
{
|
||
isIdle=FALSE;
|
||
QFile *file = new QFile(fileName);
|
||
fileName.clear();
|
||
//Если открытие успешно:
|
||
if(file->open(QIODevice::ReadOnly))
|
||
{
|
||
//Уведомление о начале передачи.
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
//Считывается файл в массив байтов.
|
||
QByteArray data;
|
||
data = file->readAll();
|
||
file->close();
|
||
//Отправка байтов в зависимости от выбранного типа подключения.
|
||
Counter_of_suc_transmit=0;
|
||
TX_error_counter=0;
|
||
BYTE MSG_Status;
|
||
unsigned short CurrentByte=0;
|
||
//Формирование пакета и его отправка.
|
||
for(int i=0; i<data.size(); i++)
|
||
{
|
||
outMsg.Data[CurrentByte]=data[i];
|
||
if(CurrentByte==7)
|
||
{
|
||
CurrentByte=0;
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
//Если при передаче произошла неизвестная ошибка - передача прерывается.
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
//Мб нужна какая-то "пустая" передача для завершения?
|
||
|
||
clearMSG();
|
||
QThread::usleep(5000);
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
clearMSG();
|
||
}
|
||
else
|
||
{
|
||
CurrentByte++;
|
||
}
|
||
//Функция для продолжения корректной работы остального
|
||
//приложения во время выполнения трудоёмкой операции.
|
||
}
|
||
//Если после отправок пактов по 8 байт что-то осталось.
|
||
if(CurrentByte!=0)
|
||
{
|
||
outMsg.DataCount=CurrentByte;
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
if (MSG_Status == 0x07)
|
||
{
|
||
outMsg.DataCount=8;
|
||
clearMSG();
|
||
QThread::usleep(5000);
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
clearMSG();
|
||
}
|
||
//Возврат к стандартному количеству байт для отправки.
|
||
outMsg.DataCount=8;
|
||
//Оповещение об успешной передаче файла.
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Всего пакетов: %1. Успешно передано: %2. Ошибок передачи: %3."
|
||
).arg(div_up(data.size(), 8)).arg(Counter_of_suc_transmit).arg(TX_error_counter);
|
||
myEvent->~MyEvent();
|
||
myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
}
|
||
else
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Не удалось отправить файл.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Не удалось отправить файл.";
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
QThread::usleep(5000);
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
void UnionCOM::sendFile_RS()
|
||
{
|
||
isIdle=FALSE;
|
||
QFile *file = new QFile(fileName);
|
||
fileName.clear();
|
||
if(file->open(QIODevice::ReadOnly))
|
||
{
|
||
//Уведомление о начале передачи.
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
//Считывается файл в массив байтов.
|
||
QByteArray data;
|
||
data = file->readAll();
|
||
file->close();
|
||
//Отправка файла с получением кол-ва переданных байт.
|
||
int WrittenBytes = m_serial->write(data);
|
||
//Если передано не всё, то выводится сообщение об ошибке.
|
||
if (WrittenBytes!=data.size())
|
||
{
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Ошибка передачи. Передано: %1. Всего: %2").arg(WrittenBytes).arg(data.size());
|
||
ui->logger->setTextColor(Qt::red);
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
}
|
||
//Если всё прошло успешно, то выводится уведомление об отправке.
|
||
else
|
||
{
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Успешно передано %1 (в байтах).").arg(WrittenBytes);
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Не удалось отправить файл.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Не удалось отправить файл.";
|
||
qDebug() << msg;
|
||
delete file;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
delete file;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
//////////////////////
|
||
//Работа с макросами//
|
||
//////////////////////
|
||
|
||
//Настройка макросов.
|
||
void UnionCOM::on_buttonSetMcrs_clicked()
|
||
{
|
||
for(int i = 0; i < 15; i++)
|
||
{
|
||
MacrosMain[i].Name = McrsButtons[i]->text();
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Открыто окно изменения макросов.");
|
||
qDebug()<<msg;
|
||
MacrosSetting *mcrs_w = new MacrosSetting();
|
||
Qt::CheckState arrEID[15];
|
||
DWORD arrID[15];
|
||
Qt::CheckState arrRTR[15];
|
||
Qt::CheckState arrIsHEX[15];
|
||
int arrDLC[15];
|
||
QString arrName[15];
|
||
QString arrMcrs[15];
|
||
int arrCount[15];
|
||
Qt::CheckState arrIsPeriod[15];
|
||
int arrPeriod[15];
|
||
//Ввод стартовых значений.
|
||
for (int i = 0; i < 15; i++)
|
||
{
|
||
arrEID[i] = MacrosMain[i].EID;
|
||
arrID[i] = MacrosMain[i].ID;
|
||
arrRTR[i] = MacrosMain[i].RTR;
|
||
arrIsHEX[i] = MacrosMain[i].IsHEX;
|
||
arrDLC[i] = MacrosMain[i].DLC;
|
||
arrName[i] = MacrosMain[i].Name;
|
||
arrMcrs[i] = MacrosMain[i].Mcrs;
|
||
arrCount[i] = MacrosMain[i].Count;
|
||
arrIsPeriod[i] = MacrosMain[i].IsPeriod;
|
||
arrPeriod[i] = MacrosMain[i].Period;
|
||
}
|
||
mcrs_w->SetStart(arrEID, arrID, arrRTR, arrIsHEX, arrDLC, arrName, arrMcrs, arrCount, arrIsPeriod, arrPeriod);
|
||
mcrs_w->exec();
|
||
if(mcrs_w->IsOK)
|
||
{
|
||
for (int i = 0; i < 15; i++)
|
||
{
|
||
MacrosMain[i].EID = arrEID[i];
|
||
MacrosMain[i].ID = arrID[i];
|
||
MacrosMain[i].RTR = arrRTR[i];
|
||
MacrosMain[i].IsHEX = arrIsHEX[i];
|
||
MacrosMain[i].DLC = arrDLC[i];
|
||
MacrosMain[i].Name = arrName[i];
|
||
MacrosMain[i].Mcrs = arrMcrs[i];
|
||
MacrosMain[i].Count = arrCount[i];
|
||
MacrosMain[i].IsPeriod = arrIsPeriod[i];
|
||
MacrosMain[i].Period = arrPeriod[i];
|
||
//Смена имени на кнопках.
|
||
if(!MacrosMain[i].Name.isEmpty())
|
||
{
|
||
McrsButtons[i]->setText(MacrosMain[i].Name);
|
||
}
|
||
}
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Макросы были изменены.");
|
||
qDebug()<<msg;
|
||
}
|
||
else
|
||
{
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Отмена изменений макросов.");
|
||
qDebug()<<msg;
|
||
}
|
||
mcrs_w->~MacrosSetting();
|
||
}
|
||
|
||
//Сохранить текущий набор макросов в файл.
|
||
void UnionCOM::on_buttonSaveMcrsKit_clicked()
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Сохранение макросов.");
|
||
qDebug()<<msg;
|
||
fileName = QFileDialog::getSaveFileName(this, "Save File", "/home/", "Bin Files (*.bin);;All files (*.*)");
|
||
if(fileName.isEmpty())
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Отмена сохранения макросов.");
|
||
qDebug()<<msg;
|
||
return;
|
||
}
|
||
QFile file(fileName);
|
||
fileName.clear();
|
||
QByteArray buffer;
|
||
if(file.open(QFile::WriteOnly))
|
||
{
|
||
for(int i = 0; i < 15; i++)
|
||
{
|
||
buffer += MacrosMain[i].EID;
|
||
buffer += '\n';
|
||
buffer += QString::number(MacrosMain[i].ID, 16);
|
||
buffer += '\n';
|
||
buffer += MacrosMain[i].RTR;
|
||
buffer += '\n';
|
||
buffer += MacrosMain[i].IsHEX;
|
||
buffer += '\n';
|
||
buffer += QString::number(MacrosMain[i].DLC, 10);
|
||
buffer += '\n';
|
||
buffer += MacrosMain[i].Name;
|
||
buffer += '\n';
|
||
buffer += MacrosMain[i].Mcrs;
|
||
buffer += '\n';
|
||
buffer += QString::number(MacrosMain[i].Count, 10);
|
||
buffer += '\n';
|
||
buffer += MacrosMain[i].IsPeriod;
|
||
buffer += '\n';
|
||
buffer += QString::number(MacrosMain[i].Period, 10);
|
||
buffer += '\n';
|
||
file.write(buffer, buffer.size());
|
||
buffer.clear();
|
||
}
|
||
file.close();
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Файл сохранён.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Макросы сохранены в файл:";
|
||
qDebug() << msg;
|
||
qDebug() << file.fileName();
|
||
}
|
||
else
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Нет доступа.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Не удалось сохранить макросы: Нет доступа.";
|
||
qDebug() << msg;
|
||
return;
|
||
}
|
||
}
|
||
|
||
//Загрузить набор макросов из файла.
|
||
void UnionCOM::on_buttonLoadMcrsKit_clicked()
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Загрузка макросов.");
|
||
qDebug()<<msg;
|
||
fileName = QFileDialog::getOpenFileName(this, "Open File", "/home/", "Bin Files (*.bin);;All files (*.*)");
|
||
if(fileName.isEmpty())
|
||
{
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Отмена загрузки макросов.");
|
||
qDebug()<<msg;
|
||
return;
|
||
}
|
||
QFile file(fileName);
|
||
fileName.clear();
|
||
char buffer[MAX_MACROS_SIZE+1];
|
||
qint64 StatusOfRead;
|
||
mcrs_kit ReadMacrosKit[15];
|
||
if(file.open(QIODevice::ReadOnly))
|
||
{
|
||
for(int i = 0; i < 15; i++)
|
||
{
|
||
//EID Flag
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_EID_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_EID_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
ReadMacrosKit[i].EID = (Qt::CheckState)buffer[0];
|
||
//ID
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_ID_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_ID_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
QString subbuffer;
|
||
for(int j = 0; j < StatusOfRead-1; j++)
|
||
{
|
||
subbuffer += QString(buffer[j]);
|
||
}
|
||
ReadMacrosKit[i].ID = subbuffer.toInt(nullptr, 16);
|
||
subbuffer.clear();
|
||
//RTR Flag
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_RTR_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_RTR_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
ReadMacrosKit[i].RTR = (Qt::CheckState)buffer[0];
|
||
//Считывание значения HEX флага в макросе.
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_HEX_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_HEX_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
ReadMacrosKit[i].IsHEX = (Qt::CheckState)buffer[0];
|
||
//Считывание имени макроса.
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_NAME_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_NAME_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
|
||
StatusOfRead = file.readLine(buffer, MAX_DLC_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_DLC_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
for(int j = 0; j < StatusOfRead-1; j++)
|
||
{
|
||
subbuffer += QString(buffer[j]);
|
||
}
|
||
ReadMacrosKit[i].DLC = subbuffer.toInt(nullptr, 10);
|
||
subbuffer.clear();
|
||
for(int j = 0; j < StatusOfRead-1; j++)
|
||
{
|
||
ReadMacrosKit[i].Name += QString(buffer[j]);
|
||
}
|
||
//Считывание макроса.
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
for(int j = 0; j < StatusOfRead-1; j++)
|
||
{
|
||
ReadMacrosKit[i].Mcrs += QString(buffer[j]);
|
||
}
|
||
//Считывание количества отправок.
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
for(int j = 0; j < StatusOfRead-1; j++)
|
||
{
|
||
subbuffer += QString(buffer[j]);
|
||
}
|
||
ReadMacrosKit[i].Count = subbuffer.toInt(nullptr, 10);
|
||
subbuffer.clear();
|
||
//Считывание значение флага периода.
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
ReadMacrosKit[i].IsPeriod = (Qt::CheckState)buffer[0];
|
||
//Считывание периода.
|
||
StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2);
|
||
if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE))
|
||
{
|
||
return;
|
||
}
|
||
for(int j = 0; j < StatusOfRead-1; j++)
|
||
{
|
||
subbuffer += QString(buffer[j]);
|
||
}
|
||
ReadMacrosKit[i].Period = subbuffer.toInt(nullptr, 10);
|
||
subbuffer.clear();
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Загрузка набора макросов из файла:");
|
||
qDebug()<<msg;
|
||
qDebug() << file.fileName();
|
||
file.close();
|
||
//Если считывание файла прошло успешно - загрузка сохранённого набора макросов.
|
||
for(int i = 0; i < 15; i++)
|
||
{
|
||
MacrosMain[i].EID = ReadMacrosKit[i].EID;
|
||
MacrosMain[i].ID = ReadMacrosKit[i].ID;
|
||
MacrosMain[i].RTR = ReadMacrosKit[i].RTR;
|
||
MacrosMain[i].IsHEX = ReadMacrosKit[i].IsHEX;
|
||
MacrosMain[i].DLC = ReadMacrosKit[i].DLC;
|
||
MacrosMain[i].Name = ReadMacrosKit[i].Name;
|
||
MacrosMain[i].Mcrs = ReadMacrosKit[i].Mcrs;
|
||
MacrosMain[i].Count = ReadMacrosKit[i].Count;
|
||
MacrosMain[i].IsPeriod = ReadMacrosKit[i].IsPeriod;
|
||
MacrosMain[i].Period = ReadMacrosKit[i].Period;
|
||
if(!MacrosMain[i].Name.isEmpty())
|
||
{
|
||
McrsButtons[i]->setText(MacrosMain[i].Name);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Нет доступа.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Не удалось загрузить макросы: Нет доступа.";
|
||
qDebug() << msg;
|
||
return;
|
||
}
|
||
}
|
||
|
||
//Функция для проверки файла сохранения наборов макросов.
|
||
bool UnionCOM::CheckFile(qint64 StatusOfRead, char *buffer, qint64 MaxByteToRead)
|
||
{
|
||
if(StatusOfRead<=0 || (StatusOfRead==(MaxByteToRead+1) && buffer[MaxByteToRead]!='\n'))
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText("Файл повреждён.");
|
||
msgBox.exec();
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += "[SYS] Не удалось загрузить макросы: Файл повреждён.";
|
||
qDebug() << msg;
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
//Макросы.
|
||
void UnionCOM::isTxIdle_MCRS(int index)
|
||
{
|
||
com_target->notTimeToStopPeriodMcrs[index-1] = TRUE;
|
||
if(isIdle)
|
||
{
|
||
//Вызов функции отправки.
|
||
startMCRSTX(index);
|
||
}
|
||
else
|
||
{
|
||
//Подключение функции отправки к сигналу о завершении.
|
||
QDialog *stopCurrentTX = new QDialog;
|
||
stopCurrentTX->setWindowTitle("Прервать текущую передачу?");
|
||
stopCurrentTX->setMinimumSize(260, 50);
|
||
stopCurrentTX->setMaximumSize(260, 50);
|
||
QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX);
|
||
stopCurrentTX->setLayout(layoutCTX);
|
||
QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX);
|
||
layoutCTX->addWidget(yesOrNo);
|
||
connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept);
|
||
connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject);
|
||
stopCurrentTX->exec();
|
||
if(stopCurrentTX->result()==QDialog::Accepted)
|
||
{
|
||
connect(this, &UnionCOM::isTxFinished, funcptr[index]);
|
||
userTXInterruption=TRUE;
|
||
if(McrsPeriodTransfer[index-1])
|
||
{
|
||
stopMcrs(index);
|
||
}
|
||
}
|
||
stopCurrentTX->~QDialog();
|
||
}
|
||
}
|
||
|
||
void UnionCOM::startMCRSTX(int index)
|
||
{
|
||
index--;
|
||
if(userTXInterruption)
|
||
{
|
||
disconnect(this, SIGNAL(isTxFinished), this, (char*)funcptr[index]);
|
||
userTXInterruption=FALSE;
|
||
}
|
||
switch (ui->cboxTypeConnection->currentIndex())
|
||
{
|
||
case 0:
|
||
{
|
||
turnOnMcrsTX(index);
|
||
break;
|
||
}
|
||
case 1:
|
||
{
|
||
pushMcrs_RS(index);
|
||
break;
|
||
}
|
||
}
|
||
//Если макрос имеет свойство периодичности, то запускается таймер,
|
||
//который повторит отправку макроса через заданный период.
|
||
if(MacrosMain[index].IsPeriod==Qt::Checked && notTimeToStopPeriodMcrs[index])
|
||
{
|
||
McrsStopButtons[index]->setEnabled(TRUE);
|
||
McrsPeriodTransfer[index]->start(MacrosMain[index].Period);
|
||
}
|
||
}
|
||
|
||
static void turnOnMcrsTX(int index)
|
||
{
|
||
com_target->pushMcrs_CAN(index);
|
||
}
|
||
|
||
static void stepToStartMCRS1()
|
||
{
|
||
com_target->startMCRSTX(1);
|
||
}
|
||
static void stepToStartMCRS2()
|
||
{
|
||
com_target->startMCRSTX(2);
|
||
}
|
||
static void stepToStartMCRS3()
|
||
{
|
||
com_target->startMCRSTX(3);
|
||
}
|
||
static void stepToStartMCRS4()
|
||
{
|
||
com_target->startMCRSTX(4);
|
||
}
|
||
static void stepToStartMCRS5()
|
||
{
|
||
com_target->startMCRSTX(5);
|
||
}
|
||
static void stepToStartMCRS6()
|
||
{
|
||
com_target->startMCRSTX(6);
|
||
}
|
||
static void stepToStartMCRS7()
|
||
{
|
||
com_target->startMCRSTX(7);
|
||
}
|
||
static void stepToStartMCRS8()
|
||
{
|
||
com_target->startMCRSTX(8);
|
||
}
|
||
static void stepToStartMCRS9()
|
||
{
|
||
com_target->startMCRSTX(9);
|
||
}
|
||
static void stepToStartMCRS10()
|
||
{
|
||
com_target->startMCRSTX(10);
|
||
}
|
||
static void stepToStartMCRS11()
|
||
{
|
||
com_target->startMCRSTX(11);
|
||
}
|
||
static void stepToStartMCRS12()
|
||
{
|
||
com_target->startMCRSTX(12);
|
||
}
|
||
static void stepToStartMCRS13()
|
||
{
|
||
com_target->startMCRSTX(13);
|
||
}
|
||
static void stepToStartMCRS14()
|
||
{
|
||
com_target->startMCRSTX(14);
|
||
}
|
||
static void stepToStartMCRS15()
|
||
{
|
||
com_target->startMCRSTX(15);
|
||
}
|
||
|
||
//Отправка макроса.
|
||
void UnionCOM::pushMcrs_CAN(int index)
|
||
{
|
||
if(!notTimeToStopPeriodMcrs[index])
|
||
{
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
isIdle=FALSE;
|
||
if(MacrosMain[index].Mcrs.size()==0 && MacrosMain[index].RTR!=Qt::Checked)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Макрос не задан.");
|
||
MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER);
|
||
QCoreApplication::postEvent(this, myEvent);
|
||
qDebug() << msg;
|
||
BYTE MSG_Status;
|
||
DWORD oldID = outMsg.ID;
|
||
outMsg.ID = MacrosMain[index].ID;
|
||
BYTE oldInfo = outMsg.Info;
|
||
if(MacrosMain[index].EID==Qt::Checked)
|
||
{
|
||
outMsg.Info = oldInfo|0b1;
|
||
}
|
||
else
|
||
{
|
||
outMsg.Info = oldInfo&0b11111110;
|
||
}
|
||
if(MacrosMain[index].RTR==Qt::Checked)
|
||
{
|
||
outMsg.Info = outMsg.Info|0b10;
|
||
short oldDataCount = outMsg.DataCount;
|
||
outMsg.DataCount=MacrosMain[index].DLC;
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
if(MacrosMain[index].IsPeriod==Qt::Checked)
|
||
stopMcrs(index+1);
|
||
clearMSG();
|
||
outMsg.DataCount = oldDataCount;
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
clearMSG();
|
||
outMsg.DataCount = oldDataCount;
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
outMsg.Info = outMsg.Info&0b11111101;
|
||
}
|
||
QByteArray buffer;
|
||
if(MacrosMain[index].IsHEX)
|
||
{
|
||
QString oldMcrs = MacrosMain[index].Mcrs;
|
||
MacrosMain[index].Mcrs = MacrosMain[index].Mcrs.replace(" ", "");
|
||
if(MacrosMain[index].Mcrs.size()%2)
|
||
{
|
||
MacrosMain[index].Mcrs = "0" + MacrosMain[index].Mcrs;
|
||
}
|
||
QString Subbuff;
|
||
for(int i = 0; i < MacrosMain[index].Mcrs.size()-1; i+=2)
|
||
{
|
||
Subbuff = MacrosMain[index].Mcrs[i];
|
||
Subbuff += MacrosMain[index].Mcrs[i+1];
|
||
buffer += Subbuff.toInt(nullptr, 16);
|
||
}
|
||
MacrosMain[index].Mcrs = oldMcrs;
|
||
}
|
||
else
|
||
{
|
||
buffer += MacrosMain[index].Mcrs.toLocal8Bit();
|
||
}
|
||
//CAN
|
||
for(int TX_Counter = 0; TX_Counter<MacrosMain[index].Count; TX_Counter++)
|
||
{
|
||
int i;
|
||
for(i = 0; i<(buffer.size()/8); i+=8)
|
||
{
|
||
outMsg.Data[0] = buffer[i];
|
||
outMsg.Data[1] = buffer[i+1];
|
||
outMsg.Data[2] = buffer[i+2];
|
||
outMsg.Data[3] = buffer[i+3];
|
||
outMsg.Data[4] = buffer[i+4];
|
||
outMsg.Data[5] = buffer[i+5];
|
||
outMsg.Data[6] = buffer[i+6];
|
||
outMsg.Data[7] = buffer[i+7];
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
if(MacrosMain[index].IsPeriod==Qt::Checked)
|
||
stopMcrs(index+1);
|
||
clearMSG();
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
clearMSG();
|
||
}
|
||
//Если остались символы, передаём их.
|
||
if(i!=buffer.size())
|
||
{
|
||
int j;
|
||
for(j = 0; (j+i)<buffer.size(); j++)
|
||
{
|
||
outMsg.Data[j]=buffer[j+i];
|
||
}
|
||
outMsg.DataCount = j;
|
||
do {
|
||
MSG_Status = writeMSG();
|
||
if (MSG_Status == 0x07 || userTXInterruption)
|
||
{
|
||
if(MacrosMain[index].IsPeriod==Qt::Checked)
|
||
stopMcrs(index+1);
|
||
clearMSG();
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
} while(MSG_Status);
|
||
clearMSG();
|
||
outMsg.DataCount = 8;
|
||
}
|
||
}
|
||
outMsg.ID = oldID;
|
||
outMsg.Info = oldInfo;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
void UnionCOM::pushMcrs_RS(int index)
|
||
{
|
||
isIdle=FALSE;
|
||
if(MacrosMain[index].Mcrs.size()==0)
|
||
{
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS] Макрос не задан.");
|
||
ui->logger->setTextColor(Qt::red);
|
||
ui->logger->append(msg);
|
||
ui->logger->setTextColor(Qt::black);
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
return;
|
||
}
|
||
QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Начало передачи.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
QByteArray buffer;
|
||
if(MacrosMain[index].IsHEX)
|
||
{
|
||
QString Subbuff;
|
||
for(int i = 0; i < MacrosMain[index].Mcrs.size()-1; i+=2)
|
||
{
|
||
Subbuff = MacrosMain[index].Mcrs[i];
|
||
Subbuff += MacrosMain[index].Mcrs[i+1];
|
||
buffer += Subbuff.toInt(nullptr, 16);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
buffer += MacrosMain[index].Mcrs;
|
||
}
|
||
for(int TX_Counter = 0; TX_Counter<MacrosMain[index].Count; TX_Counter++)
|
||
{
|
||
m_serial->write(buffer, buffer.size());
|
||
if(ui->checkEchoMode->checkState()==Qt::Checked)
|
||
{
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[TX] ");
|
||
msg += buffer;
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
}
|
||
}
|
||
msg = QTime::currentTime().toString("[hh:mm:ss.zzz]");
|
||
msg += QString("[SYS][TX] Передача успешно завершена.");
|
||
ui->logger->setTextColor(Qt::black);
|
||
ui->logger->append(msg);
|
||
qDebug() << msg;
|
||
isIdle=TRUE;
|
||
emit isTxFinished();
|
||
}
|
||
|
||
//Остановка переодического макроса.
|
||
void UnionCOM::stopMcrs(int index)
|
||
{
|
||
index--;
|
||
McrsPeriodTransfer[index]->stop();
|
||
notTimeToStopPeriodMcrs[index]=FALSE;
|
||
McrsStopButtons[index]->setEnabled(FALSE);
|
||
}
|
||
|
||
void UnionCOM::on_buttonRXErrorCountErase_clicked()
|
||
{
|
||
ui->spinRXErrorCount->setValue(0);
|
||
rxErrorTimer_clear();
|
||
}
|
||
|
||
void UnionCOM::on_buttonTXErrorCountErase_clicked()
|
||
{
|
||
ui->spinTXErrorCount->setValue(0);
|
||
txErrorTimer_clear();
|
||
}
|
||
|
||
void UnionCOM::on_buttonCRC_clicked()
|
||
{
|
||
CRC16 *crc_widget = new CRC16(nullptr);
|
||
crc_widget->setWindowTitle("CRC Calc");
|
||
crc_widget->show();
|
||
}
|
||
|
||
void UnionCOM::on_checkHEXRTR_stateChanged(int arg1)
|
||
{
|
||
bool flag;
|
||
if(ui->checkHEXRTR->checkState()==Qt::Checked)
|
||
{
|
||
flag = false;
|
||
}
|
||
else
|
||
{
|
||
flag = true;
|
||
}
|
||
for(int i = 0; i < 8; i++)
|
||
{
|
||
if(flag && (ui->boxDataCount->currentIndex()>=(i+1)))
|
||
{
|
||
HEXByteField[i]->setEnabled(flag);
|
||
}
|
||
else
|
||
{
|
||
HEXByteField[i]->setEnabled(false);
|
||
}
|
||
}
|
||
}
|
||
|
||
void UnionCOM::on_checkHEXEID_stateChanged(int arg1)
|
||
{
|
||
if(ui->checkHEXEID->checkState()==Qt::Checked)
|
||
{
|
||
ui->lineHEXID->setInputMask(">HHHHHHHH");
|
||
}
|
||
else
|
||
{
|
||
ui->lineHEXID->setInputMask(">HHH");
|
||
}
|
||
}
|
||
|
||
void UnionCOM::on_lineHEXID_textChanged(const QString &arg1)
|
||
{
|
||
QString buffer = QString::number(ui->lineHEXID->text().toUInt(nullptr, 16), 10);
|
||
int pos = 0;
|
||
unsigned long long maxRange;
|
||
if(ui->checkHEXEID->checkState()==Qt::Checked)
|
||
{
|
||
maxRange = 0x1FFFFFFF;
|
||
}
|
||
else
|
||
{
|
||
maxRange = 0x7FF;
|
||
}
|
||
if((unsigned long long)buffer.toUInt(nullptr, 10) > (unsigned long long) maxRange)
|
||
{
|
||
ui->lineHEXID->setStyleSheet("border: 1px solid red");
|
||
ui->lineHEXID->setToolTip(QString("Valid ID: 0 - 0x%1").arg(QString::number(maxRange, 16).toUpper()));
|
||
ui->buttonSendCMDHex->setEnabled(false);
|
||
}
|
||
else
|
||
{
|
||
ui->lineHEXID->setStyleSheet("");
|
||
ui->lineHEXID->setToolTip(QString());
|
||
ui->buttonSendCMDHex->setEnabled(true);
|
||
}
|
||
}
|
||
#include "canidcalc.h"
|
||
|
||
void UnionCOM::on_pushButton_clicked()
|
||
{
|
||
CanIdCalc *CAN_ID_Calc = new CanIdCalc(nullptr);
|
||
CAN_ID_Calc->setWindowTitle("CAN ID Calc");
|
||
CAN_ID_Calc->show();
|
||
}
|
||
|
||
void UnionCOM::tableInit()
|
||
{
|
||
ui->loggertable->setSortingEnabled(true);
|
||
|
||
RxCanModel = new QStandardItemModel(0, 9);
|
||
{
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_COUNT_COLUMN, Qt::Horizontal, "Count");
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_TIME_COLUMN, Qt::Horizontal, "Time, h:m:s.ms");
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_PERIOD_COLUMN, Qt::Horizontal, "Period, h:m:s.ms.us");
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_ID_COLUMN, Qt::Horizontal, "ID (hex)");
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_E_COLUMN, Qt::Horizontal, "E");
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_R_COLUMN, Qt::Horizontal, "R");
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_DLC_COLUMN, Qt::Horizontal, "DLC");
|
||
RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_DATA_COLUMN, Qt::Horizontal, "Data (hex)");
|
||
}
|
||
RxCanRequesterModel = new QStandardItemModel(0, 14);
|
||
{
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN, Qt::Horizontal, "Count");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN, Qt::Horizontal, "Time, h:m:s.ms");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN, Qt::Horizontal, "Period, h:m:s.ms.us");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN, Qt::Horizontal, "ID (hex)");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_ROUTE, Qt::Horizontal, "Route");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DATATYPE, Qt::Horizontal, "DataType");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_SENSORTYPE, Qt::Horizontal, "SensorType");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_SENSORID, Qt::Horizontal, "SensorID");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DEVICE, Qt::Horizontal, "Device");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN, Qt::Horizontal, "E");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN, Qt::Horizontal, "R");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN, Qt::Horizontal, "DLC");
|
||
RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN, Qt::Horizontal, "Data (hex)");
|
||
}
|
||
if(ui->requestBox->checkState()==Qt::Checked)
|
||
{
|
||
ui->loggertable->setModel(RxCanRequesterModel);
|
||
ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, false);
|
||
ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, true);
|
||
}
|
||
else
|
||
{
|
||
ui->loggertable->setModel(RxCanModel);
|
||
ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, true);
|
||
ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, false);
|
||
}
|
||
}
|
||
|
||
void UnionCOM::on_requestBox_stateChanged(int arg1)
|
||
{
|
||
switch (arg1) {
|
||
case Qt::Unchecked:
|
||
ui->loggertable->setModel(RxCanModel);
|
||
ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, true);
|
||
ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, false);
|
||
break;
|
||
case Qt::Checked:
|
||
ui->loggertable->setModel(RxCanRequesterModel);
|
||
ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, false);
|
||
ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, true);
|
||
break;
|
||
}
|
||
ui->loggertable->resizeColumnsToContents();
|
||
}
|