<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mengjie zhang</title>
    <description>The latest articles on DEV Community by mengjie zhang (@mengjie_zhang_3a78014a849).</description>
    <link>https://dev.to/mengjie_zhang_3a78014a849</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3956703%2F3885f929-eb8e-4eb3-be69-04e6a7348a37.png</url>
      <title>DEV Community: mengjie zhang</title>
      <link>https://dev.to/mengjie_zhang_3a78014a849</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mengjie_zhang_3a78014a849"/>
    <language>en</language>
    <item>
      <title>Phone-as-keyboard for any USB host — building a driverless HID bridge</title>
      <dc:creator>mengjie zhang</dc:creator>
      <pubDate>Thu, 28 May 2026 17:00:08 +0000</pubDate>
      <link>https://dev.to/mengjie_zhang_3a78014a849/phone-as-keyboard-for-any-usb-host-building-a-driverless-hid-bridge-92a</link>
      <guid>https://dev.to/mengjie_zhang_3a78014a849/phone-as-keyboard-for-any-usb-host-building-a-driverless-hid-bridge-92a</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5uu45vc375wv5jfc7ihk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5uu45vc375wv5jfc7ihk.png" alt="DexoPad hero — USB-C dongle and phone controller" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem that started this
&lt;/h2&gt;

&lt;p&gt;Every developer hits this eventually: you have a computer that needs typing into, and the keyboard situation is wrong.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your laptop hard-crashed mid-task, and the only way out is a BIOS reset — but you don't have a USB keyboard within reach.&lt;/li&gt;
&lt;li&gt;You need to type a long generated command into a headless server, and the only console you have is serial.&lt;/li&gt;
&lt;li&gt;You're standing next to a kiosk machine that needs admin input, and your hands are full of phones and coffee.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you almost always have on you: a phone.&lt;/p&gt;

&lt;p&gt;So the question we kept asking was: why isn't the phone in your hand already a keyboard for everything else?&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2oe43j4nx37nwca64rfz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2oe43j4nx37nwca64rfz.jpg" alt="DexoPad in use — dongle plugged into a host machine" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We built &lt;strong&gt;DexoPad&lt;/strong&gt;, a small USB-C dongle that registers itself as a generic HID keyboard + mouse on any USB host. No driver install. No companion software on the host. It just shows up like a $10 OEM keyboard would.&lt;/p&gt;

&lt;p&gt;The control surface is your phone. The phone runs a thin app that talks to the dongle over BLE; the dongle relays the input as USB HID reports to whatever it's plugged into.&lt;/p&gt;

&lt;p&gt;The decision that made this actually work: &lt;strong&gt;all the smarts live phone-side&lt;/strong&gt;. The dongle is intentionally dumb. It speaks USB HID. It does pairing. It rebroadcasts what the phone tells it to type, click, or scroll. That's it.&lt;/p&gt;

&lt;p&gt;This is what lets it work in places where you can't install anything — BIOS, locked-down corporate machines, kiosks, Pi during initial boot.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's interesting technically
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BLE latency&lt;/strong&gt;: getting typing-feel right meant tuning the connection interval down. We landed around 7.5ms with reasonable battery on the phone side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HID report descriptors&lt;/strong&gt;: we ship a composite device (keyboard + mouse) so we don't have to ask the host to enumerate two separate USB devices. This also avoids the (Windows-specific) "new HID device detected" toast every time someone re-plugs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-OS key mapping&lt;/strong&gt;: harder than it looks. The phone runs OS-aware key translation, so AZERTY / Dvorak / Bépo on the phone keyboard maps to the host's expected scancodes correctly. The dongle just sends scancodes; the phone does layout resolution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Voice (opt-in)&lt;/strong&gt;: there's an optional voice-to-text feature that pipes phone audio through the OpenAI Whisper API. It is off by default. We're adding an explicit "completely disable" toggle in the app settings after backer feedback, because "off by default" wasn't a strong enough signal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How we actually use it
&lt;/h2&gt;

&lt;p&gt;We've been running DexoPad ourselves while developing it. The honest reason it stayed in the pile after the initial prototype:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a long-running terminal session crashes and we need to type a 200-character recovery command into a Mac that has no nearby keyboard, the dongle saves real time.&lt;/li&gt;
&lt;li&gt;Initial setup for Raspberry Pi / mini-PCs without dragging out a keyboard + mouse.&lt;/li&gt;
&lt;li&gt;BIOS settings on machines that don't expose USB keyboard over the network KVM cleanly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not glamorous. It's just one of those things that quietly stops being annoying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to follow
&lt;/h2&gt;

&lt;p&gt;We're funding the production run on Kickstarter right now. Already past base goal, working toward the Android-app stretch.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.kickstarter.com/projects/palmblock/dexopad-cross-device-keyboard-mouse-and-macros-anywhere?ref=f1kjn0" rel="noopener noreferrer"&gt;https://www.kickstarter.com/projects/palmblock/dexopad-cross-device-keyboard-mouse-and-macros-anywhere?ref=f1kjn0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comments / use cases / "wait have you tried X" — welcome here or on the campaign page. We read all of them.&lt;/p&gt;

&lt;p&gt;— MJ, PalmBlock&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>embedded</category>
      <category>usb</category>
      <category>kickstarter</category>
    </item>
  </channel>
</rss>
