From: SnickerSun Date: Fri, 28 Nov 2025 12:43:53 +0000 (+0800) Subject: 添加M1产测设计稿 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=6531b002fe4d977c10f3a48db862380c0ae83a9a;p=mirrors%2Ffactory_tool.git 添加M1产测设计稿 --- diff --git "a/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/GY-33\344\275\277\347\224\250\350\257\264\346\230\216v2.pdf" "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/GY-33\344\275\277\347\224\250\350\257\264\346\230\216v2.pdf" new file mode 100644 index 0000000..db24696 Binary files /dev/null and "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/GY-33\344\275\277\347\224\250\350\257\264\346\230\216v2.pdf" differ diff --git "a/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/M1 pin\345\256\232\344\271\211.xlsx" "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/M1 pin\345\256\232\344\271\211.xlsx" new file mode 100644 index 0000000..ed106c5 Binary files /dev/null and "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/M1 pin\345\256\232\344\271\211.xlsx" differ diff --git "a/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/M1\346\265\213\350\257\225\346\226\271\346\241\210.ppt" "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/M1\346\265\213\350\257\225\346\226\271\346\241\210.ppt" new file mode 100644 index 0000000..4b23aee Binary files /dev/null and "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/M1\346\265\213\350\257\225\346\226\271\346\241\210.ppt" differ diff --git "a/docs/m1_\344\272\247\346\265\213\346\227\245\345\277\227.txt" "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/m1_\344\272\247\346\265\213\346\227\245\345\277\227.txt" similarity index 100% rename from "docs/m1_\344\272\247\346\265\213\346\227\245\345\277\227.txt" rename to "docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/m1_\344\272\247\346\265\213\346\227\245\345\277\227.txt" diff --git "a/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/pin\350\204\232\345\233\276.png" "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/pin\350\204\232\345\233\276.png" new file mode 100644 index 0000000..dd06cb1 Binary files /dev/null and "b/docs/m1\344\272\247\346\265\213\350\256\276\350\256\241/pin\350\204\232\345\233\276.png" differ diff --git a/rgb_serial_reader.cpp b/rgb_serial_reader.cpp new file mode 100644 index 0000000..9a8cdfc --- /dev/null +++ b/rgb_serial_reader.cpp @@ -0,0 +1,311 @@ +#include "rgb_serial_reader.h" +#include +#include +#include +#include +#include + +RgbSerialReader::RgbSerialReader(int port_index, QObject *parent) + : QObject(parent) + , m_port_index(port_index) + , m_rgb_serial(new QSerialPort(this)) +{ + // 连接串口信号 + connect(m_rgb_serial, &QSerialPort::readyRead, this, &RgbSerialReader::onReadyRead); + connect(m_rgb_serial, QOverload::of(&QSerialPort::error), + this, &RgbSerialReader::onError); +} + +RgbSerialReader::~RgbSerialReader() +{ + disconnectPort(); +} + +void RgbSerialReader::connectPort(const QString& com_name, int baud_rate) +{ + if (m_rgb_serial->isOpen()) { + qDebug() << tr("端口%1 RGB串口已经打开,先关闭").arg(m_port_index + 1); + m_rgb_serial->close(); + } + + // 检查是否选择了 "None" + if (com_name.isEmpty() || com_name == tr("None") || com_name == "None") { + qDebug() << tr("端口%1未选择RGB串口(选择了None),跳过打开串口操作").arg(m_port_index + 1); + emit connectionStatusChanged(false); + return; + } + + qDebug() << tr("=== 开始连接RGB串口%1 ===").arg(m_port_index + 1); + qDebug() << tr("RGB串口名称:") << com_name; + qDebug() << tr("波特率:") << baud_rate; + + m_rgb_serial->setPortName(com_name); + m_rgb_serial->setBaudRate(baud_rate); + m_rgb_serial->setDataBits(QSerialPort::Data8); + m_rgb_serial->setParity(QSerialPort::NoParity); + m_rgb_serial->setStopBits(QSerialPort::OneStop); + m_rgb_serial->setFlowControl(QSerialPort::NoFlowControl); + m_rgb_serial->setReadBufferSize(MAX_BUFFER_SIZE); + + // 清空接收缓冲区 + m_receive_buffer.clear(); + + if (m_rgb_serial->open(QIODevice::ReadWrite)) { // RGB串口需要读写(发送指令) + qDebug() << tr("端口%1 RGB串口打开成功").arg(m_port_index + 1); + emit connectionStatusChanged(true); + + // 连接成功后自动发送初始化指令 + QTimer::singleShot(100, this, [this]() { + sendCloseLedCommand(); // 关闭LED + QTimer::singleShot(50, this, [this]() { + sendSaveLedCommand(); // 保存LED设置 + QTimer::singleShot(50, this, [this]() { + sendQueryRgbcCommand(); // 查询RGBC数据 + }); + }); + }); + } else { + QString errorMsg = tr("端口%1 RGB串口打开失败: %2").arg(m_port_index + 1).arg(m_rgb_serial->errorString()); + qDebug() << errorMsg; + emit errorOccurred(errorMsg); + emit connectionStatusChanged(false); + } +} + +void RgbSerialReader::disconnectPort() +{ + if (m_rgb_serial->isOpen()) { + qDebug() << tr("端口%1关闭RGB串口").arg(m_port_index + 1); + m_rgb_serial->close(); + emit connectionStatusChanged(false); + } + + // 清空接收缓冲区 + m_receive_buffer.clear(); +} + +void RgbSerialReader::onReadyRead() +{ + const QByteArray data = m_rgb_serial->readAll(); + + if (data.isEmpty()) { + return; + } + + // 将新数据添加到缓冲区 + m_receive_buffer.append(data); + + // 保持缓冲区大小合理,避免内存溢出 + if (m_receive_buffer.length() > MAX_BUFFER_SIZE) { + // 保留最近的数据 + m_receive_buffer = m_receive_buffer.right(MAX_BUFFER_SIZE); + qDebug() << tr("端口%1 RGB串口缓冲区过大,保留最近%2字节").arg(m_port_index + 1).arg(MAX_BUFFER_SIZE); + } + + // 发送原始数据信号(仅发送新接收的数据) + emit dataReceived(data); + emit rgbDataReceived(m_port_index, data); + + // 解析RGBC数据(从整个缓冲区中查找Byte2=0x15的数据包) + parseRgbcData(m_receive_buffer); +} + +void RgbSerialReader::onError(QSerialPort::SerialPortError error) +{ + if (error == QSerialPort::NoError) { + return; + } + + QString errorMsg; + switch (error) { + case QSerialPort::DeviceNotFoundError: + errorMsg = tr("端口%1 RGB串口设备未找到").arg(m_port_index + 1); + break; + case QSerialPort::PermissionError: + errorMsg = tr("端口%1 RGB串口权限错误").arg(m_port_index + 1); + break; + case QSerialPort::OpenError: + errorMsg = tr("端口%1 RGB串口打开错误").arg(m_port_index + 1); + break; + case QSerialPort::WriteError: + errorMsg = tr("端口%1 RGB串口写入错误").arg(m_port_index + 1); + break; + case QSerialPort::ReadError: + errorMsg = tr("端口%1 RGB串口读取错误").arg(m_port_index + 1); + break; + case QSerialPort::ResourceError: + errorMsg = tr("端口%1 RGB串口资源错误(设备可能已断开)").arg(m_port_index + 1); + break; + case QSerialPort::UnsupportedOperationError: + errorMsg = tr("端口%1 RGB串口不支持的操作").arg(m_port_index + 1); + break; + case QSerialPort::TimeoutError: + errorMsg = tr("端口%1 RGB串口超时错误").arg(m_port_index + 1); + break; + default: + errorMsg = tr("端口%1 RGB串口未知错误: %2").arg(m_port_index + 1).arg(error); + break; + } + + qDebug() << errorMsg; + emit errorOccurred(errorMsg); + + // 如果是资源错误,自动断开连接 + if (error == QSerialPort::ResourceError) { + disconnectPort(); + } +} + +void RgbSerialReader::sendCloseLedCommand() +{ + if (!m_rgb_serial || !m_rgb_serial->isOpen()) { + return; + } + + // 关闭LED指令: A5 6A 0F + QByteArray cmd; + cmd.append((char)0xA5); + cmd.append((char)0x6A); + cmd.append((char)0x0F); + + qint64 bytesWritten = m_rgb_serial->write(cmd); + if (bytesWritten == cmd.size()) { + qDebug() << tr("端口%1 RGB串口发送关闭LED指令成功").arg(m_port_index + 1); + } else { + qDebug() << tr("端口%1 RGB串口发送关闭LED指令失败").arg(m_port_index + 1); + } +} + +void RgbSerialReader::sendSaveLedCommand() +{ + if (!m_rgb_serial || !m_rgb_serial->isOpen()) { + return; + } + + // 保存LED亮度设置指令: A5 CC 71 + QByteArray cmd; + cmd.append((char)0xA5); + cmd.append((char)0xCC); + cmd.append((char)0x71); + + qint64 bytesWritten = m_rgb_serial->write(cmd); + if (bytesWritten == cmd.size()) { + qDebug() << tr("端口%1 RGB串口发送保存LED设置指令成功").arg(m_port_index + 1); + } else { + qDebug() << tr("端口%1 RGB串口发送保存LED设置指令失败").arg(m_port_index + 1); + } +} + +void RgbSerialReader::sendQueryRgbcCommand() +{ + if (!m_rgb_serial || !m_rgb_serial->isOpen()) { + return; + } + + // 查询RGBC原始AD值指令: A5 51 F6 + QByteArray cmd; + cmd.append((char)0xA5); + cmd.append((char)0x51); + cmd.append((char)0xF6); + + qint64 bytesWritten = m_rgb_serial->write(cmd); + if (bytesWritten == cmd.size()) { + qDebug() << tr("端口%1 RGB串口发送查询RGBC指令成功").arg(m_port_index + 1); + } else { + qDebug() << tr("端口%1 RGB串口发送查询RGBC指令失败").arg(m_port_index + 1); + } +} + +bool RgbSerialReader::findRgbcFrame(const QByteArray& buffer, int& startPos, int& endPos) +{ + // 查找数据帧:5A 5A 15 XX ... (Byte2=0x15) + // 帧头:5A 5A + // Byte2: 0x15 (RGBC数据类型) + // Byte3: 数据长度(不包括帧头、Byte2和长度本身) + + startPos = -1; + endPos = -1; + + // 查找帧头 5A 5A,至少需要4个字节才能判断 + for (int i = 0; i <= buffer.size() - 4; i++) { + if ((quint8)buffer[i] == 0x5A && (quint8)buffer[i + 1] == 0x5A) { + // 检查Byte2是否为0x15 + if ((quint8)buffer[i + 2] == 0x15) { + // 获取数据长度(Byte3) + quint8 dataLength = (quint8)buffer[i + 3]; + // 完整帧长度 = 帧头(2) + Byte2(1) + 长度(1) + 数据(dataLength) = 4 + dataLength + int frameLength = 4 + dataLength; + + // 检查是否有足够的数据 + if (i + frameLength <= buffer.size()) { + startPos = i; + endPos = i + frameLength; + return true; + } else { + // 数据不完整,等待更多数据 + break; + } + } + } + } + + return false; +} + +void RgbSerialReader::parseRgbcData(const QByteArray& buffer) +{ + int startPos, endPos; + + // 查找所有完整的RGBC数据帧(Byte2=0x15) + // 注意:这里使用局部变量buffer,实际修改的是成员变量m_receive_buffer + QByteArray tempBuffer = buffer; + + while (findRgbcFrame(tempBuffer, startPos, endPos)) { + if (startPos >= 0 && endPos > startPos && endPos <= tempBuffer.size()) { + // 提取完整的数据帧 + QByteArray frame = tempBuffer.mid(startPos, endPos - startPos); + + // 验证帧格式:5A 5A 15 XX [数据] + // 至少需要12字节:帧头(2) + Byte2(1) + 长度(1) + RGBC数据(8) = 12 + if (frame.size() >= 12) { + // 解析RGBC数据 + // 帧格式:5A 5A 15 08 R_H R_L G_H G_L B_H B_L C_H C_L ... + // 索引: 0 1 2 3 4 5 6 7 8 9 10 11 + + // 提取RGBC数据(每个值2字节,高字节在前) + quint8 r_high = (quint8)frame[4]; + quint8 r_low = (quint8)frame[5]; + quint8 g_high = (quint8)frame[6]; + quint8 g_low = (quint8)frame[7]; + quint8 b_high = (quint8)frame[8]; + quint8 b_low = (quint8)frame[9]; + quint8 c_high = (quint8)frame[10]; + quint8 c_low = (quint8)frame[11]; + + // 计算RGBC值:高8位左移8位后与低8位或运算 + quint16 red = ((quint16)r_high << 8) | r_low; + quint16 green = ((quint16)g_high << 8) | g_low; + quint16 blue = ((quint16)b_high << 8) | b_low; + quint16 clear = ((quint16)c_high << 8) | c_low; + + // 输出调试信息(包含原始十六进制数据) + QString hexFrame = frame.toHex(' ').toUpper(); + qDebug() << tr("端口%1 RGB串口解析RGBC数据帧: %2").arg(m_port_index + 1).arg(hexFrame); + qDebug() << tr("端口%1 RGB串口RGBC值: R=%2, G=%3, B=%4, C=%5") + .arg(m_port_index + 1).arg(red).arg(green).arg(blue).arg(clear); + + // 发送解析后的RGBC数据信号 + emit rgbcDataParsed(m_port_index, red, green, blue, clear); + } + + // 从临时缓冲区中移除已处理的数据帧,继续查找 + tempBuffer.remove(startPos, endPos - startPos); + + // 同时从成员变量缓冲区中移除已处理的数据帧 + m_receive_buffer.remove(startPos, endPos - startPos); + } else { + break; + } + } +} + diff --git a/rgb_serial_reader.h b/rgb_serial_reader.h new file mode 100644 index 0000000..f294cab --- /dev/null +++ b/rgb_serial_reader.h @@ -0,0 +1,70 @@ +#ifndef RGB_SERIAL_READER_H +#define RGB_SERIAL_READER_H + +#include +#include +#include +#include + +// RGB串口读取器类 - 专门处理RGB串口的数据读取 +class RgbSerialReader : public QObject +{ + Q_OBJECT + +public: + explicit RgbSerialReader(int port_index, QObject *parent = nullptr); + ~RgbSerialReader(); + + // 端口索引 (0-3) + int portIndex() const { return m_port_index; } + + // 串口对象访问 + QSerialPort* serialPort() const { return m_rgb_serial; } + + // 公共接口函数 + void connectPort(const QString& com_name, int baud_rate); + void disconnectPort(); + bool isConnected() const { return m_rgb_serial && m_rgb_serial->isOpen(); } + + // RGB传感器控制指令 + void sendCloseLedCommand(); // 关闭LED指令: A5 6A 0F + void sendSaveLedCommand(); // 保存LED亮度设置: A5 CC 71 + void sendQueryRgbcCommand(); // 查询RGBC原始AD值: A5 51 F6 + +signals: + // 数据接收信号 + void dataReceived(const QByteArray& data); // 接收到原始数据 + void textReceived(const QString& text); // 接收到文本数据 + void rgbDataReceived(int port_index, const QByteArray& data); // 带端口索引的数据信号 + + // RGBC数据解析信号(当Byte2=0x15时) + void rgbcDataParsed(int port_index, quint16 red, quint16 green, quint16 blue, quint16 clear); // 解析后的RGBC数据 + + // 状态信号 + void connectionStatusChanged(bool connected); // 连接状态变化 + void errorOccurred(const QString& error); // 错误信号 + +private slots: + void onReadyRead(); // 串口数据就绪 + void onError(QSerialPort::SerialPortError error); // 串口错误处理 + +private: + // 端口索引 (0-3) + int m_port_index; + + // 串口对象 + QSerialPort *m_rgb_serial; + + // 数据缓冲区(用于处理分包数据) + QByteArray m_receive_buffer; + + // 最大缓冲区大小(防止内存溢出) + static const int MAX_BUFFER_SIZE = 32768; // 32KB + + // 数据解析函数 + void parseRgbcData(const QByteArray& data); // 解析RGBC数据(查找Byte2=0x15的数据包) + bool findRgbcFrame(const QByteArray& buffer, int& startPos, int& endPos); // 查找完整的RGBC数据帧 +}; + +#endif // RGB_SERIAL_READER_H +