基于CircuitPython与MagTag的电子墨水屏俳句显示器项目实践

news2026/5/17 1:52:44
1. 项目概述与核心价值如果你对嵌入式开发感兴趣但又觉得传统的C/C开发环境配置繁琐、学习曲线陡峭那么CircuitPython绝对是一个值得尝试的入口。它本质上是一个运行在微控制器上的Python 3解释器由Adafruit主导开发目标就是让硬件编程变得像写Python脚本一样简单。你不需要安装复杂的IDE、配置交叉编译工具链只需要把开发板通过USB线连接到电脑它就会以一个U盘名为CIRCUITPY的形式出现。你的代码、库文件、配置文件都像操作普通文件一样拖拽进去保存后程序即刻运行。这种“所见即所得”的体验极大地降低了原型验证和创意实现的门槛。本次我们要实践的项目正是CircuitPython这种“低门槛、高表现力”特性的一个绝佳例证一个基于Adafruit MagTag的电子墨水屏俳句显示器。MagTag是一块集成了ESP32-S2 WiFi芯片、2.9英寸灰度电子墨水屏和四个物理按键的开发板。电子墨水屏的特性是仅在刷新时耗电显示静态内容时几乎为零功耗这使得它非常适合作为信息展示终端比如天气预报站、日程提醒器或者像本项目一样——一个充满禅意的数字俳句画框。项目的核心逻辑并不复杂设备启动后从两个来源本地的haikus.txt文件或远程的Adafruit IO云服务加载一系列俳句随机显示一条在屏幕上。用户可以通过左右按键顺序浏览或通过另一个按键随机跳转。然而在这个简单的功能背后串联起了现代嵌入式开发的几个关键环节无线网络连接与认证管理、云端数据同步、低功耗显示驱动以及本地文件系统操作。通过完成这个项目你不仅能收获一个有趣的桌面摆件更能系统地掌握如何使用CircuitPython生态下的核心库来构建一个完整的、可联网的物联网应用。注意Adafruit MagTag在2025年推出了新版主要区别在于WiFi模块和内存。最关键的一点是新版MagTag必须使用CircuitPython 10.x.x或更高版本旧的9.x.x版本将无法运行。在开始前请务必确认你的板子型号并下载对应的固件。2. 硬件准备与开发环境搭建2.1 核心硬件Adafruit MagTag深度解析MagTag的设计目标很明确一个开箱即用、电池友好、具备网络能力的显示终端。我们来看看它的几个核心组件及其在本项目中的作用ESP32-S2微控制器这是板子的“大脑”。它基于Xtensa单核32位处理器主频高达240MHz集成了WiFi功能并提供了丰富的GPIO通用输入输出引脚。在本项目中它负责运行CircuitPython解释器、管理网络连接、处理按键输入以及驱动屏幕刷新。2.9英寸灰度电子墨水屏E-Ink这是项目的“脸面”。其分辨率为296x128像素支持4级灰度黑、白、浅灰、深灰。电子墨水屏的原理是通过电场控制带电荷的颜料颗粒移动形成图像。一旦颗粒就位即使断电图像也能持久显示。这意味着我们的俳句在显示后MagTag可以进入深度睡眠仅靠电池就能维持显示数周甚至数月。驱动这块屏幕需要专门的波形文件幸运的是Adafruit的displayio库已经为我们封装好了所有底层细节。四个物理按键D11, D12, D15, 及复位键这是用户与设备交互的“手脚”。D11右、D15左和D12下被我们编程为浏览控制键。在CircuitPython中我们通过digitalio库来读取这些按键的状态。为了防止按键抖动一种由于机械触点不稳定导致的电平快速变化造成误触发我们会使用adafruit_debouncer库进行“消抖”处理。USB-C接口与锂电池接口提供电源和程序下载通道。USB-C接口用于供电和串口通信打印调试信息同时它也是我们给板载锂电池充电的入口。2.2 软件基石CircuitPython固件安装详解为MagTag安装CircuitPython是第一步也是新手最容易卡住的地方。其核心是向板子的闪存中烧录一个.bin或.uf2格式的固件文件。Adafruit提供了三种方法我会详细解释最推荐的两种及其背后的原理。第一步获取固件访问CircuitPython官网找到MagTag的下载页面。这里你会看到两个关键文件.bin文件和.uf2文件。.bin是原始的二进制镜像而.uf2USB Flashing Format是一种特殊格式它包含了目标地址等信息可以被UF2引导程序直接识别并写入。对于2025年及之后的新版MagTag请务必选择10.x.x版本的固件。第二步进入烧录模式MagTag有两种启动模式正常运行模式和烧录模式。我们需要先让它进入烧录模式。UF2 Bootloader模式推荐如果你的MagTag正面是黑色PCB它通常预装了UF2引导程序。操作方法是用USB线连接电脑和MagTag然后快速双击板子上的复位按钮紧挨着USB-C口。如果成功电脑会识别出一个名为MAGTAGBOOT的U盘。这个过程实际上是让芯片从系统闪存启动跳转到独立存储的引导程序该引导程序将自己模拟成一个U盘等待接收.uf2文件。ROM Bootloader模式如果你的板子是早期的白色PCB版本可能没有UF2。这时需要进入芯片内置的ROM引导模式。方法是按住板子上的D0按钮通常有标注再按一下复位键然后松开D0。此时芯片不会启动主程序而是运行出厂时固化在芯片内部的低级引导代码等待通过串口接收指令。第三步烧录固件UF2方式直接将下载好的.uf2文件拖拽到MAGTAGBOOT盘符中。文件复制完成后盘符会自动消失板子重启一个名为CIRCUITPY的新盘符会出现。这表明CircuitPython系统已经成功运行。esptool方式备用如果UF2方式失败需要使用esptool.py这个Python工具。首先在电脑上安装esptoolpip install esptool然后通过命令行执行擦除和写入命令。例如esptool.py --chip esp32s2 --port COM3 erase_flash esptool.py --chip esp32s2 --port COM3 --baud 460800 write_flash -z 0x1000 adafruit-circuitpython-adafruit_magtag_2.9_grayscale-10.x.x.bin这里的COM3需要替换成你的MagTag在电脑上实际的串口号Windows在设备管理器中查看macOS/Linux通常是/dev/tty.usbmodemXX或/dev/ttyACM0。0x1000是ESP32-S2系列芯片固定的固件烧录起始地址。实操心得双击复位键进入UF2模式需要一点手感不是每次都能成功。如果没出现MAGTAGBOOT盘符多试几次确保在第一次按下复位键后系统启动的瞬间通常USB连接音效响起时迅速完成第二次双击。如果始终不行就果断使用esptool方式虽然步骤稍多但成功率是100%。2.3 关键配置settings.toml文件的作用与编写CircuitPython 8之后引入了settings.toml文件来管理敏感信息取代了之前的secrets.py。这是一个非常棒的设计它实现了配置与代码的分离。为什么需要settings.toml想象一下你的代码里直接写着WiFi密码和Adafruit IO的API密钥。当你把代码分享到GitHub或传给朋友时这些秘密就泄露了。settings.toml文件存储在CIRCUITPY驱动器上但通常被.gitignore忽略。你的代码通过os.getenv()函数来读取其中的值。这样你可以安全地分享代码而只需私下提供配置文件。如何创建正确的settings.toml在CIRCUITPY驱动器的根目录下新建一个纯文本文件命名为settings.toml注意扩展名。用任何文本编辑器如VS Code、Notepad甚至系统自带的记事本打开它内容如下CIRCUITPY_WIFI_SSID 你的WiFi名称 CIRCUITPY_WIFI_PASSWORD 你的WiFi密码 ADAFRUIT_AIO_USERNAME 你的Adafruit IO用户名 ADAFRUIT_AIO_KEY 你的Adafruit IO Active Key关键细节与避坑指南格式严格这是TOML格式。等号两边有空格字符串必须用双引号括起来。键名如CIRCUITPY_WIFI_SSID是大小写敏感的。获取Adafruit IO密钥登录Adafruit IO网站点击右上角个人头像 - “My Key”。页面中显示的“Active Key”就是ADAFRUIT_AIO_KEY的值。千万不要使用“Username”旁边的“Key”那个是只读的。文件位置必须放在CIRCUITPY的根目录不能放在任何文件夹里。编码问题建议使用支持UTF-8 without BOM编码的编辑器保存。如果文件中包含非ASCII字符如中文WiFi名错误的编码可能导致读取失败。变量名匹配本项目代码中读取的是ADAFRUIT_AIO_USERNAME和ADAFRUIT_AIO_KEY。有些其他Adafruit示例可能会用AIO_USERNAME或AIO_KEY。务必保证settings.toml中的键名与代码中os.getenv()里引用的字符串完全一致否则会返回None。完成这一步后你的MagTag就已经具备了连接指定WiFi并访问Adafruit IO服务的能力。当CircuitPython启动时它会自动读取这个文件并尝试连接网络。3. 项目代码深度解析与实现3.1 工程文件结构与获取一个典型的CircuitPython项目文件结构是清晰且模块化的。对于本项目你需要将以下文件放置到CIRCUITPY驱动器上CIRCUITPY/ ├── settings.toml # WiFi和AIO配置需自己创建 ├── code.py # 主程序文件 ├── haikus.txt # 本地俳句库可选 ├── bamboo.bmp # 底部装饰的竹子图像 ├── fanwood_webfont_15.bdf # 显示字体文件 └── lib/ # 依赖库目录 ├── adafruit_io/ ├── adafruit_bitmap_font/ ├── adafruit_display_text/ ├── adafruit_imageload/ ├── adafruit_debouncer/ ├── adafruit_requests/ └── adafruit_connection_manager/最方便的方式是直接下载项目捆绑包Project Bundle它通常包含了除settings.toml之外的所有必需文件。将捆绑包解压后把code.py、bamboo.bmp、haikus.txt如果你想用本地库和lib文件夹内含所有依赖库全部复制到CIRCUITPY驱动器的根目录即可。lib文件夹里的库文件是预编译的MPY文件CircuitPython可以直接导入使用无需我们手动编译。3.2 核心代码逻辑拆解code.py是这个项目的大脑我们可以将其逻辑分为四个主要阶段初始化与数据加载、显示界面构建、硬件输入设置和主事件循环。第一阶段初始化与数据加载程序启动后首先会导入所有必要的库。然后它尝试从两个源头加载俳句从Adafruit IO加载代码检查settings.toml中是否配置了AIO用户名和密钥。如果配置了它会初始化一个到Adafruit IO的HTTP会话并获取名为”haikus”的数据流Feed。从IO获取的数据其换行符\n会被服务器转义为\\n所以代码需要执行.replace(“\\n”, “\n”)将其还原。从本地文件加载无论是否从IO加载成功代码都会尝试打开本地的haikus.txt文件。该文件的格式是每个俳句由三行组成俳句之间用两个换行符\n\n分隔。代码读取整个文件内容然后按\n\n进行分割得到独立的俳句列表。最后将来自两个源头的所有俳句合并到一个名为all_haikus的列表中。如果这个列表为空程序会抛出错误因为无内容可显示。注意这里有一个优先级逻辑。代码会同时尝试两个源。这意味着你既可以只用本地文件也可以只用云端或者两者混用。云端管理的优势在于你可以远程更新俳句库而无需物理接触设备。第二阶段显示界面构建displayio图形系统这是CircuitPython中创建复杂用户界面的核心。displayio采用了一种“分组”Group和“平铺网格”TileGrid的层级模型类似于Photoshop的图层。创建根组和背景main_group是根组所有其他视觉元素都是它的子项。为了节省内存背景被设计成一个缩放8倍scale8的白色位图。这意味着我们在内存中只创建了一个很小的位图display.width // 8xdisplay.height // 8但显示时将其放大8倍铺满屏幕极大地减少了内存占用。加载装饰图像使用adafruit_imageload.load(“bamboo.bmp”)加载竹子位图。这个图像被放置在屏幕底部通过设置bamboo_tg.y坐标。绘制灰色边框这里用了一个巧妙的技巧。代码创建了一个和屏幕大小成比例的位图scale4并定义了一个调色板Palette其中索引0是灰色(0x999999)索引1是白色(0xFFFFFF)并将索引1设置为透明(make_transparent(1)。然后它使用bitmaptools.fill_region()函数将位图内部区域从(1,1)到(width-1, height-1)填充为白色索引1。由于白色是透明的最终显示出来的就只剩下一个像素宽的灰色边框。这种“挖空”的方法比直接画四条线更高效。创建文本标签使用adafruit_bitmap_font加载一个BDF格式的字体文件fanwood_webfont_15.bdf然后用这个字体创建一个Label对象。Label的anchor_point属性设置为(0, 0)左上角对齐anchored_position设置为(8, 0)让文本距离屏幕左边缘有8像素的边距看起来更舒服。第三阶段硬件输入设置初始化三个按键D11右 D15左 D12随机对应的GPIO引脚。关键步骤是将引脚方向设置为输入Direction.INPUT。启用内部上拉电阻Pull.UP。这意味着当按键未按下时引脚被内部电阻拉到高电平3.3V当按键按下时引脚通过按键接地变为低电平0V。这是一种常见的按键电路设计。为每个引脚创建一个Debouncer对象。消抖器会在一小段时间内默认约20毫秒连续采样引脚状态只有状态稳定变化时才认为是一次有效的按键动作从而过滤掉机械触点抖动产生的毛刺信号。第四阶段主事件循环这是一个经典的while True:循环不断做三件事更新消抖器状态调用每个Debouncer对象的update()方法。检测按键动作检查消抖器的fell属性。fell为True表示检测到了从高电平到低电平的“下降沿”即按键被按下的瞬间。响应并刷新显示右键(D11)current_index加1。如果超过列表长度则回到0循环。左键(D15)current_index减1。如果小于0则跳转到列表最后一个。随机键(D12)在确保列表中有至少两个俳句的前提下随机选择一个与当前显示不同的新索引。 每次更新current_index后从all_haikus列表中取出对应的文本赋值给haiku_lbl.text然后调用refresh_display()函数。refresh_display()函数是电子墨水屏编程的关键。它先通过display.time_to_refresh获取屏幕刷新所需的最短等待时间电子墨水屏刷新较慢通常需要几百毫秒到几秒然后调用display.refresh()执行实际的屏幕刷新。在刷新完成前程序必须等待否则强行刷新会导致屏幕残影或损坏。3.3 数据源管理本地与云端本地文件 (haikus.txt)这是最简单直接的数据管理方式。文件格式非常自由你只需要遵守“俳句之间用空行分隔”的规则。你可以用任何文本编辑器编辑它。例如秋风萧瑟起 落叶归根化春泥 岁月静无声 代码如诗行 逻辑严谨意悠长 bug无处藏将编辑好的文件保存到CIRCUITPY根目录设备下次启动或重新运行程序时就会自动加载。这种方式完全离线适合固定内容或不想依赖网络的场景。云端Adafruit IO Feed这是一种更动态、可远程管理的方式。创建Feed登录Adafruit IO在“Feeds”页面点击“New Feed”命名为haikus注意大小写代码中查找的feed名称是”haikus”。添加数据进入该Feed点击“Add Data”。在数据输入框中你需要输入俳句并且必须用\n来显式表示换行。例如明月照松间\n清泉石上流潺潺\n夜静春山空原理当你点击“Create”后Adafruit IO会存储这个字符串。当MagTag通过HTTP请求获取这个Feed的数据时服务器返回的JSON数据中这个字符串里的\n会被转义为\\n。这就是为什么代码中需要做replace(“\\n”, “\n”)处理将其还原为Python能识别的换行符。云端管理的优势在于你可以在任何有网络的地方通过手机或电脑的浏览器随时添加、删除或修改Adafruit IO上的俳句。MagTag只要联网就会在启动时自动同步最新的内容。这为实现一个“可众筹”的俳句显示器提供了可能。4. 高级技巧、问题排查与扩展思路4.1 性能优化与内存管理实战ESP32-S2虽然有足够的内存运行CircuitPython但在处理图形和字体时仍需精打细算。本项目已经运用了几项关键优化技术位图缩放Scaling背景和边框的Group都设置了scale参数8和4。这允许我们使用尺寸小得多的位图Bitmap对象在显示时由硬件或库进行放大。创建一个296x128的全屏单色位图需要约4.7KB内存而缩放8倍后我们只需要创建37x16的位图内存占用仅为74字节节省了98%以上。字体子集化项目中使用的fanwood_webfont_15.bdf是一个完整的字体文件。如果你只显示英文、数字和少量符号可以考虑使用字体子集化工具如Adafruit提供的font-to-py脚本生成一个仅包含所需字符的BDF或PY字体文件能进一步减少内存占用和加载时间。对象复用在循环中我们只是更新了Label对象的文本属性而不是每次按键都销毁旧对象、创建新对象。创建和销毁显示对象特别是涉及位图操作时是相对昂贵的操作应尽量避免在主循环中进行。4.2 常见问题与故障排除指南在制作和运行过程中你可能会遇到以下问题。这里提供一个快速排查清单问题现象可能原因解决方案CIRCUITPY盘符不出现1. USB线仅支持充电。2. CircuitPython固件未正确烧录。3. 板子硬件故障。1. 换用已知可传输数据的USB线。2. 重新按照步骤2.2烧录固件确认使用正确版本。3. 尝试另一台电脑。程序无法启动REPL报错1. 库文件缺失或版本不匹配。2.settings.toml格式错误。3. 语法错误。1. 检查lib文件夹内库是否完整从官方Bundle重新获取。2. 检查settings.toml的TOML格式引号、等号空格。3. 连接串口监视器如Mu编辑器、Thonny查看具体错误信息。屏幕无显示或显示乱码1. 屏幕排线接触不良。2. 显示刷新未正确等待。3. 字体文件路径错误。1. 重新插拔MagTag上连接屏幕的排线。2. 确保refresh_display()函数中的time.sleep(display.time_to_refresh)被调用。3. 确认fanwood_webfont_15.bdf文件在根目录。按键无反应1. 引脚定义错误。2. 消抖器未正确更新。3. 上拉电阻未启用。1. 核对代码中board.D11,D12,D15与实际板载按键标注是否一致。2. 在主循环中确认调用了left_btn.update()等。3. 确认pull digitalio.Pull.UP已设置。无法连接Adafruit IO1. WiFi密码错误或信号弱。2.settings.toml键名错误。3. Adafruit IO Feed名称不是”haikus”。4. AIO密钥权限不足。1. 检查WiFi名称密码确保设备在信号范围内。2. 确认settings.toml中键名与代码中os.getenv()完全一致。3. 在Adafruit IO网站确认Feed名称拼写。4. 使用Adafruit IO账户中的“Active Key”而非只读Key。从IO加载的俳句换行丢失Adafruit IO服务器对数据中的\n进行了转义。确保在Adafruit IO输入数据时使用了\n并且代码中执行了.replace(“\\n”, “\n”)操作。串口调试是王道当遇到任何问题时第一件事就是打开串口监视器。CircuitPython会将print()语句的输出以及运行时错误信息通过USB串口打印出来。使用Mu编辑器内置串口监视器或Thonny IDE选择正确的串口如COM3或/dev/ttyACM0波特率通常为115200。错误信息会明确指出问题所在行和原因比如ImportError: no module named ‘adafruit_io’库缺失或KeyError: ‘haikus’Feed名称错误。4.3 项目扩展与创意改造这个项目的框架具有很强的通用性稍加修改就能变身成各种有趣的应用名言/笑话/每日鸡汤显示器将haikus.txt改为quotes.txt或者将Adafruit IO的Feed改名为quotes。代码中加载和显示的逻辑完全不用变只需修改文件或Feed名称。你甚至可以设置一个定时任务每天从某个公开API如诗词API、笑话API获取一条新内容推送到Adafruit IO实现自动更新。简易信息看板利用Adafruit IO创建多个Feed分别存储天气、温度、日程、股票价格等信息。修改代码使其能轮询或按需获取这些Feed并使用displayio的多个Label或图形元素在屏幕上分区展示。交互式菜单系统利用四个按键实现上下左右选择和确认的功能。可以构建一个多级菜单用来控制设备设置如亮度、刷新间隔、切换显示模式等。低功耗优化目前代码主循环是while True会持续运行并检测按键功耗较高。可以引入alarm模块让设备在无操作一段时间后进入深度睡眠alarm.sleep_memory可以保存当前显示索引仅通过按键或定时器唤醒。这样配合电池续航时间可以延长数倍。更换字体与UIdisplayio支持绘制线条、矩形、圆形等基本图形。你可以完全重写UI部分比如将文本居中显示添加更复杂的背景图案或者使用不同的字体文件网上有很多开源BDF字体可供转换。adafruit_imageload也支持加载PNG等格式的图片让你的界面更加个性化。这个项目的魅力在于它用一个具体的例子串起了从硬件初始化、网络通信、数据解析、图形界面到用户交互的完整物联网应用链条。当你成功让它运行起来并看着自己添加的句子显示在那块低功耗的电子墨水屏上时那种亲手创造一件“智能物件”的成就感正是嵌入式开发最吸引人的地方。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2620072.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…