QT嵌入式温湿度系统:串口帧协议与线程安全UI实战
简介本资源是一个基于物联网实验环境的温湿度实时监测与可视化系统面向嵌入式开发初学者、物联网课程实践者及Qt GUI编程学习者解决传感器数据采集、串口通信解析与跨平台界面动态展示的一体化实践问题。项目采用C结合Qt框架开发主程序通过串口UART实时读取DHT系列温湿度传感器数据并在图形界面中刷新显示完整覆盖感知层传感器、通信层串口驱动、处理层数据解析与应用层UI交互四层物联网架构。压缩包共23个文件含7个cpp源码与5个h头文件构成核心逻辑1个ui文件定义界面布局1个pro工程配置以及qextserialbase等串口扩展组件整体578KB轻量易学。已有1956人学习下载提供可直接编译运行的完整工程结构、带注释的关键模块如serialservice.h、temphum.cpp、背景图与资源文件qrc适合快速上手、理解Qt信号槽机制与嵌入式数据流闭环设计。1. 基于物联网实验环境的温湿度实时显示系统不是Demo是能接真实传感器、跑满72小时不掉线的嵌入式QT界面工程你手头有一块ESP32开发板连着DHT22串口吐着“temp:23.4,hum:56.1”你打开QT Creator新建一个Widget项目拖个Label进去写两行QSerialPort读取——结果数据跳变、界面卡死、串口缓冲区溢出、重启三次后发现QTimer精度根本撑不住100ms级刷新。这不是QT学不会是缺一套从硬件协议解析到UI线程安全更新的闭环链路。这个资源包就是为这类场景打磨出来的它不教你怎么安装QT而是直接给你一个已配置好交叉编译链arm-linux-gnueabihf、内置串口帧同步校验、支持断线自动重连、UI每秒刷新但CPU占用压在8%以下的完整工程。适合正在做课程设计、毕业设计或工业实训平台搭建的开发者——尤其当你被导师问“数据丢没丢界面卡不卡掉线后怎么恢复”时能立刻拿出可演示、可调试、可改参数的实物代码。2. 硬件通信层为什么必须用自定义帧协议而不是裸串口读取2.1 DHT22原始数据不可靠必须加帧头校验超时重发机制DHT22单次测量耗时约80ms输出的是40位二进制脉冲经MCU转换成ASCII字符串后常见格式为T:23.4,H:56.1\n。但实测中串口线受干扰、MCU供电波动、USB转串口芯片缓存溢出会导致字符粘连T:23.4,H:56.1\nT:23.5,H:56.0\n变成T:23.4,H:56.1\nT:23.5,H:56.0缺少换行数据截断只收到T:23.4,H:5乱码T:23.4,H:56.1\x00\xFF\xAA裸用QSerialPort::readAll()会把上述所有情况当有效数据喂给解析函数最终UI显示T:23.4,H:5或直接崩溃。本工程强制采用三段式帧结构[0xAA][0x55][TEMP_H][TEMP_L][HUM_H][HUM_L][CHKSUM][0xCC]其中CHKSUM (TEMP_H TEMP_L HUM_H HUM_L) 0xFF帧头0xAA55防误触发帧尾0xCC防粘包。MCU端ESP32固件已预编译好QT端解析逻辑在SensorFrameParser.cpp中实现非正则、非字符串分割而是字节流状态机驱动。2.2 QT串口配置必须关闭流控、禁用回显、设置精确超时很多初学者直接复制网上示例用默认构造函数创建QSerialPort结果在Linux ARM板上频繁丢帧。本工程SerialManager.cpp中关键配置如下// bash // 先确认设备权限sudo usermod -a -G dialout $USER重启生效 // 再检查波特率是否被内核限制stty -F /dev/ttyUSB0// cpp serial-setPortName(/dev/ttyUSB0); serial-setBaudRate(QSerialPort::Baud9600); // 必须与MCU固件一致DHT22常用9600 serial-setDataBits(QSerialPort::Data8); serial-setParity(QSerialPort::NoParity); serial-setStopBits(QSerialPort::OneStop); serial-setFlowControl(QSerialPort::NoFlowControl); // ⚠️ 关键RTS/CTS流控在嵌入式串口上极易导致阻塞 serial-setReadBufferSize(1024); // 避免内核缓冲区溢出丢帧 if (!serial-open(QIODevice::ReadWrite)) { qWarning() Failed to open serial port: serial-errorString(); return false; } // 设置读超时为100ms避免read()无限等待 serial-setReadTimeout(100);提示setReadTimeout(100)不是“每100ms读一次”而是read()调用后若100ms内无数据到达就返回空需配合循环轮询。本工程用QTimer::singleShot(50, this, SerialManager::tryReadFrame)实现非阻塞读取比readyRead()信号更可控——因为readyRead在数据未组帧完成时就触发易读到半帧。2.3 帧解析状态机拒绝字符串操作全程uint8_t指针移动SensorFrameParser.h定义了enum FrameState { IDLE, HEADER1, HEADER2, PAYLOAD, CHKSUM, FOOTER }parseByte(uint8_t byte)函数逐字节推进状态。关键逻辑void SensorFrameParser::parseByte(uint8_t byte) { switch (state) { case IDLE: if (byte 0xAA) state HEADER1; break; case HEADER1: if (byte 0x55) state HEADER2; else state IDLE; // 错误帧头重置 break; case HEADER2: payload[0] byte; // TEMP_H state PAYLOAD; payloadIndex 1; break; case PAYLOAD: if (payloadIndex 4) { payload[payloadIndex] byte; } else if (payloadIndex 4) { checksum byte; state CHKSUM; } break; case CHKSUM: if (byte 0xCC verifyChecksum()) { emit frameReady(payload[0], payload[1], payload[2], payload[3]); } state IDLE; break; } }参数说明payload[0]是温度高字节整数部分payload[1]是温度低字节小数部分×10payload[2]湿度高字节payload[3]湿度低字节。例如payload{0x17,0x06,0x38,0x0A}→ temp0x170623.06℃hum0x380A56.10%。这种二进制编码比ASCII字符串节省50%带宽且无解析歧义。3. QT UI线程安全更新为什么QTimer定时器不能直接更新QLabel3.1 主线程UI与串口读取必须分离否则必卡死QT官方文档强调“所有QWidget操作必须在主线程执行”。但初学者常犯错误在SerialManager::tryReadFrame()里直接调用ui-tempLabel-setText(...)。问题在于tryReadFrame()运行在串口读取线程本工程中为QThread子类SerialWorkerQLabel::setText()内部触发paintEvent需GUI线程事件循环跨线程调用导致QObject: Cannot create children for a parent that is in a different thread警告严重时程序abort本工程采用信号-槽跨线程连接且强制使用Qt::QueuedConnection// SerialWorker.h 中声明信号 signals: void sensorDataReceived(float temp, float hum, qint64 timestamp); // MainWindow.cpp 中连接在构造函数中 connect(serialWorker, SerialWorker::sensorDataReceived, this, MainWindow::updateDisplay, Qt::QueuedConnection); // ⚠️ 必须显式指定否则默认AutoConnection在同线程时变DirectConnection仍会崩溃3.2 updateDisplay()函数必须做数据有效性过滤和刷新节流即使信号正确投递若MCU每100ms发一帧updateDisplay()每秒被调用10次QLabel::setText()高频触发重绘ARM平台GPU负载飙升。本工程加入两级过滤void MainWindow::updateDisplay(float temp, float hum, qint64 timestamp) { // 过滤无效值DHT22正常范围 -20~80℃, 0~100%RH if (temp -20.0f || temp 80.0f || hum 0.0f || hum 100.0f) { qWarning() Invalid sensor data filtered: temp hum; return; } // 节流仅当变化超过阈值或超时才刷新UI static float lastTemp 0.0f, lastHum 0.0f; static qint64 lastUpdate 0; const qint64 now QDateTime::currentMSecsSinceEpoch(); if (qAbs(temp - lastTemp) 0.3f || qAbs(hum - lastHum) 0.5f || (now - lastUpdate) 2000) { ui-tempLabel-setText(QString::number(temp, f, 1) ℃); ui-humLabel-setText(QString::number(hum, f, 1) %RH); ui-timeLabel-setText(QDateTime::currentDateTime().toString(hh:mm:ss)); lastTemp temp; lastHum hum; lastUpdate now; } }参数说明qAbs(temp - lastTemp) 0.3f防止温度微小抖动如23.41→23.42引发无意义刷新(now - lastUpdate) 2000保证即使传感器静止UI时间戳每2秒强制更新避免用户误判系统挂起。3.3 历史曲线绘制QCustomPlot轻量替代方案本工程未引入QChart依赖Qt5.15且ARM编译臃肿而采用QCustomPlot 2.1.1头文件仅qcustomplot.h/.cpp。HistoryChart.cpp中关键配置// 初始化曲线 ui-customPlot-addGraph(); ui-customPlot-graph(0)-setPen(QPen(Qt::blue, 2)); ui-customPlot-xAxis-setRange(0, 300); // X轴显示最近300秒 ui-customPlot-yAxis-setRange(0, 100); // Y轴0~100%RH ui-customPlot-xAxis-setLabel(Time (s)); ui-customPlot-yAxis-setLabel(Humidity (%)); // 每次updateDisplay中追加数据 QVectordouble x ui-customPlot-graph(0)-data()-keys(); QVectordouble y ui-customPlot-graph(0)-data()-values(); if (x.size() 300) { x.remove(0); y.remove(0); } x.append((double)(QDateTime::currentMSecsSinceEpoch() - startTime) / 1000.0); y.append(hum); ui-customPlot-graph(0)-setData(x, y); ui-customPlot-replot(); // ⚠️ replot()必须在主线程调用本函数已在主线程注意replot()是重绘核心但若每秒调用10次ARM Mali GPU会过热降频。本工程将曲线刷新与UI文本刷新解耦——文本每2秒或变化大时更新曲线固定每5秒replot()一次通过QTimer::singleShot(5000, this, MainWindow::updateChart)控制。4. 断线重连与异常恢复为什么你的系统总在插拔USB后彻底失联4.1 Linux下USB串口设备名动态变化必须用udev规则固化在树莓派或ARM开发板上/dev/ttyUSB0可能因插入顺序变为/dev/ttyUSB1甚至/dev/ttyACM0。本工程提供99-iot-sensor.rulesudev规则# /etc/udev/rules.d/99-iot-sensor.rules SUBSYSTEMtty, ATTRS{idVendor}10c4, ATTRS{idProduct}ea60, SYMLINKiot_sensor # CP2102芯片常见VID:PID为10c4:ea60实际请用lsusb -v确认执行sudo udevadm control --reload-rules sudo udevadm trigger后设备恒为/dev/iot_sensorQT中直接写死serial-setPortName(/dev/iot_sensor); // 不再用/dev/ttyUSB0提示ATTRS{idVendor}和ATTRS{idProduct}需根据你的USB转串口芯片型号调整。常见芯片对应关系CP2102→10c4:ea60CH340→1a86:7523FTDI→0403:6001。用lsusb命令查看。4.2 串口异常检测不止监听error()信号还要主动心跳探测QSerialPort::error()信号只在底层驱动报错时触发如设备拔出但无法捕获MCU死机、线缆松动等“静默故障”。本工程增加应用层心跳机制MCU固件每5秒发送一次心跳帧[0xAA][0x55][0x00][0x00][0x00][0x00][0x00][0xCC]全零payloadQT端SerialManager维护lastHeartbeatTime若QDateTime::currentMSecsSinceEpoch() - lastHeartbeatTime 8000则判定为通信中断void SerialManager::onHeartbeatReceived() { lastHeartbeatTime QDateTime::currentMSecsSinceEpoch(); if (isReconnecting) { isReconnecting false; emit connectionRestored(); } } void SerialManager::checkConnection() { const qint64 now QDateTime::currentMSecsSinceEpoch(); if (now - lastHeartbeatTime 8000) { if (!isReconnecting) { isReconnecting true; emit connectionLost(); // 启动重连定时器 reconnectTimer-start(3000); // 3秒后尝试重连 } } }4.3 自动重连策略指数退避 设备存在性验证盲目serial-close(); serial-open()会导致Resource busy错误。本工程重连流程先用QFile::exists(/dev/iot_sensor)确认设备节点存在若存在调用serial-close()后延时200ms让内核释放资源再serial-open()失败则等待2^retryCount * 1000ms首次1s第二次2s第三次4s…最多重试5次失败后弹出系统托盘通知void SerialManager::attemptReconnect() { if (QFile::exists(/dev/iot_sensor)) { serial-close(); QThread::msleep(200); // ⚠️ 关键延时否则open()立即失败 if (serial-open(QIODevice::ReadWrite)) { qDebug() Reconnected successfully; emit connectionRestored(); } else { retryCount; const int delay qMin(32000, (1 retryCount) * 1000); // 封顶32秒 reconnectTimer-start(delay); } } else { // 设备未插入等待下次检测 reconnectTimer-start(2000); } }血泪经验某次调试中MCU固件bug导致心跳帧发送间隔忽长忽短QT端未做超时重置lastHeartbeatTime始终被更新系统永远认为“在线”。后来在onHeartbeatReceived()中加入if (payloadIsAllZero)判断只对真正的心跳帧更新时间戳杜绝伪在线。5. 避坑五个真实翻车现场与当场解决方案5.1 现象QT界面显示温度为“-127.0℃”湿度为“0.0%RH”且持续不变原因DHT22传感器未供电或数据线接触不良MCU读取失败后返回默认值0x8000-128的补码QT端未做有效性校验直接显示。解决在SensorFrameParser::verifyChecksum()后增加原始值检查if (payload[0] 0x80 payload[1] 0x00) return false; // DHT22错误码 if (payload[2] 0x00 payload[3] 0x00) return false; // 湿度0值异常5.2 现象ARM板上程序启动后串口灯常亮但QT无任何数据显示dmesg | grep tty显示usb 1-1.2: cp210x converter now attached to ttyUSB0原因udev规则未生效QT仍在尝试打开/dev/ttyUSB0但该设备节点被其他进程如ModemManager占用。解决sudo systemctl stop ModemManager永久禁用sudo systemctl disable ModemManagersudo usermod -a -G dialout $USER添加当前用户到dialout组重启系统仅udevadm trigger不够需重新加载内核模块5.3 现象Windows下一切正常Linux ARM板上编译报错undefined reference to pthread_create原因交叉编译链未链接pthread库QSerialPort底层依赖POSIX线程。解决在CMakeLists.txt中添加find_package(Threads REQUIRED) target_link_libraries(iot_display PRIVATE ${CMAKE_THREAD_LIBS_INIT}) # 或在qmake项目中.pro文件添加LIBS -lpthread5.4 现象历史曲线X轴时间戳乱跳出现负值或突变到1970年原因startTime变量未初始化QDateTime::currentMSecsSinceEpoch()减去随机栈值。解决在MainWindow构造函数中强制初始化startTime QDateTime::currentMSecsSinceEpoch(); // 在ui-setupUi(this)之后5.5 现象插拔USB后QT程序日志疯狂打印QSerialPort: Device not readyCPU占用100%原因reconnectTimer未停止attemptReconnect()被高频触发每次调用都尝试open()失败并立即重试。解决在attemptReconnect()开头添加守卫if (reconnectTimer-isActive()) return; // 防止重入 // ...后续逻辑并在connectionRestored()槽函数中调用reconnectTimer-stop()。6. 进阶技巧用QSettings持久化存储让系统记住你的校准偏移量6.1 为什么需要校准DHT22出厂误差±0.5℃实测同一环境三块传感器读数差达1.2℃实验室级应用必须支持用户手动校准。本工程在UI右下角添加“校准”按钮点击弹出CalibrationDialog输入温度偏移量如0.3和湿度偏移量如-2.1点击确定后保存至QSettings。关键代码// CalibrationDialog.cpp void CalibrationDialog::on_okButton_clicked() { float tempOffset ui-tempOffsetEdit-text().toFloat(); float humOffset ui-humOffsetEdit-text().toFloat(); QSettings settings(IoT-Lab, TempHumDisplay); settings.setValue(calibration/temp_offset, tempOffset); settings.setValue(calibration/hum_offset, humOffset); // 立即应用到当前显示 emit calibrationApplied(tempOffset, humOffset); accept(); }6.2 校准值如何注入数据流在信号传递链路上做拦截不修改SensorFrameParser保持协议层纯净而在SerialWorker中拦截sensorDataReceived信号// SerialWorker.cpp void SerialWorker::onRawDataReceived(float rawTemp, float rawHum, qint64 ts) { // 读取校准值首次读取时QSettings自动创建ini文件 QSettings settings(IoT-Lab, TempHumDisplay); float tempOffset settings.value(calibration/temp_offset, 0.0f).toFloat(); float humOffset settings.value(calibration/hum_offset, 0.0f).toFloat(); float calibratedTemp rawTemp tempOffset; float calibratedHum qBound(0.0f, rawHum humOffset, 100.0f); // 湿度不能超限 emit sensorDataReceived(calibratedTemp, calibratedHum, ts); }注意qBound(0.0f, ..., 100.0f)确保校准后湿度仍在物理合理范围避免-1.5%RH这种荒谬显示。6.3 QSettings存储位置与跨平台一致性QSettings在不同系统存储路径不同但API完全一致系统存储路径WindowsHKEY_CURRENT_USER\Software\IoT-Lab\TempHumDisplayLinux$HOME/.config/IoT-Lab/TempHumDisplay.confmacOS$HOME/Library/Preferences/IoT-Lab.TempHumDisplay.plist本工程所有配置串口名、校准值、图表Y轴范围均通过QSettings管理无需修改代码即可适配不同部署环境。某次为某高校实训室批量部署时运维人员只需拷贝一份预配置好的.conf文件到每台ARM终端的~/.config/IoT-Lab/目录30秒完成全校50台设备参数统一。6.4 验证校准效果用双传感器对比法做可信度检验最可靠的验证不是看数字而是看趋势一致性。本工程预留DualSensorMode编译开关// 在main.cpp中定义 #define DUAL_SENSOR_MODE // 取消注释启用双传感器模式启用后UI底部增加第二行显示接收来自第二个串口如/dev/iot_sensor2的数据并用不同颜色区分。当两个传感器在相同环境下其温度曲线应高度重合偏差应稳定在±0.2℃内——这比单点校准值更直观证明系统可靠性。从那以后我每次交付物联网QT项目都会在main()函数第一行加上qInstallMessageHandler(customMessageHandler); // 捕获所有qDebug/qWarning并把日志重定向到/var/log/iot_display.log配合logrotate每日归档。不是为了炫技而是当用户深夜打电话说“屏幕黑了”我能直接SSH上去tail -f /var/log/iot_display.log30秒定位是USB掉线还是MCU固件崩溃。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

K8S 1.13节点NotReady:CNI配置未初始化故障排查指南

K8S 1.13节点NotReady:CNI配置未初始化故障排查指南

1. 问题现场还原&#xff1a;K8S集群节点卡在NOT READY&#xff0c;CNI配置未初始化不是报错&#xff0c;是系统在“喊救命”你执行kubectl get nodes&#xff0c;看到节点状态死死卡在NotReady&#xff0c;连Ready的影子都见不到&#xff1b;kubectl describe node <node-n…

2026/10/13 18:47:50 阅读更多 →
Java进阶实战:常用API、Lambda与算法在业务代码中的高效应用

Java进阶实战:常用API、Lambda与算法在业务代码中的高效应用

每个Java开发者都会经历过这样一个阶段&#xff1a;基础语法倒背如流&#xff0c;集合框架也天天在用&#xff0c;可一碰到“进阶”两个字就开始心虚。尤其是工作里真正要写一段高效、健壮、别人看得懂的代码时&#xff0c;总会遇到这些困惑——明明同一个需求&#xff0c;为什…

2026/10/13 18:47:50 阅读更多 →
V2G电动汽车实时调度策略:滚动优化与Matlab仿真实现

V2G电动汽车实时调度策略:滚动优化与Matlab仿真实现

前阵子做一个车网协同仿真项目&#xff0c;整个课题的落点就落在“电动车到底能不能作为柔性负荷参与电网调节”上。我们一开始拿到的任务是做静态充电调度&#xff0c;但真正把仿真跑起来之后发现&#xff0c;手里那批车辆的到达时间、出门时的 SOC 需求、台区基础负荷预测&am…

2026/10/13 18:47:50 阅读更多 →

最新新闻

Cursor额度重置教程:设备指纹清理实现合规续杯

Cursor额度重置教程:设备指纹清理实现合规续杯

简介&#xff1a;本资源是面向软件开发者的 Cursor 编辑器 11 月续杯实战源码包&#xff0c;聚焦解决免费用户模型调用受限、账号续期繁琐等实际痛点&#xff0c;适用于中初级开发者快速提升 AI 编程效率。压缩包共 3 个文件&#xff0c;含 .inscode&#xff08;Cursor 插件配置…

2026/10/13 19:38:20 阅读更多 →
用Claude Code摸清老项目技术栈:三轮提示词框架与实战记录

用Claude Code摸清老项目技术栈:三轮提示词框架与实战记录

“只管去写”系列到了第二天。今天的任务很明确&#xff1a;用Claude分析一个老项目的技术栈。这件事听起来远没有写一个新功能那么有成就感&#xff0c;但只要你接过大半年之前自己写的代码、接过离职同事留下的半成品项目、或者刚入职需要快速搞清一套业务系统的底细&#xf…

2026/10/13 19:38:20 阅读更多 →
开源协作的隐形基石:高效代码评审实践指南

开源协作的隐形基石:高效代码评审实践指南

做开源项目这几年&#xff0c;我越来越确信一件事&#xff1a;代码评审&#xff08;code review&#xff09;是整个协作链条里最被低估的一环。很多人觉得代码写完、测试跑通、合并进去就完事了&#xff0c;可真正把一个项目推过几个版本之后才发现&#xff0c;评审才是让代码质…

2026/10/13 19:38:20 阅读更多 →
Python pickle序列化实战:从协议版本到安全红线全解析

Python pickle序列化实战:从协议版本到安全红线全解析

如果你写过 Python&#xff0c;一定遇到过这类需求&#xff1a;程序跑完把内存里的字典、列表或者某个自定义类实例保存到磁盘&#xff0c;下次启动再原封不动读回来。Python 为此内置了一个序列化模块叫 pickle&#xff0c;标题说得很直白——Pickle 是 Python 内置的序列化模…

2026/10/13 19:38:20 阅读更多 →
AnyPS5:不越狱的PS5增强方案与边界协同架构

AnyPS5:不越狱的PS5增强方案与边界协同架构

项目标题&#xff1a;“AnyPS5”这个名称本身带有强烈的指向性与模糊性并存的特征——它既像一个技术代号&#xff0c;又像一句口号&#xff1b;既暗示兼容性、泛用性&#xff08;“Any”&#xff09;&#xff0c;又锚定在特定硬件生态&#xff08;“PS5”&#xff09;。但问题…

2026/10/13 19:38:20 阅读更多 →
互联网大厂薪酬结构全解析:总包、级别、绩效与谈薪技巧

互联网大厂薪酬结构全解析:总包、级别、绩效与谈薪技巧

1. 先说结论&#xff1a;今年这个薪酬盘子到底什么情况每年这个节点&#xff0c;总有人拿着某头部互联网平台的薪酬截图或者 Offer 在各个群里问“这个数正常吗”。说实话&#xff0c;我在这一行摸爬滚打了十几年&#xff0c;带过团队、做过招聘、也背过绩效&#xff0c;今年这…

2026/10/13 19:37:19 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目&#xff0c;我最大的感受是&#xff0c;大部分坑不是出在技术前沿&#xff0c;而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节&#xff0c;最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了&#xff0c;很难不碰到舵机控制这道坎。做智能小车要转方向&#xff0c;做机械臂要抬关节&#xff0c;做云台要偏航俯仰&#xff0c;背后都是同一个东西在干活&#xff1a;舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”&#xff1f;——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台&#xff1f;或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜&#xff1f;又或者&#xff0c;在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →