基于BLE与CircuitPython的无线8-bit音乐合成器DIY全攻略

news2026/5/15 23:01:49
1. 项目概述与核心思路想不想亲手做一个能揣在口袋里随时随地弹奏出复古8-bit音乐的小玩意儿不是那种手机App模拟的而是实实在在的、有物理按键、能无线连接、还会发光的小合成器。今天分享的这个项目就是基于两块小巧但功能强大的Adafruit开发板——Feather nRF52840和Circuit Playground Bluefruit通过蓝牙低功耗BLE技术打造一个完全无线的音乐合成器。键盘和音箱分离中间没有一根线缆的束缚这才是真正的“无线”音乐创作。这个项目的核心思路非常清晰将输入按键和输出声音与灯光分离并通过无线技术连接。Feather nRF52840开发板扮演了“键盘”的角色它上面焊接了12个物理按键每个按键对应一个音符从C4到B4。当你按下某个键时它不会自己发声而是通过BLE向另一端的“音箱”——Circuit Playground Bluefruit发送一个特定的信号包。Circuit Playground Bluefruit收到信号后会做两件事一是驱动其板载的NeoPixel LED灯环呈现出与音符对应的彩色流光动画二是通过一个外接的STEMMA Speaker放大器播放出对应音符的纯净方波音调。整个过程从按键到声光反馈都是无线完成的。这种架构有几个实实在在的好处。首先布线极其简洁。你不需要为了把键盘和音箱连在一起而拉一根长长的音频线或数据线整个系统看起来非常清爽也便于携带和摆放。其次扩展性很强。理论上一个“音箱”可以接收来自多个“键盘”的信号甚至可以尝试做一些简单的多键盘合奏。最后它完美结合了硬件制作焊接、3D打印和软件编程CircuitPython的乐趣是一个综合性很强的创客项目既能锻炼动手能力又能深入理解无线通信和嵌入式音频的基础原理。2. 硬件选型与电路设计解析2.1 核心控制器为何是它们这个项目的灵魂是两块开发板它们的选型直接决定了项目的可行性和体验。Feather nRF52840 Express选择它作为键盘主控首要原因就是其内置的nRF52840芯片。这颗芯片是Nordic Semiconductor的明星产品集成了一个强大的ARM Cortex-M4F内核和一款完全兼容蓝牙5.0的射频模块。对于我们的项目而言它最关键的能力是原生、高效地支持BLE。CircuitPython社区为这块板子提供了优秀的adafruit_ble库支持使得用Python代码实现BLE通信变得像调用普通函数一样简单。此外Feather板型提供了丰富的GPIO引脚我们用了12个来连接按键以及一个用于指示连接状态的蓝色LED硬件资源刚好够用且不浪费。Circuit Playground Bluefruit这块板子堪称“创客瑞士军刀”选择它作为音频和灯光输出端再合适不过。它同样基于nRF52840保证了与Feather之间BLE通信的兼容性和低功耗。其不可替代的优势在于丰富的板载资源10个可编程的RGB NeoPixel LED让我们无需额外焊接就能实现酷炫的灯光效果一个质量不错的板载扬声器以及一个专用的音频输出引脚A0可以直连外部放大器提升音量。更重要的是它有一个标准的STEMMA QT连接器可以像乐高一样即插即用地连接各种传感器和执行器比如本项目中的STEMMA Speaker放大器这大大简化了硬件连接。注意虽然两块板子都用了nRF52840但它们的CircuitPython固件和库支持是分别针对其板载外设进行优化的不能混刷固件。务必从Adafruit官网下载对应板型的最新版CircuitPython。2.2 外围电路设计从原理到实现整个项目的电路可以分为键盘和音箱两个独立部分它们之间仅通过BLE无线电波联系。2.2.1 键盘部分电路键盘电路的核心是12个按键的矩阵扫描。但为了极致简化本项目采用了最直接的方式12个独立按键每个按键一端接GPIO另一端统一接地GND。每个GPIO引脚都配置为内部上拉输入Pull.UP。当按键未按下时引脚通过内部电阻被拉到高电平True或1当按键按下时引脚直接与GND短路读到低电平False或0。这种方式的优点是电路和代码都非常简单直观每个按键独立互不影响。缺点是占用了12个宝贵的IO口好在Feather nRF52840刚好能满足。引脚分配如下D5, D6, D9, D10, D11, D12, D13, A0, A1, A2, A3, A4。这里跳过了D0、D1通常用于串口调试和一些用于特殊功能如USB、电池监测的引脚。此外键盘部分还增加了一个滑动开关连接在Feather的EN使能引脚和GND之间。EN引脚是芯片的复位/使能引脚默认通过内部电阻上拉至高电平。当开关闭合将EN与GND短接时会强制芯片复位并保持复位状态相当于一个硬件开关机功能。这是一个非常实用的设计避免了频繁插拔USB线来断电。2.2.2 音箱部分电路音箱部分的电路更简单核心是STEMMA Speaker放大器与CPB的连接。STEMMA Speaker是一个集成了D类功放的小模块只需要三根线POWER (VIN)接CPB的3.3V输出引脚为功放芯片供电。GND接CPB的GND形成共地。SIGNAL (IN)接CPB的A0音频输出引脚。CPB内部可以通过cpb.start_tone(frequency)函数在A0引脚产生指定频率的方波信号。电源方面CPB可以通过其JST PH接口连接一个3xAAA电池盒。电池盒自带物理开关可以控制整个音箱部分的供电。这种设计让音箱可以完全脱离USB线实现真正的移动使用。2.3 两种键盘实现方案PCB与万用板原作者提供了两种键盘硬件的实现路径这体现了创客项目的灵活性。PCB印刷电路板方案这是最优雅、最稳定的方案。作者提供了设计好的Eagle文件你可以直接发给PCB打样厂生产。PCB上已经规划好了12个按键的位置、与Feather引脚对应的走线以及开关的焊盘。你只需要把按键和排针焊上去即可成品整洁、专业并且可靠性高。对于想要完美外观和稳定性的朋友这是首选。万用板Perfboard方案这是更通用、更体现手工焊接乐趣的方案。你需要用两小块万用板按照一定间距文中建议5个孔距来布置12个按键。通过飞线将每个按键的一端连接到对应的Feather GPIO引脚另一端全部“菊花链”式地串联到GND。开关也需要通过飞线连接到EN和GND。这个方案的好处是材料易得电子市场随处可买万用板并且制作过程能让你更深刻地理解电路的连接关系。缺点是焊接工作量稍大且成品的美观度和坚固度取决于你的手工。实操心得如果你选择万用板方案强烈建议在焊接前用万用表的导通档仔细检查每一条飞线连接。特别是GND的“菊花链”任何一个虚焊或短路都可能导致多个按键失灵。焊接时可以先用胶带将按键临时固定在板子上焊好一个引脚确保位置正确后再焊接其余引脚。3. 软件环境搭建与代码深度剖析3.1 CircuitPython环境配置要让这两块板子听你的话第一步就是给它们刷入“灵魂”——CircuitPython固件。进入Bootloader模式Feather nRF52840快速双击板载的RESET按钮。此时电脑上会出现一个名为FTHR840BOOT的U盘。Circuit Playground Bluefruit同样快速双击板载的RESET按钮。电脑上会出现一个名为CPLAYBTBOOT的U盘。 如果连接后直接出现名为CIRCUITPY的盘符说明板子已经预装了CircuitPython可以跳过刷机步骤。下载并安装固件访问Adafruit的CircuitPython官网找到对应板型的最新版.uf2固件文件。将下载的.uf2文件直接拖拽或复制到刚刚出现的FTHR840BOOT或CPLAYBTBOOTU盘中。板子会自动重启之后U盘名称会变为CIRCUITPY。安装必要的库文件 项目代码依赖几个外部库。最简单的方法是下载项目打包文件Project Bundle。解压后你会看到两个文件夹cpb_amp_code用于CPB和feather_keyboard_code用于Feather。将对应文件夹lib子目录下的所有.mpy或.py文件复制到各自板子CIRCUITPY盘符下的lib文件夹中。如果lib文件夹不存在就新建一个。部署主程序 将feather_keyboard_code目录下的code.py复制到Feather的CIRCUITPY根目录。同理将cpb_amp_code目录下的code.py复制到CPB的CIRCUITPY根目录。CircuitPython会自动运行根目录下的code.py文件。3.2 键盘端代码详解Feather nRF52840键盘端代码的核心任务是检测按键状态并通过BLE发送对应的颜色数据包。# 关键代码段按键扫描与BLE发送 while uart_connection and uart_connection.connected: for switch_pin in switch_array: i switch_array.index(switch_pin) switches_pressed_state switches_pressed[i] colors color[i] # 1. 检测按键释放先于按下检测 if switch_pin.value and switches_pressed_state: print(button off) # 发送“RIGHT按钮按下”包通知CPB停止发声 if not send_packet(uart_connection, ButtonPacket(ButtonPacket.RIGHT, pressedTrue)): uart_connection None continue switches_pressed[i] False time.sleep(0.05) # 2. 检测按键按下 if not switch_pin.value and not switches_pressed_state: # 发送与当前按键索引对应的颜色包 if not send_packet(uart_connection, ColorPacket(colors)): uart_connection None continue switches_pressed[i] True time.sleep(0.05)代码逻辑精讲状态去抖Debouncing代码为每个按键维护了一个状态变量switches_pressed[i]。只有当引脚电平为低按键按下且状态记录为False之前未按下时才判定为一次有效的“按下”事件并发送数据包。这有效防止了因按键触点抖动导致的多次误触发。“释放”优先检测注意代码中先检查按键是否释放switch_pin.value and switches_pressed_state再检查是否按下。这是一个巧妙的处理。因为物理按键的“按下”和“释放”事件是紧接着发生的。如果先处理“按下”可能会在单次循环中快速连续触发“按下”和“释放”导致逻辑混乱。先处理“释放”能确保每次“按下”事件后状态被置为True直到下一次真实的“释放”事件到来时才被清除逻辑更清晰。双包协议设计这是本项目通信协议的关键。按下时发送ColorPacket包含颜色信息释放时发送ButtonPacket类型为RIGHT。CPB端依靠ColorPacket来触发播放音调和灯光依靠ButtonPacket来停止播放。这实现了音符的持续发音与释放止音模拟了真实乐器的行为。如果只发按下包音符将会一直响下去。3.3 音箱端代码详解Circuit Playground Bluefruit音箱端代码的核心任务是监听BLE连接接收数据包并控制灯光和声音。# 关键代码段数据包处理 if isinstance(packet, ColorPacket): for i in range(12): colors color[i] notes note[i] if packet.color colors and not tone: animations.color colors # 设置流光颜色 cpb.start_tone(notes) # 播放对应频率的音调 tone True # 设置“正在发音”状态 elif isinstance(packet, ButtonPacket) and packet.pressed: if packet.button ButtonPacket.RIGHT and tone: tone False cpb.stop_tone() # 停止发音 animations.color off # 灯光颜色设为熄灭但动画继续代码逻辑精讲颜色-音符映射代码中定义了两个长度均为12的数组color[]和note[]。它们按相同的索引顺序排列分别对应C, C#, D...B这12个音符的颜色和频率。当收到一个ColorPacket时程序会遍历颜色数组进行匹配。一旦匹配成功就用相同索引i从note[]数组中取出对应的频率值进行播放。这种设计使得通信协议非常简洁Feather只需要发送颜色信息CPB就能自行映射到正确的音高。动画与声音的同步控制使用adafruit_led_animation库的Comet彗星动画产生灯光在LED环上旋转流动的效果。当收到颜色包时不仅播放声音还将动画的主色设置为该颜色。当收到按钮包时停止声音并将动画颜色设置为(0,0,0)熄灭但动画对象本身仍在运行。这样灯光会立即熄灭但彗星动画的位置和运动状态得以保留为下一次按键触发做好了准备视觉上过渡更平滑。状态机防重复触发tone变量在这里充当了一个简单的状态机。只有当tone为False没有音符在响时才处理新的ColorPacket并开始播放。这防止了在同一个音符持续按下期间代码重复触发start_tone。只有当收到ButtonPacket后tone被重置为False才允许播放下一个音符。3.4 BLE通信机制剖析两个设备间的BLE通信建立在UART服务UARTService之上。这是一种模拟串口通信的BLE服务让开发者可以像操作有线串口一样通过read()和write()函数来收发数据极大简化了无线编程。连接建立CPB作为外设Peripheral持续广播自己提供了UART服务。Feather作为中心设备Central不断扫描周围设备。当Feather发现CPB的广播并识别出UART服务后便发起连接。连接成功后Feather板载的蓝色LED会点亮作为指示。数据封装与解析我们并非直接发送原始字节。Adafruit的adafruit_bluefruit_connect库定义了更高层的“数据包”对象如ColorPacket和ButtonPacket。这些对象内部会按照约定的格式将数据如RGB值、按钮类型序列化成字节流通过UART服务发送。接收方再用Packet.from_stream()方法解析还原成数据包对象。这种方式比处理原始字节流更安全、更便捷。连接稳定性代码中包含了基本的连接状态检查。如果发送数据包失败send_packet函数返回False程序会尝试断开连接并将连接对象置空然后重新进入扫描连接流程。这提高了无线环境下的鲁棒性。4. 外壳制作与整体组装4.1 3D打印文件处理与打印要点作者在Thingiverse上提供了所有外壳的STL文件。使用这些文件前有几点需要注意键盘琴键这些键帽设计用于套在那种圆形顶部的贴片微动开关上。打印时无需支撑建议使用PLA材料填充率15%-20%即可。键帽的底部开口尺寸可能与你的开关略有差异如果太紧可以用小刀或砂纸稍微修整内壁如果太松可以在开关顶部涂抹少量热熔胶再套上键帽。音箱外壳这个模仿吉他放大器的小盒子设计为卡扣式Snap-fit组装同样无需支撑。打印时请确保打印机床调平良好以保证底面平整使前后盖能严丝合缝。外壳正面有扬声器网孔图案背面有电池仓开口。板子的固定孔位M3和M2.5比较精确如果螺丝拧入困难可以用合适尺寸的钻头或手捻钻轻轻通一下孔。键盘底座PCB/万用板版本针对两种键盘方案提供了不同的底座。PCB版本的底座带有螺柱孔位需要用M2的螺柱和螺丝固定。万用板版本则是一个浅托盘依靠边缘的卡唇将电路板固定在内。打印时注意底座的底板是否容易翘边可以开启打印平台的裙边Brim功能来增加附着力。实操心得对于这种功能性外壳层高Layer Height设置为0.2mm是精度和打印速度的良好平衡。如果追求更光滑的表面可以降到0.16mm或0.12mm但打印时间会大幅增加。组装前最好将所有打印件用砂纸打磨一下边缘的毛刺并试装一下确保开关、接口的位置都对得上。4.2 分步组装指南音箱部分组装将Circuit Playground Bluefruit的正面带有NeoPixel灯环的一面朝向音箱外壳的内侧用M3螺丝将其固定在外壳盖板背面的对应支柱上。这样灯光才能透过外壳的网孔透出来。同样将STEMMA Speaker的正面带有Adafruit标志的一面也朝向内侧用M2.5螺丝固定在其对应的位置。使用一根3Pin的STEMMA连接线将CPB的STEMMA接口与STEMMA Speaker的接口连接起来。注意线序通常是红色VIN、黑色GND、白色SIGNAL但最好对照板子上的丝印确认。将3xAAA电池盒的JST插头插入CPB的电池接口。把电池盒和多余的线缆整理好放入外壳内部空间。合上音箱的前后盖听到卡扣“咔哒”声即表示组装到位。键盘部分组装以PCB版本为例将M2螺柱拧入3D打印底座的固定孔中。将焊接好所有按键和排针的PCB板对准螺柱轻轻放下去。从PCB上方拧入M2螺丝将PCB紧固在底座上。将Feather nRF52840开发板插入PCB上的排母中。注意方向USB接口应朝向键盘后方以便接线。最后将12个3D打印的键帽按照你喜欢的颜色顺序一一按压到微动开关的顶部。万用板版本的组装则更为简单只需将焊接好的整个万用板组件对准浅托盘外壳的内部轮廓轻轻按压使其边缘卡入外壳的卡唇之下即可。确保所有按键都能被顺利按下且Feather板上的开关和USB口没有被外壳遮挡。5. 使用、调试与扩展思路5.1 首次使用与连接测试组装完成后首次使用的步骤如下分别打开键盘通过滑动开关和音箱通过电池盒开关的电源。观察Feather nRF52840板上的蓝色LED。大约几秒内如果BLE连接成功这颗LED会常亮。这是最重要的连接状态指示。连接成功后随意按下键盘上的一个键。你应该立即听到音箱发出一个清脆的8-bit音调同时Circuit Playground Bluefruit周围的NeoPixel灯环会亮起并旋转出对应颜色的流光。松开按键声音应立即停止灯光熄灭但动画背景可能仍在运行。5.2 常见问题排查速查表问题现象可能原因排查步骤上电后无任何反应1. 电源未接通2. 电池电量耗尽3. 硬件短路导致保护1. 检查键盘滑动开关和音箱电池盒开关是否打开。2. 更换新的AAA电池。3. 检查USB线是否连接可靠如果使用USB供电。4. 断开电源用万用表检查键盘和音箱板子上是否有明显的短路特别是VCC和GND之间。蓝色LED不亮无连接1. BLE未成功配对2. 其中一块板子程序未运行3. 天线或射频问题罕见1.先给音箱CPB上电再给键盘Feather上电确保CPB先进入广播状态。2. 分别将两块板子通过USB连接到电脑查看CIRCUITPY盘符是否存在code.py文件是否在根目录。3. 打开串口监视器如Mu编辑器查看Feather的打印输出是否卡在Scanning...。按下按键有灯光但无声音1. 音箱音量过低或静音2. STEMMA Speaker连接错误或损坏3. CPB音频输出引脚配置错误1. 检查STEMMA Speaker上的音量电位器是否被调到最小。2. 重新拔插STEMMA连接线确认VIN、GND、SIGNAL三线连接正确。3. 临时修改CPB代码尝试用cpb.play_tone(440, 1.0)驱动其板载扬声器以判断是主板问题还是外接放大器问题。按下按键无灯光也无声音1. 特定按键硬件故障2. BLE连接已断开3. 代码中按键引脚定义错误1. 检查该按键焊接是否牢固用万用表测量按下时是否导通。2. 观察Feather蓝色LED是否仍亮着。尝试复位两块板子按RESET键重新连接。3. 核对代码中switch_pins数组的引脚定义是否与实际焊接的引脚一致。声音或灯光有延迟、卡顿1. BLE信号干扰或距离过远2. 代码中延时不当3. 电源供电不足1. 确保两设备在无障碍物的近距离3米内使用远离Wi-Fi路由器、微波炉等强干扰源。2. 检查代码中time.sleep(0.05)的延时如果觉得反应慢可以尝试减小到0.03或0.02但过小可能导致去抖失效。3. 音箱使用全新的碱性电池键盘如果使用USB供电确保USB口能提供足够电流500mA以上。音符音高不准或不对1. 代码中音符频率数组note[]顺序错误2. 按键物理顺序与代码逻辑顺序不匹配1. 对照标准音高如A4440Hz检查code.py中note数组的数值是否正确。2. 这是最常见的问题按下键盘从左到右的键记录下发出的音符。与代码中color和note数组的顺序C, C#, D... B对比。如果不匹配需要调整按键到Feather引脚的物理连接顺序或者调整代码中数组的顺序。5.3 项目扩展与魔改灵感这个项目是一个绝佳的基础平台你可以在此基础上尽情发挥创意扩展音域与和弦12个键只有一个八度。你可以增加更多按键定义更多音符甚至实现按下单个键触发一个和弦同时发送多个频率值。这需要修改Feather的代码使其能处理组合键并让CPB能同时播放多个音调CircuitPython的audiocore或audiomixer库可能派上用场。更换音色引擎目前是简单的方波音色单一。你可以探索CircuitPython的音频库尝试生成锯齿波、三角波甚至加载简短的WAV采样来作为音源让合成器的声音更丰富。加入效果器在CPB端代码中可以在声音输出前加入数字效果比如简单的延迟Echo、颤音Vibrato或低通滤波模拟衰减。这需要对音频信号处理有一定了解。设计更复杂的灯光效果利用adafruit_led_animation库中其他的动画如彩虹、火花、脉动等或者根据按压力度如果使用模拟压力传感器或电容触摸代替按键来改变灯光亮度和颜色。无线MIDI控制器将Feather键盘改造成一个无线MIDI控制器。通过BLE发送标准的MIDI信息Note On, Note Off这样它就可以控制电脑、手机或硬件合成器里的任何软件音源用途瞬间扩大无数倍。Adafruit也有相关的MIDI over BLE库可供研究。外壳艺术化3D打印外壳提供了完美的画布。可以对其进行打磨、喷漆、贴纸甚至用丙烯颜料手绘把它变成一件独一无二的艺术品。这个项目的魅力在于它清晰地演示了从概念到实物的完整链路。当你按下自己焊接的按键听到通过自己编写的无线协议传来的、从自己组装的外壳里发出的声音时那种成就感是无可替代的。希望这份详细的指南能帮你顺利复现这个有趣的项目并点燃你更多创造的灵感。

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