Skip to content

Arduino - 键盘注销

本教程演示如何使用 Arduino 兼容开发板作为 USB 人机接口设备(HID)来模拟键盘。具体来说,我们将创建一个设备,当按下按钮时,它会发送一个特定于操作系统的键盘快捷键来注销您的计算机。这个项目展示了具有原生 USB 功能的开发板的强大之处,它们可以直接与主机电脑进行交互。

⚠️ 重要警告: 当您使用 Keyboard 库时,Arduino 可以完全控制您电脑的键盘。为防止意外地将自己锁定在电脑之外或发送意料之外的命令,请务必实现一个可靠的物理触发器,例如本教程中使用的按钮。对于更长期的项目,请考虑添加一个主开关。

您将需要以下组件:

  • 1 × 面包板
  • 1 × 具有原生 USB HID 支持的 Arduino 开发板。例如:Arduino Leonardo、Micro、Due、Zero,或任何 MKR 系列开发板。树莓派 Pico(运行 Arduino 核心)也是一个不错的选择。
  • 1 × 按钮
  • 跳线

我们将使用现代的 Arduino IDE 2.x。Keyboard.h 库与支持 HID 的开发板支持包捆绑在一起,因此您通常无需手动安装它。如果需要安装,请使用库管理器(工具 > 管理库...)来查找和安装。

电路很简单。我们将一个按钮连接到一个数字引脚,并使用微控制器内部的上拉电阻。这消除了对外部电阻的需求。

  • 将按钮的一个引脚连接到数字引脚(我们将使用引脚 2)。
  • 将按钮的另一个引脚连接到 Arduino 上的 GND 引脚。
  • 当按钮按下时,它将连接引脚 2 到地,将引脚的状态从高电平拉低到低电平。
/*
键盘注销 - 现代化示例
此草图演示了如何使用 Keyboard 库在按下按钮时发送系统注销
命令。它支持 Windows、macOS 和 Linux (Ubuntu)。
此代码适用于具有原生 USB 支持的开发板,如 Leonardo、Micro、Due、MKR 系列或 RP2040 开发板。
电路:
- 一个瞬时按钮连接在数字引脚 2 和 GND 之间。
*/
#include "Keyboard.h"
// --- 配置 ---
// 在此处设置您的目标操作系统
// 选项:OS_WINDOWS, OS_MACOS, OS_LINUX
#define TARGET_OS OS_WINDOWS
// 用于更好平台管理的枚举
enum OperatingSystem {
OS_MACOS,
OS_WINDOWS,
OS_LINUX
};
// 使用 'const' 定义引脚号是良好实践
const int buttonPin = 2;
// --- Setup 函数 ---
void setup() {
// 将按钮引脚初始化为带内部上拉电阻的输入模式。
// 默认情况下引脚为高电平,按下按钮时为低电平。
pinMode(buttonPin, INPUT_PULLUP);
// 初始化键盘模拟。
Keyboard.begin();
}
// --- 主循环 ---
void loop() {
// 检查按钮是否按下(引脚为低电平)
if (digitalRead(buttonPin) == LOW) {
// 短暂延迟以进行按钮去抖。
delay(50);
// 等待按钮释放以避免多次触发
while (digitalRead(buttonPin) == LOW) {
// 当按钮按住时不做任何事
}
// 执行注销序列
performLogout();
// 暂停程序以防止意外重复注销。
// 您需要重置开发板才能再次运行代码。
while (true);
}
// 短暂延迟以防止循环运行过快
delay(100);
}
// --- 注销函数 ---
void performLogout() {
// 在发送按键之前短暂延迟,以便操作系统有时间聚焦
delay(1000);
switch (TARGET_OS) {
case OS_MACOS:
// 在 macOS 上:Command + Shift + Q,然后回车
Keyboard.press(KEY_LEFT_GUI); // 按下 Command 键
Keyboard.press(KEY_LEFT_SHIFT); // 按下 Shift 键
Keyboard.press('q');
delay(100);
Keyboard.releaseAll();
delay(1000); // 等待确认对话框
Keyboard.press(KEY_RETURN);
break;
case OS_WINDOWS:
// 在 Windows 10/11 上:Win + X,然后 U,然后 I(注销)
Keyboard.press(KEY_LEFT_GUI); // 按下 Windows 键
Keyboard.press('x');
delay(100);
Keyboard.releaseAll();
delay(500); // 等待菜单出现
Keyboard.press('u');
delay(100);
Keyboard.releaseAll();
delay(500);
Keyboard.press('i');
break;
case OS_LINUX: // 假设是基于 GNOME 的发行版,如 Ubuntu
// 在 Ubuntu 上:Ctrl + Alt + Delete,然后回车
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press(KEY_DELETE);
delay(100);
Keyboard.releaseAll();
delay(1500); // 等待注销对话框
Keyboard.press(KEY_RETURN);
break;
}
// 释放所有按键作为最后的安全措施
Keyboard.releaseAll();
}
  • #define TARGET_OS ...:这个预处理指令允许您在上传代码前轻松地为您的特定操作系统配置代码。
  • const int buttonPin = 2;:我们使用常量来定义按钮引脚。这是一种现代 C++ 实践,可以提高代码可读性并防止意外修改引脚号。
  • pinMode(buttonPin, INPUT_PULLUP);:这会将引脚配置为输入模式并激活内部上拉电阻。这是一种无需外部元件即可连接按钮的有效方式。
  • if (digitalRead(buttonPin) == LOW):代码持续检查按钮的状态。由于上拉电阻的存在,低电平信号意味着按钮已被按下。
  • 去抖和释放检测:短暂的 delay(50) 和等待按钮释放的 while 循环构成了一个简单但有效的去抖机制。这确保了每次按钮按下只触发一次动作。
  • performLogout():此函数封装了特定于操作系统的逻辑,使主循环更简洁。switch 语句根据 TARGET_OS 选择正确的按键序列。
  • Keyboard.press() 和 Keyboard.releaseAll():Keyboard.press() 模拟按住一个键。它用于组合键。Keyboard.releaseAll() 释放所有当前按下的键,这对于避免“卡键”状态至关重要。
  • 代码无法编译或找不到 Keyboard:您可能正在使用没有原生 USB 支持的开发板(例如,Arduino UNO R3、Nano)。您必须使用兼容的开发板,如 Leonardo 或 Micro。
  • 按下按钮没有反应:仔细检查您的接线。确保按钮连接到正确的引脚和 GND。另外,验证您在 Arduino IDE 中选择了正确的开发板。
  • 电脑上发生了错误的操作:注销的键盘快捷键在不同操作系统版本和发行版之间可能有所不同。您可能需要调整 performLogout() 函数中的按键以匹配您的特定系统。

这个简单的项目是创建强大自定义 USB 设备的门户:

  • 自定义宏键盘:扩展项目,增加更多按钮以触发 Photoshop、VS Code 或 OBS 等软件中的复杂快捷键。
  • 辅助设备:为运动障碍用户创建自定义界面。
  • 物理静音按钮:构建一个专用硬件按钮,用于发送 Zoom 或 Microsoft Teams 等视频会议应用程序的静音/取消静音快捷键。
  • 安全提示:请注意,这项技术可用于创建恶意设备(通常称为“BadUSB”)。插入未知 USB 设备到您的电脑时务必小心。