
1. 项目概述一个能“骗过”电脑的物理鼠标摇动器如果你和我一样经常需要长时间开着电脑处理文档、等待远程编译或者只是挂着某个需要保持“在线”状态的软件那么你一定对屏幕保护程序或者系统自动休眠深恶痛绝。动动鼠标就能解决但总忘记或者离开时不想让电脑休眠。市面上的软件方案要么有安全顾虑要么功能单一。今天分享的这个项目——MAUS就是一个用Arduino实现的硬件鼠标摇动器。它本质上是一个USB HID人机接口设备模拟器通过微控制器定时向电脑发送微小的鼠标移动指令让系统认为用户一直在操作从而阻止屏幕保护或休眠激活。这个项目的核心价值在于它的物理隔离性和高度可定制性。它不依赖电脑上的任何软件即插即用从根本上杜绝了软件方案可能带来的安全风险或杀毒软件误报。同时它基于开源的Arduino平台硬件成本极低核心部件成本通常在20元人民币以内并且我们可以在其基础上添加炫酷的RGB灯效把它从一个单纯的功能工具变成一个兼具实用与观赏性的桌面小摆件。接下来我将从设计思路、硬件搭建、代码编写到调试优化完整拆解如何制作一个属于你自己的、独一无二的MAUS。2. 核心硬件选型与电路设计解析制作MAUS硬件是基础。我们需要选择一个能够模拟USB鼠标的微控制器并为其设计最小系统电路。2.1 微控制器核心为何选择Arduino Pro Micro及其兼容板市面上常见的Arduino Uno/Nano虽然普及但其核心的ATmega328P芯片本身不具备原生的USB通信能力它依赖一个额外的USB转串口芯片如CH340、FT232与电脑通信这种架构无法直接模拟成USB鼠标或键盘。因此我们必须选择内置了USB功能的微控制器。ATmega32U4芯片是绝佳选择。它内置了USB控制器可以让设备将自己枚举为标准的USB HID设备如鼠标、键盘、游戏手柄。基于这颗芯片的开发板中Arduino Leonardo和Arduino Pro Micro最为常见。对于MAUS这种小型化项目Arduino Pro Micro是性价比和体积的最优解。它体积小巧价格低廉国产兼容版约15元并且引出了足够多的数字和模拟引脚供我们使用。注意购买时请务必确认板子型号是基于ATmega32U4的“Pro Micro”市面上也有基于ESP32或STM32的“Pro Micro”兼容板虽然功能更强大但初始配置和库支持不同对于新手会增加不必要的复杂度。认准ATmega32U4是关键。2.2 核心电路与外围元件设计一个最基本的MAUS只需要Arduino Pro Micro即可工作。但为了增加状态指示和炫酷效果我们计划加入两种LED板载红色LED用于指示基础工作状态如电源、简单的心跳。WS2812B RGB LED用于显示丰富的灯光模式这也是“享受放松灯光”的由来。电路连接非常简单电源Pro Micro通过USB接口直接取电。板载LED通常连接在Pro Micro的LED_BUILTIN引脚通常是D17对应RX_LED无需额外接线。WS2812B RGB LED这是一种智能控制LED只需要一根信号线。我们将其VCC接至Pro Micro的VCC5VGND接至GNDDIN数据输入接至Pro Micro的一个数字引脚例如D10。一颗WS2812B即可如需更多可串联。为什么选择WS2812B因为它采用单线归零码通信协议只需要微控制器的一个IO引脚就能控制串联起来的数十甚至上百颗LED的每一个像素的颜色极大地节省了IO资源并且有成熟的Adafruit_NeoPixel库支持编程非常方便。2.3 物料清单与成本估算为了让你能一次性采购齐全这里列出详细清单Arduino Pro Micro (ATmega32U4) 开发板 x1 【约15元】WS2812B RGB LED 5050封装 x1 【约1元】USB Micro-B 数据线用于供电和编程 x1 【约5元】可选洞洞板、杜邦线、外壳用于焊接和美化。总成本可以轻松控制在25元以内性价比远超任何成品。3. 软件环境搭建与核心代码剖析硬件准备就绪后我们需要让Arduino“学会”如何模仿鼠标。3.1 开发环境与必要库安装首先在电脑上安装Arduino IDE建议版本1.8.x或更新。安装后我们需要确保开发板支持。Arduino IDE默认可能没有Pro Micro的选项需要手动添加板管理器网址打开Arduino IDE点击文件-首选项。在“附加开发板管理器网址”中填入https://raw.githubusercontent.com/sparkfun/Arduino_Boards/master/IDE_Board_Manager/package_sparkfun_index.json点击工具-开发板-开发板管理器搜索“SparkFun AVR Boards”找到后安装。安装完成后在工具-开发板下就能选择“SparkFun Pro Micro”。接下来安装WS2812B的驱动库。点击项目-加载库-管理库搜索“Adafruit NeoPixel”找到由Adafruit维护的版本并安装。3.2 鼠标模拟核心代码实现Arduino Leonardo/Pro Micro的核心库Mouse.h提供了鼠标模拟功能。其原理是当我们在代码中调用Mouse.move(x, y, wheel)时微控制器会通过USB协议向主机发送对应的HID报告描述符电脑会将其识别为一个标准鼠标的移动或滚轮事件。下面是一个增强版的MAUS核心代码框架包含了可配置的摇动模式、随机性和RGB灯效#include Mouse.h #include Adafruit_NeoPixel.h // 配置区域 #define NEOPIXEL_PIN 10 // WS2812B连接的数字引脚 #define NUM_PIXELS 1 // 连接的WS2812B数量 #define JIGGLE_INTERVAL 30000 // 基础摇动间隔毫秒例如30秒 #define MOVE_PIXEL 1 // 每次移动的像素数1像素足够隐蔽 // 模式枚举 enum JiggleMode { MODE_REGULAR, // 规律性移动 MODE_RANDOM, // 随机时间间隔移动 MODE_FIGURE8 // 画“8”字轨迹 }; JiggleMode currentMode MODE_RANDOM; // 初始模式 Adafruit_NeoPixel pixels(NUM_PIXELS, NEOPIXEL_PIN, NEO_GRB NEO_KHZ800); // 用于计时和状态跟踪 unsigned long previousJiggleTime 0; int moveDirection 1; // 1表示向右/下-1表示向左/上 void setup() { // 初始化NeoPixel pixels.begin(); pixels.setBrightness(50); // 设置亮度0-255避免太刺眼 setStatusLED(0, 255, 0); // 启动时显示绿色 // 初始化鼠标库 Mouse.begin(); // 短暂延迟让电脑完全识别设备 delay(2000); setStatusLED(0, 0, 255); // 准备就绪显示蓝色 } void loop() { unsigned long currentMillis millis(); // 判断是否到达下一次摇动的时间 if (currentMillis - previousJiggleTime getNextInterval()) { performMouseJiggle(); updateLEDPattern(); previousJiggleTime currentMillis; } // 此处可以添加模式切换的触发条件例如通过按键 // checkModeSwitch(); } // 计算下一次摇动的间隔 unsigned long getNextInterval() { if (currentMode MODE_RANDOM) { // 随机间隔在0.5倍到1.5倍基础间隔之间更模拟人类行为 return random(JIGGLE_INTERVAL / 2, JIGGLE_INTERVAL * 3 / 2); } else { return JIGGLE_INTERVAL; } } // 执行鼠标移动动作 void performMouseJiggle() { switch (currentMode) { case MODE_REGULAR: // 简单的上下或左右1像素移动 Mouse.move(MOVE_PIXEL * moveDirection, 0, 0); moveDirection * -1; // 下次反方向移动 break; case MODE_RANDOM: // 在随机方向上移动1-2像素 Mouse.move(random(-2, 3), random(-2, 3), 0); break; case MODE_FIGURE8: // 画一个小“8”字轨迹简化版 static int figure8Step 0; int dx[4] {1, 0, -1, 0}; int dy[4] {0, 1, 0, -1}; Mouse.move(dx[figure8Step], dy[figure8Step], 0); figure8Step (figure8Step 1) % 4; break; } // 微小的延迟让移动更自然 delay(10); // 将鼠标移回原点附近避免光标真的跑远可选 // Mouse.move(-dx, -dy, 0); } // 更新RGB LED状态 void updateLEDPattern() { // 根据模式或状态改变LED颜色 switch (currentMode) { case MODE_REGULAR: setStatusLED(255, 165, 0); break; // 橙色 case MODE_RANDOM: setStatusLED(0, 255, 255); break; // 青色 case MODE_FIGURE8: setStatusLED(255, 0, 255); break; // 紫色 } // 可以添加更复杂的呼吸灯、彩虹循环效果 // rainbowCycle(10); } void setStatusLED(int r, int g, int b) { pixels.setPixelColor(0, pixels.Color(r, g, b)); pixels.show(); }代码关键点解析Mouse.begin()必须在setup()中调用初始化鼠标模拟功能。delay(2000)至关重要这给电脑操作系统留出了足够的时间来识别和加载这个新插入的“鼠标”驱动。如果没有这个延迟紧接着的Mouse.move()命令可能会被忽略导致设备失效。millis()非阻塞延时使用millis()记录时间而非delay()是为了让LED灯效或其他未来可能添加的功能如按键检测能够流畅运行不被鼠标移动的延时阻塞。随机化MODE_RANDOM模式通过random()函数在基础间隔上下浮动并且移动方向也是随机的这使得鼠标行为更接近真人无意识的微动比严格的周期性移动更难被一些高级的办公监控软件识别为“非人工活动”。像素移动量MOVE_PIXEL设置为1这是最小移动单位在屏幕上几乎不可见完全足够欺骗系统。移动幅度过大反而会干扰正常使用。4. 高级功能扩展与个性化定制基础功能实现后我们可以让MAUS变得更智能、更个性化。4.1 添加物理按键进行模式切换目前模式是写在代码里的。我们可以添加一个 tactile 按键连接到 Pro Micro 的某个引脚如 D9和 GND并启用内部上拉电阻。通过检测按键按下来循环切换工作模式并通过RGB LED的颜色来直观显示当前模式。#define MODE_BUTTON_PIN 9 int lastButtonState HIGH; int currentModeIndex 0; const int MODE_COUNT 3; void checkModeSwitch() { int buttonState digitalRead(MODE_BUTTON_PIN); if (buttonState LOW lastButtonState HIGH) { // 检测下降沿按下 delay(50); // 简单消抖 if (digitalRead(MODE_BUTTON_PIN) LOW) { // 确认按下 currentModeIndex (currentModeIndex 1) % MODE_COUNT; currentMode (JiggleMode)currentModeIndex; // 通过LED闪烁反馈模式切换 blinkLEDForMode(); } } lastButtonState buttonState; }4.2 实现丰富的WS2812B灯效利用Adafruit_NeoPixel库我们可以轻松实现呼吸灯、彩虹循环、颜色渐变等效果让MAUS成为桌面的氛围灯。例如一个简单的呼吸灯效果可以放在updateLEDPattern()中调用void breathingLED(uint32_t color) { static int breathDirection 1; static int brightness 0; brightness breathDirection * 5; if (brightness 255 || brightness 0) { breathDirection * -1; } pixels.setBrightness(brightness); pixels.setPixelColor(0, color); pixels.show(); }4.3 功耗优化与便携性考虑如果希望MAUS能通过移动电源长时间工作可以进行功耗优化在loop()的末尾如果没有任何事件需要处理可以添加一小段delay(10)或使用LowPower.idle()需安装LowPower库来让处理器休眠降低功耗。降低WS2812B的亮度pixels.setBrightness()是省电最有效的方法。可以考虑使用更省电的APA102DotStarLED但其接线稍复杂。5. 烧录、测试与疑难排解这是将代码变为现实的关键一步。5.1 烧录程序的具体步骤连接硬件用USB线将Pro Micro连接到电脑。注意首次插入时电脑会尝试安装驱动可能需要几分钟。选择开发板和处理器在Arduino IDE中工具-开发板选择“SparkFun Pro Micro”。处理器根据你实际购买的版本选择“ATmega32U4 (5V, 16MHz)”或“ATmega32U4 (3.3V, 8MHz)”市面上5V/16MHz的版本更常见。选择端口在工具-端口中选择新出现的COM口在Windows设备管理器中通常显示为“USB串行设备”或“Arduino Leonardo”。上传代码点击上传按钮向右箭头。关键步骤在代码编译完成后IDE底部状态栏会显示“上传”时需要快速短按一下Pro Micro板上的物理复位按钮。这是因为Pro Micro的bootloader等待上传的时间窗口很短需要手动复位进入。成功上传后IDE会显示“上传完毕”。5.2 功能测试与验证上传成功后MAUS会自动重启。此时电脑应该会发出“检测到新设备”的提示音并在“设置-蓝牙和其他设备-鼠标”中看到一个新的指针设备。测试方法打开一个文本文档将光标放在文本中间。观察光标是否每隔一段时间如30秒轻微抖动一下但不会打乱文本位置。打开系统“屏幕保护程序设置”将等待时间设为1分钟观察1分钟后屏幕保护是否被成功阻止。观察WS2812B LED是否按预设模式发光。5.3 常见问题与解决方案实录在实际制作过程中你可能会遇到以下问题这里是我踩过坑后的经验总结问题1电脑无法识别Pro Micro或上传代码时提示“在COMx上找不到设备”。排查首先检查USB线是否只充电不传数据换一根已知好的数据线。检查设备管理器端口中是否有未知设备或带感叹号的设备。解决尝试手动安装驱动。在设备管理器中右键点击未知设备-更新驱动程序-浏览我的电脑以查找驱动程序-让我从计算机上的可用驱动程序列表中选取-选择“通用串行总线设备”下的“USB串行设备”。如果还不行可能需要安装特定的驱动如https://github.com/sparkfun/Arduino_Boards/raw/master/IDE_Boards/drivers/FTDI%20Drivers/下的驱动但Pro Micro通常用CDC驱动非FTDI。问题2代码上传成功但鼠标指针不动。排查检查setup()函数中的delay(2000)是否足够。某些系统可能需要更长时间。解决将delay(2000)增加到delay(5000)再试。确保Mouse.begin()被成功调用。问题3鼠标指针移动幅度过大影响使用。排查检查代码中Mouse.move()的参数确保X和Y方向的移动量是±1或±2。解决将MOVE_PIXEL改为1。如果使用随机模式确保random()的范围是(-2, 3)这样的小范围。问题4WS2812B LED不亮或颜色异常。排查首先确认接线正确VCC-5V, GND-GND, DIN-D10。检查代码中NEOPIXEL_PIN的定义是否与实际连接引脚一致。解决WS2812B对时序要求严格尝试在pixels.begin()前加一小段延时delay(500)。确保pixels.setPixelColor()和pixels.show()被正确调用。问题5设备在某些安全严格的办公电脑上被禁用。现象插入后鼠标键盘可能被锁死几秒然后设备被禁用。分析与应对这是最棘手的情况。一些企业级终端安全软件会监控和限制未经授权的HID设备。MAUS作为一个新的“鼠标”可能触发策略。这不是MAUS的缺陷而是安全软件的预期行为。对此没有完美的软件解决方案。硬件上可以尝试将设备标识信息PID/VID修改成更常见的鼠标品牌这涉及修改Arduino核心库有一定难度和风险。最务实的建议是仅在个人设备或得到许可的环境中使用。制作这样一个MAUS从硬件焊接、代码编写到调试完成整个过程大约需要1-2个小时。它带给你的不仅仅是一个防休眠工具更是一次完整的嵌入式开发实践。当你看到自己亲手制作的小设备闪烁着定制的灯光安静地帮你“欺骗”电脑时那种成就感是购买任何成品都无法替代的。更重要的是你完全掌握了它的所有细节可以根据自己的需求随时调整它的行为这才是创客精神的精髓所在。