基于CircuitPython与BLE构建多探头无线温度监测系统

news2026/5/16 2:05:19
1. 项目概述一个无线温度监控的“瑞士军刀”如果你和我一样喜欢在周末慢烤一块牛排或者沉迷于培养天然酵母做面包那你一定理解同时盯着好几个温度计的烦恼。厨房里烟雾缭绕烤箱里正烤着东西发酵箱里还有面团在膨胀传统的温度计要么线缆缠绕要么需要你频繁地凑近查看既不方便也不优雅。几年前市面上开始出现一些基于蓝牙低功耗BLE的无线温度计它们通过手机App查看数据确实方便了不少。但作为一个喜欢折腾硬件的开发者我总觉得缺了点什么——数据被封闭在手机App里没法方便地接入我的自动化流程或者进行长期的数据记录和分析。直到我遇到了Adafruit CLUE这块开发板和CircuitPython再结合那些支持iBBQ协议的平价烧烤温度计一个想法诞生了为什么不自己做一个开放、可编程、还能本地显示的多探头温度监控中心呢这个项目我称之为“BBQLUE”本质上是一个基于微控制器的无线温度数据聚合与显示终端。它的核心是Adafruit CLUE开发板搭载nRF52840芯片原生支持BLE运行CircuitPython固件。通过编写特定的代码CLUE可以主动扫描并连接市面上常见的、采用iBBQ协议的BLE温度计主机比如InkBird、NutriChef等品牌的产品读取其连接的多个探头的实时温度数据并在自带的彩色屏幕上清晰地显示出来。你不仅可以同时监控多达6个通道的温度还能通过板载的A按钮一键切换摄氏和华氏度完全摆脱了对手机App的依赖。它解决的不仅仅是“看温度”的问题更是“如何更智能、更集成地管理温度数据”的问题。无论是监控慢烤炉的内部温度和环境温度还是同时追踪烤箱上下层、发酵箱内多个点的温度甚至是进行一些有趣的厨房科学实验比如验证盐水沸点升高这个系统都能胜任。更重要的是整个系统是开源的所有数据都在本地处理你可以轻松地修改代码将数据通过Wi-Fi上传到服务器或者触发其他智能家居设备可玩性和扩展性极高。接下来我将从硬件选型、环境搭建、代码逐行解析到实际使用技巧和问题排查完整地拆解这个项目的构建过程。无论你是嵌入式开发新手还是想寻找一个有趣物联网项目的爱好者相信都能从中获得启发。2. 核心硬件与协议深度解析在动手写代码之前理解我们手中的“武器”至关重要。这个项目的巧妙之处在于它巧妙地利用了成熟的消费级硬件和一个相对开放的蓝牙协议避免了从零设计传感器电路的复杂性。2.1 硬件核心为什么是Adafruit CLUE主控板的选择直接决定了项目的上限。我选择Adafruit CLUE是基于以下几个经过深思熟虑的理由强大的nRF52840 SoC这是项目的通信基石。nRF52840是Nordic Semiconductor推出的一款顶级BLE芯片不仅蓝牙5.0协议栈稳定成熟其ARM Cortex-M4F内核提供了充足的性能来运行Python解释器和处理显示刷新。市面上很多廉价的ESP32开发板虽然也有蓝牙但其BLE栈的稳定性和易用性尤其在CircuitPython下与经过深度优化的nRF52840相比仍有差距。丰富的集成外设CLUE板载了1.3英寸全彩LCD屏幕、按钮、蜂鸣器、RGB LED灯。这意味着我们无需焊接任何额外的元件就能实现完整的人机交互显示、按键、声光提示真正做到了“开箱即用”。对于快速原型和希望项目外观整洁的用户来说这节省了大量时间和精力。出色的CircuitPython支持Adafruit是CircuitPython的主要维护者其自家的CLUE板自然拥有第一梯队的驱动和库支持。我们项目中用到的displayio图形库、adafruit_ble蓝牙库在CLUE上都能获得最佳性能和最少的兼容性问题。实操心得备选方案考量如果你手头没有CLUE理论上其他搭载nRF52840且支持CircuitPython的板子如Adafruit Feather nRF52840 Express也可以但你需要自行连接一个SPI或I2C屏幕并解决供电和封装问题复杂度会上升。ESP32-S3等板子目前在CircuitPython下的BLE库生态和稳定性尚不如nRF52系列除非你非常熟悉MicroPython或Arduino否则不推荐初学者替换。2.2 传感器端揭秘iBBQ协议生态项目的另一个智慧之处在于对现有消费产品的“破解”与利用。我们并没有自己制作温度探头和无线发射器而是选择了支持iBBQ协议的BLE烧烤温度计。什么是iBBQ协议它本质上是一个自定义的蓝牙GATT通用属性服务。当这些温度计开机后会以特定的服务UUID例如FFF0广播自身。手机App或我们的CLUE通过识别这个UUID就能与之建立连接并订阅其特征值Characteristic来读取温度、电量等数据。协议细节通常是厂商私有的但开源社区特别是Adafruit已经通过逆向工程将其封装成了易于使用的CircuitPython库adafruit_ble_ibbq这让我们免去了抓包分析的繁琐过程。硬件优势这些温度计主机通常有4到6个K型热电偶探头接口探头本身耐高温可达300°C以上长度可选非常适合烧烤、烘焙等高温场景。它们内置电池续航时间长且探头和主机是工业标准接口更换和扩展成本极低。自己从头实现同等性能的无线热电偶系统成本和技术难度会高出一个数量级。选购指南并非所有无线温度计都使用iBBQ协议。在购买前最好在Adafruit的教程页面或开源社区确认型号。常见的兼容品牌包括InkBird IBT-4X/6X系列、某些型号的Pyle和NutriChef。购买时注意选择探头数量符合你需求的版本。2.3 通信基石理解BLE的工作模式为了写出稳定的代码我们需要对BLE通信有一个基本的概念模型。在这个项目中CLUE扮演中心设备Central的角色而温度计主机则是外围设备Peripheral。广播与扫描温度计主机不断向外广播数据包里面包含设备名称、服务UUID等信息。我们的CLUE代码中的ble.start_scan()就是在持续监听这些广播包。连接与数据交换一旦CLUE扫描到包含IBBQService的广播就会发起连接请求。连接建立后通信从“广播”模式转为“连接”模式此时可以进行双向、低功耗的数据传输。服务与特征连接后CLUE通过IBBQService这个“服务”接口访问特定的“特征”来读取温度数组和电池电量。你可以把服务看作一个数据文件夹特征就是里面的具体文件。连接维护代码中的while ibbq_connection.connected:循环确保了在连接保持期间持续读取数据。一旦连接意外断开如温度计关机_bleio.ConnectionError异常会被捕获代码会跳回扫描状态重新寻找设备实现了自动重连的鲁棒性设计。理解了这个流程再看后面的代码就会觉得清晰很多你也能更从容地应对可能出现的连接不稳定等问题。3. 开发环境搭建与项目初始化工欲善其事必先利其器。这部分我们将完成从零开始让CLUE运行我们代码的所有步骤。请严格按照顺序操作避免踩坑。3.1 为CLUE安装CircuitPython固件CircuitPython是MicroPython的一个分支由Adafruit主导开发其最大特点是将开发板模拟成一个U盘CIRCUITPY你可以像编辑文本文件一样编写Python代码体验非常接近现代Web开发。下载固件访问 CircuitPython官网 找到对应Adafruit CLUE的最新稳定版.uf2文件并下载。务必确认文件名中包含“clue”这是专为CLUE硬件优化的版本。进入引导加载程序模式使用一条可靠的数据线很多手机充电线只能充电无法传输数据这是最常见的失败原因将CLUE连接到电脑。快速双击CLUE板上的Reset按钮板子顶部标有RESET字样。此时板载的RGB NeoPixel LED会闪烁绿色屏幕可能熄灭。如果操作成功你的电脑上会出现一个名为CLUEBOOT的U盘驱动器。如果LED闪红色或者没有出现CLUEBOOT盘请尝试更换USB线或电脑USB端口。刷入固件将下载好的adafruit-circuitpython-...-clue.uf2文件直接拖拽或复制到CLUEBOOT磁盘中。CLUE的LED会快速闪烁CLUEBOOT盘会自动弹出随后出现一个新的名为CIRCUITPY的磁盘。这个过程通常只需几秒钟。验证安装打开CIRCUITPY盘你应该能看到至少boot_out.txt和code.py两个文件。boot_out.txt记录了固件版本code.py则是主程序文件CircuitPython启动后会自动运行它。3.2 部署项目代码与依赖库CircuitPython项目通常由主程序代码和一系列库文件组成。库文件提供了硬件驱动、蓝牙协议解析等核心功能。获取项目包从Adafruit的教程页面下载本项目的“Project Bundle”。这是一个zip压缩包里面已经包含了所有必需的库文件和主程序code.py。文件系统结构解压下载的zip包。关键目录结构如下CLUE_BBQ/ └── lib/ # 库文件夹 ├── adafruit_ble/ ├── adafruit_ble_ibbq.mpy ├── adafruit_bus_device/ ├── adafruit_display_shapes/ ├── adafruit_display_text/ └── adafruit_bitmap_font/ └── code.py # 主程序 └── font/ # 字体文件 └── GothamBlack-50.bdf └── GothamBlack-25.bdf部署到CLUE将CIRCUITPY盘中现有的lib文件夹如果有重命名为lib_backup作为备份。将解压后项目包里的lib文件夹和code.py文件整个复制到CIRCUITPY盘的根目录。将font文件夹也复制到CIRCUITPY盘根目录。最终你的CIRCUITPY盘应该看起来像这样CIRCUITPY/ ├── lib/ ├── font/ ├── code.py └── boot_out.txt注意事项库文件管理.mpy文件是预编译的MicroPython字节码加载速度比.py文件快。请确保复制整个lib文件夹而不是单独的几个文件因为库之间存在依赖关系。如果未来更新CircuitPython固件CIRCUITPY盘的内容通常会被保留但为防万一定期备份你的code.py和font文件夹是个好习惯。3.3 首次运行与基础测试完成文件复制后CLUE会自动重启并运行新的code.py。观察启动过程CLUE屏幕会先黑屏片刻正在加载字体和图形然后你应该会看到屏幕右上角出现一个橙色的“BBQLUE”Logo背景是一个烧焦色的方块。同时板载的RGB LED可能会闪烁。检查串口输出高级调试这是排查问题的利器。使用串口终端工具如VS Code的Serial Monitor、PuTTY、或者screen/tty命令连接到CLUE的串口在设备管理器中查找类似COMx或/dev/ttyACM0的端口波特率通常为115200。你将在终端里看到“Scanning...”的打印信息这表明程序已开始扫描BLE设备。准备温度计打开你的兼容iBBQ协议的烧烤温度计主机并插入至少一个温度探头。确保温度计主机处于开机状态。如果一切顺利当CLUE扫描到温度计后终端会打印“found an IBBQ advertisement”和“Connected”屏幕会切换到温度显示界面。如果长时间停留在Logo界面请进入下一章节的故障排查部分。4. 代码逐行解析与核心逻辑剖析理解了硬件和协议现在我们来深入代码看看魔法是如何发生的。我将以模块化的方式解释code.py中的关键部分。4.1 导入与初始化搭建舞台代码开头是一系列的导入语句它们引入了所有必要的工具包。import time import displayio import _bleio import adafruit_ble from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble_ibbq import IBBQService from adafruit_clue import clue from adafruit_display_shapes.circle import Circle from adafruit_display_text import label from adafruit_bitmap_font import bitmap_fontdisplayio这是CircuitPython的图形显示核心库它采用“显示组Group”和“图块网格TileGrid”的概念来管理屏幕上的所有元素效率远高于直接操作像素。_bleio和adafruit_ble前者是底层的BLE驱动后者是更高层、更易用的封装。ProvideServicesAdvertisement帮助我们过滤只广播了特定服务的设备。adafruit_ble_ibbq这是项目的关键它包含了逆向工程得到的iBBQ协议解析器提供了IBBQService这个类让我们能像访问属性一样轻松获取温度数据ibbq_service.temperatures。adafruit_clueCLUE板的硬件抽象库通过clue.button_a、clue.pixel、clue.display等对象我们可以用统一的方式访问按钮、LED和屏幕无需关心底层引脚。4.2 显示系统构建双屏切换的艺术项目使用了两个displayio.Group来管理界面这是实现流畅屏幕切换的关键设计。homescreen_screen displayio.Group() # 首页Logo组 temperatures_screen displayio.Group() # 温度显示组首页homescreen_screen的构建创建背景displayio.Bitmap创建了一个120x120像素的单色位图Palette调色板定义了它的颜色BURNT最后用TileGrid将其定位到屏幕右上角x120, y0。绘制圆形边框Circle对象在屏幕中央画了一个黑色填充、BURNT色边框的大圆作为Logo的视觉容器。添加文字使用bitmap_font加载位于/font/目录下的.bdf矢量字体文件。load_glyphs预加载了“BQLUE”这几个字符的图形能提升首次显示速度。Label对象创建文本标签并设置位置和颜色。最终呈现所有元素背景、圆、文字都被append到homescreen_screen这个组里。通过clue.display.root_group homescreen_screen我们将这个组设置为当前根组屏幕便显示出Logo。温度屏temperatures_screen的构建 逻辑类似但更动态。它预先为6个探头创建了6个Label对象每个都有预设的颜色和位置通过my_labels_config列表定义。这些标签的初始文本是空的等待后续填入温度值。标题“BBQLUE”也被添加进去。注意此时我们并没有将这个组设置为根组它只是在内存中准备好。这种“双屏”设计的好处是切换时几乎没有延迟。当需要显示温度时只需一句clue.display.root_group temperatures_screen当连接断开需要返回首页时再切回homescreen_screen即可。4.3 BLE连接与数据读取核心通信循环主循环while True是整个程序的心脏它清晰地分为扫描、连接、数据处理三个阶段。阶段一扫描与连接while True: clue.display.root_group homescreen_screen print(Scanning...) for adv in ble.start_scan(ProvideServicesAdvertisement, timeout5): if IBBQService in adv.services: ibbq_connection ble.connect(adv) break ble.stop_scan()ble.start_scan(ProvideServicesAdvertisement, timeout5)开始扫描只关注那些广播了“提供服务”信息的设备超时时间为5秒。这比盲目扫描所有设备更高效。if IBBQService in adv.services:检查扫描到的设备广播的服务列表中是否包含我们定义的IBBQService。这是匹配iBBQ温度计的关键条件。ble.connect(adv)一旦找到立即发起连接并将连接对象保存在ibbq_connection中。ble.stop_scan()无论是否连接成功都停止扫描以节省功耗。阶段二连接维持与数据处理try: if ibbq_connection and ibbq_connection.connected: ibbq_service ibbq_connection[IBBQService] ibbq_service.init() while ibbq_connection.connected: # ... 处理按钮和温度数据 ... except _bleio.ConnectionError: continueibbq_service ibbq_connection[IBBQService]从连接对象中获取IBBQService实例。ibbq_service.init()至关重要的一步。根据对iBBQ协议的分析必须向设备发送一个初始化指令它才会开始持续发送温度数据。缺少这一步temperatures属性将永远为None。while ibbq_connection.connected:在这个内部循环中只要连接保持就持续工作。except _bleio.ConnectionError:如果连接意外断开如设备关机、超出范围会抛出此异常。continue语句会跳回外层while True循环的开头重新开始扫描实现了自动重连。4.4 温度数据处理与单位转换在连接保持的内部循环中程序不断读取并更新温度显示。temps ibbq_service.temperatures if temps is not None: probe_count len(temps) for i in range(probe_count): if temps[i] ! 0 and temps[i] 1000: if unit_mode: # Celsius temp temps[i] my_labels[i].text {} C.format(temp) else: # Fahrenheit temp temps[i] * 9 / 5 32 my_labels[i].text {} F.format(temp) else: my_labels[i].text --- clue.display.root_group temperatures_screen数据有效性判断if temps is not None确保我们已经收到了有效数据包。probe_count len(temps)获取探头数量通常是4或6。探头状态判断if temps[i] ! 0 and temps[i] 1000:这是一个经验性的判断。根据测试未插入探头的通道其温度值要么是0要么是一个极大的无效值如1023。这个条件用于过滤掉无效探头。单位转换与显示根据unit_mode由A按钮切换变量决定是直接显示摄氏温度还是通过公式F C * 9/5 32转换为华氏度并更新对应的标签文本。屏幕刷新所有标签更新后通过clue.display.root_group temperatures_screen刷新整个温度显示界面。4.5 用户交互按钮与反馈交互设计虽简单但贴心。if clue.button_a: unit_mode not unit_mode clue.red_led True clue.play_tone(1200, 0.1) clue.red_led False time.sleep(0.1)状态切换unit_mode not unit_mode在True摄氏和False华氏之间翻转。多感官反馈按下按钮时红色LED亮起同时蜂鸣器发出一个短暂的1200Hz提示音play_tone然后LED熄灭。这种声光结合的方式在嘈杂的厨房或户外环境下比单纯的屏幕变化更能确保操作被感知。防抖延时time.sleep(0.1)是一个简单的软件防抖措施避免一次物理按压被误判为多次。5. 系统使用指南与厨房科学实验硬件连接好代码跑起来这个系统就能成为你厨房或工作台的得力助手。下面分享一些实际使用中的技巧和一个有趣的扩展应用。5.1 日常使用与最佳实践启动顺序建议先打开CLUE待其启动完成进入扫描状态显示Logo后再打开你的iBBQ温度计主机。这能确保CLUE能立刻发现并连接设备避免因扫描超时导致的等待。探头颜色编码为了与屏幕显示对应建议按照以下顺序插入探头探头1用绿色标签或记号笔标记探头2用蓝色以此类推红、橙、黄、紫。这样屏幕上绿色的数字就对应你标记为绿色的探头一目了然。放置与信号CLUE和温度计主机之间尽量避免厚重的金属或混凝土墙遮挡以保证BLE信号稳定。通常10米以内的无障碍空间连接都很可靠。省电提示CLUE通过USB供电而iBBQ温度计主机使用电池。长时间不使用时请记得关闭温度计主机。CLUE屏幕亮度较高如需长时间监控可以考虑在代码中适当调低clue.display.brightness的值如设为0.7。5.2 厨房科学实验盐水沸点升高这个项目不仅实用还是一个绝佳的STEM教育工具。原教程中提到的“盐水沸点升高”实验我亲自复现并做了一些优化。实验原理简述纯水在标准大气压下的沸点是100°C。当加入非挥发性溶质如食盐NaCl后溶液的沸点会升高。这是因为溶质粒子占据了溶液表面使得水分子更难逸出需要更多的能量更高的温度才能达到气化逃逸的速度。我的实验改进与实操记录材料准备两个完全相同的奶锅小容量加热快。两个iBBQ温度探头对应CLUE上的两个颜色如绿色和蓝色。夹具我用了小型的“万向棒夹”代替晾衣夹更容易调节探头深度和角度。蒸馏水减少水中原有矿物质的影响。精制食盐、电子秤追求精确、量杯。实验设置控制组Pot A倒入250毫升蒸馏水。实验组Pot B倒入250毫升蒸馏水然后加入36克食盐约等于海水的盐度质量分数约12.6%。关键技巧为确保完全溶解我预先用少量热水将盐化开再与剩余冷水混合。探头固定用夹具将探头固定在锅边确保金属测温头浸入水面以下约2-3厘米且绝对不接触锅底或锅壁否则测量的是锅体温度而非水温。这是实验准确性的关键。操作与观测将两锅并排放在电磁炉或燃气灶的相同功率档位上加热。观察CLUE屏幕。你会明显看到升温阶段盐水Pot B的升温速度略慢于纯水因为盐水的比热容稍大且盐的溶解过程也吸收少量热量。沸腾阶段纯水Pot A温度迅速达到99-100°C并稳定下来剧烈沸腾。关键现象盐水Pot B的温度会超过100°C在我的实验中它最终稳定在102.5°C左右并保持沸腾。屏幕上两个探头清晰的温度差直观地验证了沸点升高现象。数据记录与拓展你可以在代码中添加数据记录功能将温度数据通过串口输出并导入到Excel或Python中进行绘图得到更漂亮的温度-时间曲线。进阶实验尝试不同浓度的盐水如5% 20%观察沸点升高值ΔTb与浓度的关系。甚至可以尝试糖水、小苏打水比较不同溶质的效果。这个实验完美展示了如何将嵌入式开发、传感器技术和基础科学结合起来做出既有趣又有教育意义的项目。6. 常见问题排查与进阶优化即使按照教程操作你也可能会遇到一些问题。这里我整理了开发和使用过程中可能遇到的“坑”及其解决方案。6.1 连接与通信问题问题现象可能原因排查步骤与解决方案CLUE一直显示Logo不切换温度屏。1. 温度计未开机或未进入广播模式。2. 温度计不支持iBBQ协议。3. CLUE与温度计距离过远或有强干扰。4. 代码中服务UUID不匹配可能性低。1.检查温度计确认已开机屏幕有显示。某些型号需要短按按钮唤醒广播。2.验证协议用手机蓝牙扫描如果能用官方App如“InkBird”连接则支持iBBQ。3.靠近设备将CLUE和温度计放在1米内排除干扰。4.查看串口输出连接串口监视器看是否有“found an IBBQ advertisement”打印。如果没有说明没扫描到。连接成功但所有探头都显示“---”。1. 探头未插紧或损坏。2.最重要的原因代码中ibbq_service.init()未成功执行或设备未响应。1.检查探头重新插拔探头确保接触良好。2.检查串口输出连接后是否打印了“Connected”之后是否有持续的温度打印如果没有可能是初始化失败。尝试重启CLUE和温度计。3.检查代码确保ibbq_service.init()在连接后的循环中被调用。连接间歇性断开。1. BLE信号不稳定。2. 温度计主机进入超低功耗休眠模式。1.改善环境移除可能的信号屏蔽物避免微波炉、无绳电话等2.4GHz设备干扰。2.防止休眠部分温度计在一段时间无操作后会休眠。查阅说明书看是否有“常亮”或“持续广播”模式或者尝试在代码中定期发送一个无害的读取指令如读取电量来保持连接活跃。6.2 显示与性能问题屏幕刷新慢或有残影displayio的刷新率受代码复杂度和主循环速度影响。确保主循环尤其是数据处理部分不要有长时间的阻塞操作如time.sleep(1)。温度更新频率通常1-2秒一次就足够可以在主循环内适当添加time.sleep(0.5)来降低CPU占用反而可能让系统更稳定。字体文件缺失导致无法启动如果启动后屏幕空白或报错请检查CIRCUITPY盘根目录下是否存在font文件夹以及里面是否有GothamBlack-50.bdf和GothamBlack-25.bdf文件。字体文件路径在代码中是硬编码的“/font/GothamBlack-50.bdf”必须完全匹配。内存不足错误如果未来你添加了太多功能如网络连接、复杂图形可能会遇到MemoryError。可以尝试使用.mpy格式的库文件。优化代码移除不必要的全局变量或大列表。考虑使用gc.collect()手动触发垃圾回收需导入gc模块。6.3 功能扩展与进阶玩法这个项目的框架具有很强的扩展性以下是一些方向数据记录与上传本地记录CLUE的存储空间有限但可以定期将温度数据追加写入到CIRCUITPY盘的一个CSV文件中。注意频繁写入会损耗存储芯片寿命建议间隔几分钟记录一次平均值。import csv with open(/temperature_log.csv, a) as f: writer csv.writer(f) writer.writerow([time.monotonic(), temp1, temp2, ...])无线传输为CLUE搭配一个Wi-Fi协处理器如ESP32或者使用具有Wi-Fi功能的开发板如ESP32-S2/S3但需注意其CircuitPython BLE支持情况可以将数据实时发送到MQTT服务器、InfluxDB或云平台如Adafruit IO实现远程监控和历史图表。报警功能在代码中添加温度阈值判断。当某个探头温度超过设定值如牛排中心温度达到55°C三成熟让CLUE的蜂鸣器持续鸣叫RGB LED闪烁红色实现声光报警。多设备支持修改扫描逻辑维护一个已发现设备的列表允许用户通过按钮切换显示不同温度计主机比如同时监控烤箱和发酵箱的数据。低功耗优化如果你希望用电池驱动CLUE需要大幅修改代码在不显示时关闭屏幕背光、降低CPU频率、让BLE连接间隔更长、使用深度睡眠等。这属于高级话题需要对CircuitPython的电源管理有深入了解。这个基于CircuitPython和BLE的多探头温度监测系统从一个具体的烹饪需求出发串联起了嵌入式开发、无线通信和基础物理。它最吸引我的地方在于其“桥梁”作用——将消费级的智能硬件通过开源软件变成了一个可编程、可扩展的开发平台。希望这份详细的拆解不仅能帮你成功复现项目更能激发你用它去解决更多实际问题的灵感。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2616757.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…