mythread.cpp \
result_thread.cpp \
custom.cpp \
+ rgb_serial_reader.cpp \
sqldbmanager.cpp \
settings.cpp \
dialogsettings.cpp \
result_thread.h \
common.h \
custom.h \
+ rgb_serial_reader.h \
sqldbmanager.h \
settings.h \
dialogsettings.h \
case 0:
widgets.txtb_dispaly = ui->txtb_dispaly;
widgets.label_runtime_status = ui->label_runtime_status1;
-
widgets.label_result_success = ui->label_result_success1;
widgets.label_result_fail = ui->label_result_fail1;
widgets.cbox_uart_com_select = ui->cbox_uart_com_select_1;
+ widgets.cbox_uart_com_select_rgb = ui->cbox_uart_com_select_rgb1;
widgets.pbtn_spp_reconnect = ui->pbtn_spp_reconnect_1;
break;
case 1:
widgets.txtb_dispaly = ui->txtb_dispaly_2;
widgets.label_runtime_status = ui->label_runtime_status2;
-
widgets.label_result_success = ui->label_result_success2;
widgets.label_result_fail = ui->label_result_fail2;
widgets.cbox_uart_com_select = ui->cbox_uart_com_select_2;
+ widgets.cbox_uart_com_select_rgb = ui->cbox_uart_com_select_rgb2;
widgets.pbtn_spp_reconnect = ui->pbtn_spp_reconnect_2;
break;
case 2:
widgets.txtb_dispaly = ui->txtb_dispaly_3;
widgets.label_runtime_status = ui->label_runtime_status3;
-
widgets.label_result_success = ui->label_result_success3;
widgets.label_result_fail = ui->label_result_fail3;
widgets.cbox_uart_com_select = ui->cbox_uart_com_select_3;
+ widgets.cbox_uart_com_select_rgb = ui->cbox_uart_com_select_rgb3;
widgets.pbtn_spp_reconnect = ui->pbtn_spp_reconnect_3;
break;
case 3:
widgets.txtb_dispaly = ui->txtb_dispaly_4;
widgets.label_runtime_status = ui->label_runtime_status4;
-
widgets.label_result_success = ui->label_result_success4;
widgets.label_result_fail = ui->label_result_fail4;
widgets.cbox_uart_com_select = ui->cbox_uart_com_select_4;
+ widgets.cbox_uart_com_select_rgb = ui->cbox_uart_com_select_rg_4;
widgets.pbtn_spp_reconnect = ui->pbtn_spp_reconnect_4;
break;
default:
widgets.txtb_dispaly = ui->txtb_dispaly;
widgets.label_runtime_status = ui->label_runtime_status1;
-
widgets.label_result_success = ui->label_result_success1;
widgets.label_result_fail = ui->label_result_fail1;
widgets.cbox_uart_com_select = ui->cbox_uart_com_select_1;
+ widgets.cbox_uart_com_select_rgb = ui->cbox_uart_com_select_rgb1;
widgets.pbtn_spp_reconnect = ui->pbtn_spp_reconnect_1;
break;
}
// 连接显示消息信号
connect(controller, &TestPortController::displayMessage, [widgets](QString str, bool inOrOut) {
if (widgets.txtb_dispaly) {
- widgets.txtb_dispaly->moveCursor(QTextCursor::End);
+ widgets.txtb_dispaly->moveCursor(QTextCursor::End);
if (inOrOut) {
- widgets.txtb_dispaly->setTextColor(QColor(127, 255, 0));
+ widgets.txtb_dispaly->setTextColor(QColor(127, 255, 0));
} else {
- widgets.txtb_dispaly->setTextColor(Qt::red);
- }
- widgets.txtb_dispaly->insertPlainText(str);
- widgets.txtb_dispaly->moveCursor(QTextCursor::End);
- }
+ widgets.txtb_dispaly->setTextColor(Qt::red);
+ }
+ widgets.txtb_dispaly->insertPlainText(str);
+ widgets.txtb_dispaly->moveCursor(QTextCursor::End);
+}
});
// 连接结果显示信号
Q_UNUSED(buf);
// 此函数已废弃,数据回显现在由TestPortController处理
if (buf) {
- free(buf);
+ free(buf);
}
}
});
// 保存当前选中的串口(如果有)
- QStringList currentSelections;
- currentSelections << ui->cbox_uart_com_select_1->currentText();
- currentSelections << ui->cbox_uart_com_select_2->currentText();
- currentSelections << ui->cbox_uart_com_select_3->currentText();
- currentSelections << ui->cbox_uart_com_select_4->currentText();
+ QStringList currentDutSelections;
+ currentDutSelections << ui->cbox_uart_com_select_1->currentText();
+ currentDutSelections << ui->cbox_uart_com_select_2->currentText();
+ currentDutSelections << ui->cbox_uart_com_select_3->currentText();
+ currentDutSelections << ui->cbox_uart_com_select_4->currentText();
+
+ QStringList currentRgbSelections;
+ currentRgbSelections << ui->cbox_uart_com_select_rgb1->currentText();
+ currentRgbSelections << ui->cbox_uart_com_select_rgb2->currentText();
+ currentRgbSelections << ui->cbox_uart_com_select_rgb3->currentText();
+ currentRgbSelections << ui->cbox_uart_com_select_rg_4->currentText();
- // 更新所有4个串口选择框
- QComboBox *comboBoxes[] = {
+ // 更新所有4个DUT串口选择框
+ QComboBox *dutComboBoxes[] = {
ui->cbox_uart_com_select_1,
ui->cbox_uart_com_select_2,
ui->cbox_uart_com_select_3,
ui->cbox_uart_com_select_4
};
+ // 更新所有4个RGB串口选择框
+ QComboBox *rgbComboBoxes[] = {
+ ui->cbox_uart_com_select_rgb1,
+ ui->cbox_uart_com_select_rgb2,
+ ui->cbox_uart_com_select_rgb3,
+ ui->cbox_uart_com_select_rg_4
+ };
+
+ // 更新DUT串口选择框
+ for (int i = 0; i < MAX_SERIAL_PORTS; i++) {
+ dutComboBoxes[i]->clear();
+ dutComboBoxes[i]->addItem(tr("None"));
+ dutComboBoxes[i]->addItems(strlist);
+
+ if (!currentDutSelections[i].isEmpty() && currentDutSelections[i] != tr("None")) {
+ int index = dutComboBoxes[i]->findText(currentDutSelections[i]);
+ if (index >= 0) {
+ dutComboBoxes[i]->setCurrentIndex(index);
+ } else {
+ dutComboBoxes[i]->setCurrentIndex(0);
+ }
+ } else {
+ dutComboBoxes[i]->setCurrentIndex(0);
+ }
+ }
+
+ // 更新RGB串口选择框
for (int i = 0; i < MAX_SERIAL_PORTS; i++) {
- comboBoxes[i]->clear();
- // 添加 "None" 作为第一个选项(默认值)
- comboBoxes[i]->addItem(tr("None"));
- // 添加可用串口列表
- comboBoxes[i]->addItems(strlist);
+ rgbComboBoxes[i]->clear();
+ rgbComboBoxes[i]->addItem(tr("None"));
+ rgbComboBoxes[i]->addItems(strlist);
- // 尝试恢复之前的选择(如果仍然存在)
- if (!currentSelections[i].isEmpty() && currentSelections[i] != tr("None")) {
- int index = comboBoxes[i]->findText(currentSelections[i]);
+ if (!currentRgbSelections[i].isEmpty() && currentRgbSelections[i] != tr("None")) {
+ int index = rgbComboBoxes[i]->findText(currentRgbSelections[i]);
if (index >= 0) {
- comboBoxes[i]->setCurrentIndex(index);
+ rgbComboBoxes[i]->setCurrentIndex(index);
} else {
- // 如果之前的串口不存在了,设置为 "None"
- comboBoxes[i]->setCurrentIndex(0);
+ rgbComboBoxes[i]->setCurrentIndex(0);
}
} else {
- // 如果没有之前的选择,设置为 "None"
- comboBoxes[i]->setCurrentIndex(0);
+ rgbComboBoxes[i]->setCurrentIndex(0);
}
}
- qDebug() << tr("已更新所有串口选择框,共找到") << strlist.size() << tr("个可用串口");
+ qDebug() << tr("å·²æ\9b´æ\96°æ\89\80æ\9c\89串å\8f£é\80\89æ\8b©æ¡\86ï¼\88DUTå\92\8cRGBï¼\89ï¼\8cå\85±æ\89¾å\88°") << strlist.size() << tr("个å\8f¯ç\94¨ä¸²å\8f£");
}
void MainWindow::uart_com_switch(QString com)
{
void MainWindow::uart_baud_switch(QString baud)
{
Q_UNUSED(baud);
- QString str_com = ui->cbox_uart_com_select_1->currentText();
+ QString str_com = ui->cbox_uart_com_select_1->currentText();
Q_UNUSED(str_com);
}
// nIndex为索引号 bValue选择返回值为key还是value,默认为value
QMessageBox::information(this, tr("提示"), tr("端口%1未选择串口,请先选择串口").arg(port_index + 1));
return;
}
-
+
+ // 连接DUT串口
controller->connectPort(com_name, baud_rate.toInt());
+
+ // 同时连接RGB串口(如果已选择)
+ // RGB串口固定使用9600波特率,8,n,1
+ if (widgets.cbox_uart_com_select_rgb) {
+ QString rgb_com_name = widgets.cbox_uart_com_select_rgb->currentText();
+ if (!rgb_com_name.isEmpty() && rgb_com_name != tr("None") && rgb_com_name != "None") {
+ controller->connectRgbPort(rgb_com_name, 9600); // RGB串口固定9600波特率
+ }
+ }
} else {
// 停止工作
controller->disconnectPort();
QLabel *label_runtime_status;
QLabel *label_result_success;
QLabel *label_result_fail;
- QComboBox *cbox_uart_com_select; // 串口选择框
+ QComboBox *cbox_uart_com_select; // DUT串口选择框
+ QComboBox *cbox_uart_com_select_rgb; // RGB串口选择框
QPushButton *pbtn_spp_reconnect; // 连接按钮
};
: QObject(parent)\r
, m_port_index(port_index)\r
, m_rgb_serial(new QSerialPort(this))\r
+ , m_query_timer(new QTimer(this))\r
+ , m_last_color_name("")\r
{\r
// 连接串口信号\r
connect(m_rgb_serial, &QSerialPort::readyRead, this, &RgbSerialReader::onReadyRead);\r
connect(m_rgb_serial, QOverload<QSerialPort::SerialPortError>::of(&QSerialPort::error),\r
this, &RgbSerialReader::onError);\r
+ \r
+ // 连接定时器信号(每秒查询一次RGB数据)\r
+ connect(m_query_timer, &QTimer::timeout, this, &RgbSerialReader::sendQueryRgbcCommand);\r
+ m_query_timer->setInterval(1000); // 1秒 = 1000毫秒\r
}\r
\r
RgbSerialReader::~RgbSerialReader()\r
// 清空接收缓冲区\r
m_receive_buffer.clear();\r
\r
+ // 重置颜色名称(重新连接时清空上一次的颜色)\r
+ m_last_color_name = "";\r
+ \r
if (m_rgb_serial->open(QIODevice::ReadWrite)) { // RGB串口需要读写(发送指令)\r
qDebug() << tr("端口%1 RGB串口打开成功").arg(m_port_index + 1);\r
emit connectionStatusChanged(true);\r
QTimer::singleShot(50, this, [this]() {\r
sendSaveLedCommand(); // 保存LED设置\r
QTimer::singleShot(50, this, [this]() {\r
- sendQueryRgbcCommand(); // 查询RGBC数据\r
+ sendQueryRgbcCommand(); // 首次查询RGBC数据\r
+ // 启动定时器,每秒自动查询一次RGB数据\r
+ m_query_timer->start();\r
+ qDebug() << tr("端口%1 RGB串口启动自动查询定时器(每秒一次)").arg(m_port_index + 1);\r
});\r
});\r
});\r
\r
void RgbSerialReader::disconnectPort()\r
{\r
+ // 停止定时器\r
+ if (m_query_timer->isActive()) {\r
+ m_query_timer->stop();\r
+ qDebug() << tr("端口%1 RGB串口停止自动查询定时器").arg(m_port_index + 1);\r
+ }\r
+ \r
if (m_rgb_serial->isOpen()) {\r
qDebug() << tr("端口%1关闭RGB串口").arg(m_port_index + 1);\r
m_rgb_serial->close();\r
\r
// 清空接收缓冲区\r
m_receive_buffer.clear();\r
+ \r
+ // 重置颜色名称\r
+ m_last_color_name = "";\r
}\r
\r
void RgbSerialReader::onReadyRead()\r
quint16 blue = ((quint16)b_high << 8) | b_low;\r
quint16 clear = ((quint16)c_high << 8) | c_low;\r
\r
+ // 检测颜色名称\r
+ QString colorName = detectColorName(red, green, blue, clear);\r
+ \r
// 输出调试信息(包含原始十六进制数据)\r
QString hexFrame = frame.toHex(' ').toUpper();\r
qDebug() << tr("端口%1 RGB串口解析RGBC数据帧: %2").arg(m_port_index + 1).arg(hexFrame);\r
- qDebug() << tr("端口%1 RGB串口RGBC值: R=%2, G=%3, B=%4, C=%5")\r
- .arg(m_port_index + 1).arg(red).arg(green).arg(blue).arg(clear);\r
+ qDebug() << tr("端口%1 RGB串口RGBC值: R=%2, G=%3, B=%4, C=%5, 颜色: %6")\r
+ .arg(m_port_index + 1).arg(red).arg(green).arg(blue).arg(clear).arg(colorName);\r
+ \r
+ // 只有颜色变化时才发送信号更新UI\r
+ if (colorName != m_last_color_name) {\r
+ m_last_color_name = colorName;\r
+ // 发送带颜色名称的信号(只发送颜色名称,不发送RGBC数值)\r
+ emit rgbcDataParsedWithColor(m_port_index, red, green, blue, clear, colorName);\r
+ qDebug() << tr("端口%1 颜色变化: %2").arg(m_port_index + 1).arg(colorName);\r
+ }\r
\r
- // 发送解析后的RGBC数据信号\r
+ // 发送解析后的RGBC数据信号(保持向后兼容,用于其他用途)\r
emit rgbcDataParsed(m_port_index, red, green, blue, clear);\r
}\r
\r
}\r
}\r
\r
+QString RgbSerialReader::detectColorName(quint16 red, quint16 green, quint16 blue, quint16 clear)\r
+{\r
+ // 如果Clear值太低,可能是黑色或没有物体\r
+ if (clear < 50) {\r
+ return tr("黑色/无物体");\r
+ }\r
+ \r
+ // 计算RGB的总和和最大值\r
+ quint32 rgbSum = red + green + blue;\r
+ quint16 maxValue = qMax(qMax(red, green), blue);\r
+ quint16 minValue = qMin(qMin(red, green), blue);\r
+ \r
+ // 如果RGB总和太低,可能是黑色\r
+ if (rgbSum < 100) {\r
+ return tr("黑色");\r
+ }\r
+ \r
+ // 如果RGB值都很高且接近,可能是白色\r
+ if (maxValue > 500 && minValue > maxValue * 0.7) {\r
+ return tr("白色");\r
+ }\r
+ \r
+ // 计算各通道的相对比例\r
+ double rRatio = (double)red / rgbSum;\r
+ double gRatio = (double)green / rgbSum;\r
+ double bRatio = (double)blue / rgbSum;\r
+ \r
+ // 判断主要颜色通道\r
+ quint16 diff = maxValue - minValue;\r
+ \r
+ // 如果差异太小,可能是灰色\r
+ if (diff < maxValue * 0.2) {\r
+ if (maxValue > 300) {\r
+ return tr("浅灰色");\r
+ } else {\r
+ return tr("深灰色");\r
+ }\r
+ }\r
+ \r
+ // 根据主要通道判断颜色\r
+ if (red == maxValue) {\r
+ // 红色为主\r
+ if (green > maxValue * 0.6) {\r
+ if (blue < maxValue * 0.3) {\r
+ return tr("黄色");\r
+ } else {\r
+ return tr("橙色");\r
+ }\r
+ } else if (green > maxValue * 0.4) {\r
+ return tr("橙红色");\r
+ } else {\r
+ return tr("红色");\r
+ }\r
+ } else if (green == maxValue) {\r
+ // 绿色为主\r
+ if (red > maxValue * 0.6) {\r
+ if (blue < maxValue * 0.3) {\r
+ return tr("黄绿色");\r
+ } else {\r
+ return tr("青绿色");\r
+ }\r
+ } else if (blue > maxValue * 0.5) {\r
+ return tr("青色");\r
+ } else {\r
+ return tr("绿色");\r
+ }\r
+ } else {\r
+ // 蓝色为主\r
+ if (red > maxValue * 0.5 && green > maxValue * 0.5) {\r
+ return tr("青色");\r
+ } else if (red > maxValue * 0.4) {\r
+ return tr("紫色");\r
+ } else {\r
+ return tr("蓝色");\r
+ }\r
+ }\r
+}\r
+\r
\r
#include <QObject>\r
#include <QSerialPort>\r
+#include <QTimer>\r
#include <QByteArray>\r
#include <QString>\r
\r
\r
// RGBC数据解析信号(当Byte2=0x15时)\r
void rgbcDataParsed(int port_index, quint16 red, quint16 green, quint16 blue, quint16 clear); // 解析后的RGBC数据\r
+ void rgbcDataParsedWithColor(int port_index, quint16 red, quint16 green, quint16 blue, quint16 clear, const QString& colorName); // 解析后的RGBC数据(带颜色名称)\r
\r
// 状态信号\r
void connectionStatusChanged(bool connected); // 连接状态变化\r
\r
// 串口对象\r
QSerialPort *m_rgb_serial;\r
+ \r
+ // 定时器(用于每秒查询一次RGB数据)\r
+ QTimer *m_query_timer;\r
\r
// 数据缓冲区(用于处理分包数据)\r
QByteArray m_receive_buffer;\r
// 最大缓冲区大小(防止内存溢出)\r
static const int MAX_BUFFER_SIZE = 32768; // 32KB\r
\r
+ // 上一次检测到的颜色名称(用于判断颜色是否变化)\r
+ QString m_last_color_name;\r
+ \r
// 数据解析函数\r
void parseRgbcData(const QByteArray& data); // 解析RGBC数据(查找Byte2=0x15的数据包)\r
bool findRgbcFrame(const QByteArray& buffer, int& startPos, int& endPos); // 查找完整的RGBC数据帧\r
+ QString detectColorName(quint16 red, quint16 green, quint16 blue, quint16 clear); // 根据RGB值判断颜色名称\r
};\r
\r
#endif // RGB_SERIAL_READER_H\r
#include "test_port_controller.h"
+#include "rgb_serial_reader.h"
#include "settings.h"
#include <QRegExp>
#include <QDebug>
: QObject(parent)
, m_port_index(port_index)
, m_dut_serial(new QSerialPort(this))
- , m_rgb_serial(new QSerialPort(this))
+ , m_rgb_serial(new QSerialPort(this)) // 保留用于向后兼容
+ , m_rgb_reader(new RgbSerialReader(port_index, this))
, m_spp_timer_handle(new QTimer(this))
, m_result_thread(new Result_Thread(nullptr, port_index + 1))
, m_bytesToWrite(0)
// 连接定时器信号
connect(m_spp_timer_handle, &QTimer::timeout, this, &TestPortController::onTimerTimeout);
- // 连接串口信号
+ // 连接DUT串口信号
connect(m_dut_serial, &QSerialPort::readyRead, this, &TestPortController::onReadyRead);
connect(m_dut_serial, &QSerialPort::bytesWritten, this, &TestPortController::onBytesWritten);
+ // 连接RGB串口读取器信号
+ connect(m_rgb_reader, &RgbSerialReader::dataReceived, this, [this](const QByteArray& data) {
+ // RGB串口接收到原始数据(用于调试)
+ QString hexData = data.toHex(' ').toUpper();
+ qDebug() << tr("端口%1 RGB串口接收到数据,长度:%2, 内容: %3")
+ .arg(m_port_index + 1).arg(data.length()).arg(hexData);
+ });
+
+ // 连接RGBC数据解析信号(带颜色名称)
+ connect(m_rgb_reader, &RgbSerialReader::rgbcDataParsedWithColor, this,
+ [this](int port_index, quint16 red, quint16 green, quint16 blue, quint16 clear, const QString& colorName) {
+ // 只显示颜色名称(颜色变化时才更新)
+ QString colorInfo = tr("颜色: %1\r\n").arg(colorName);
+ emit displayMessage(colorInfo, true);
+ qDebug() << tr("端口%1 检测到颜色: %2").arg(m_port_index + 1).arg(colorName);
+ });
+
+ connect(m_rgb_reader, &RgbSerialReader::errorOccurred, this, [this](const QString& error) {
+ qDebug() << tr("端口%1 RGB串口错误:").arg(m_port_index + 1) << error;
+ emit displayMessage(tr("RGB串口错误: ") + error + tr("\r\n"), false);
+ });
+
// 启动结果线程
m_result_thread->start();
m_result_thread->pause();
if (m_dut_serial->isOpen()) {
m_dut_serial->close();
}
+
+ // 同时断开RGB串口
+ disconnectRgbPort();
+}
+
+void TestPortController::connectRgbPort(const QString& rgb_com_name, int baud_rate)
+{
+ if (m_rgb_reader) {
+ m_rgb_reader->connectPort(rgb_com_name, baud_rate);
+ }
+}
+
+void TestPortController::disconnectRgbPort()
+{
+ if (m_rgb_reader) {
+ m_rgb_reader->disconnectPort();
+ }
}
void TestPortController::poweroffWatch()
class QSerialPort;
class QTimer;
class Result_Thread;
+class RgbSerialReader;
// 测试端口控制器类 - 封装每个测试端口的所有变量和函数
class TestPortController : public QObject
// 串口对象访问
QSerialPort* dutSerial() const { return m_dut_serial; }
QSerialPort* rgbSerial() const { return m_rgb_serial; }
+ RgbSerialReader* rgbReader() const { return m_rgb_reader; }
// 状态访问
bool isWorking() const { return m_working_state; }
// 公共接口函数
void connectPort(const QString& com_name, int baud_rate);
+ void connectRgbPort(const QString& rgb_com_name, int baud_rate); // 连接RGB串口
void disconnectPort();
+ void disconnectRgbPort(); // 断开RGB串口
void poweroffWatch();
void setMacAddress(const QString& mac);
// 串口对象
QSerialPort *m_dut_serial;
- QSerialPort *m_rgb_serial;
+ QSerialPort *m_rgb_serial; // 保留用于向后兼容,实际使用m_rgb_reader
+
+ // RGB串口读取器
+ RgbSerialReader *m_rgb_reader;
// 定时器
QTimer *m_spp_timer_handle;