极客秀
搜索

鸡胸肉键盘?看我复刻之…..C#软件大杂烩(1.4)串口映射键盘

今天在抖音冲浪,突然刷到了某佬用鸡胸肉当键盘。


OK,这东西熟悉呀,好酷。 我在家疯狂寻找。


OK,鸡胸肉和开发板都有。我直接开做。 ** 本文源码会上传于交流群: 656210280 **

感兴趣的小伙伴可以加群一起探讨🤪🤪

原理阐述 由于人体在接触ESP32的IO时会导致电容值发生变化,ESP32总共有 十个可以直接读取电容的IO
,我们可以利用电容量变化来判断我们是否按下。

在Arduino IDE中利用以下函数读取触摸传感器


for(;;)  {    Serial.print("A:");    Serial.println(touchRead(4));    delay(10);  }

用上述代码,我们进行测试。

可以发现,在空置的时候,触摸传感器的值在80作用,当我们触摸IO(我拉了根杜邦线)的时候,电容的值会降到10+。变化非常明显。
知道这个原理,我们加点判断逻辑,即可实现触摸的检测。 接下来写一个上位机程序


      using System.Management;      using System.Runtime.InteropServices;             [DllImport("user32.dll", SetLastError = true)]       static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);  
       struct INPUT       {           public int type;           public InputUnion u;       }  
       [StructLayout(LayoutKind.Explicit)]       struct InputUnion       {           [FieldOffset(0)]           public MOUSEINPUT mi;           [FieldOffset(0)]           public KEYBDINPUT ki;           [FieldOffset(0)]           public HARDWAREINPUT hi;       }  
       struct MOUSEINPUT       {           public int dx;           public int dy;           public uint mouseData;           public uint dwFlags;           public uint time;           public IntPtr dwExtraInfo;       }  
       struct KEYBDINPUT       {           public ushort wVk;           public ushort wScan;           public uint dwFlags;           public uint time;           public IntPtr dwExtraInfo;       }  
       struct HARDWAREINPUT       {           public uint uMsg;           public ushort wParamL;           public ushort wParamH;       }  
       const int INPUT_KEYBOARD = 1;       const uint KEYEVENTF_KEYUP = 0x0002;  
       public static void SendKey(ushort key, bool keyUp)       {           INPUT[] inputs = new INPUT[]           {           new INPUT           {               type = INPUT_KEYBOARD,               u = new InputUnion               {                   ki = new KEYBDINPUT                   {                       wVk = key,                       wScan = 0,                       dwFlags = keyUp ? KEYEVENTF_KEYUP : 0,                       time = 0,                       dwExtraInfo = IntPtr.Zero                   }               }           }           };  
           SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));       }       char boolc;       private void SendKeysToApplication(string input)       {           foreach (char c in input)           {               if(c!='T')               {                   SendKey(c, true);                   boolc = c;               }               else               {                   SendKey(boolc, false);               }           }       }

我们调用系统API将我们接收到的文本转化为键盘硬件输出(有些游戏会把模拟键盘视作外挂(英雄联盟我试了不行))并且在串口接收的部分调用这个函数。
System.Management 用于管理和操作Windows管理信息。 System.Runtime.InteropServices
用于在托管代码和非托管代码之间进行工作,特别是用于调用Windows API。

[DllImport("user32.dll", SetLastError = true)]static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

这是 SendInput 函数的声明,它来自user32.dll(一个Windows系统库),用于插入键盘或鼠标输入事件到Windows的消息队列。
SetLastError = true 表示如果函数调用失败,可以使用 Marshal.GetLastWin32Error() 来获取错误代码。 **
结构体定义 ** 代码中定义了几个结构体,它们对应于 SendInput 函数所需的参数。


struct INPUT{    public int type;    public InputUnion u;}

type 表示输入类型,例如键盘输入(INPUT_KEYBOARD)。 u 是一个联合体,可以表示鼠标、键盘或硬件输入。


[StructLayout(LayoutKind.Explicit)]struct InputUnion{    [FieldOffset(0)]    public MOUSEINPUT mi;    [FieldOffset(0)]    public KEYBDINPUT ki;    [FieldOffset(0)]    public HARDWAREINPUT hi;}  

一个具有显式布局的结构体,其成员共享相同的内存位置(所有成员的 FieldOffset 都是0)。这意味着 mi、ki 和 hi
实际上是互相重叠的,这个结构体在任何时候只能表示其中一种输入。MOUSEINPUT, KEYBDINPUT, HARDWAREINPUT
结构体这些结构体包含了模拟鼠标、键盘和硬件输入所需 的具体信息。

  • 最后 SendKey 中,第一个参数是字符,第二个参数是模拟按下还是释放

在之前的串口助手中将模拟键盘功能加上。 我们测试一遍发现没有问题。 直接上幻兽帕鲁测试

1.转载请保留原文链接谢谢!
2.本站所有资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
3.本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户擦亮眼睛自行鉴别,做一个有主见和判断力的用户。
4.本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
5.联系方式(#替换成@):pm#vimge.com

  相关内容