I am trying to create a HID that controls the up and down arrow keys with the raspberry pi. I don't know the simplest/best way to connect the pi to pc for live data exchange.

My idea is that the pi has an ultrasonic sensor that is set up vertically, that reads the distance. My hand would reflect its waves and when I was approaching the sensor it would push a key in one direction, and when I was getting further away from it, it would push the other key.

I have the ultrasonic sensor, and know how to use it and create the code that would see if I was approaching or departing. I also have a code on my pc that can make keystrokes. (ctypes library)

My issue is how do I link the 2. How do I send live data from my pi to my pc?

All code is in python


Okay. First of all let me explain what I am trying to do. My goal is to make a HID that is an ultrasonic sensor that reads how far my hand is from it. It will be placed on my desk pointing upward. When my hand approaches it, it should trigger the down arrow key. When my hand is growing further away, it should trigger the up arrow key. No hand (5 ft distance) would indicate for no movement.

Second, let me tell you what I have so far. I created the circuitry , and made a script to test distance from the sensor. It works great. I also made a script on my PC that can make keystrokes and control my PC. Afterwards I linked my Raspberry Pi and PC via SSH. With SSH I can control my Pi from my PC through the pi's terminal.

Third, the product and the problem. I can run the sensor file on my PC through the ssh and get readings in the terminal. I tried to do the same with my keystroke program to see if I could combine the 2 for a finished product, but I soon found out that I was unable to run it due to the keystroke program being made for Windows and not Raspbian. I am stuck and have no clue what to do. I was wondering if any of you wonderful people in the community could help.


Here is the keystroke code.

import ctypes
from ctypes import wintypes
import time

user32 = ctypes.WinDLL('user32', use_last_error=True)


KEYEVENTF_KEYUP       = 0x0002


# msdn.microsoft.com/en-us/library/dd375731
VK_TAB  = 0x09
VK_MENU = 0x12

# C struct definitions

wintypes.ULONG_PTR = wintypes.WPARAM

class MOUSEINPUT(ctypes.Structure):
    _fields_ = (("dx",          wintypes.LONG),
                ("dy",          wintypes.LONG),
                ("mouseData",   wintypes.DWORD),
                ("dwFlags",     wintypes.DWORD),
                ("time",        wintypes.DWORD),
                ("dwExtraInfo", wintypes.ULONG_PTR))

class KEYBDINPUT(ctypes.Structure):
    _fields_ = (("wVk",         wintypes.WORD),
                ("wScan",       wintypes.WORD),
                ("dwFlags",     wintypes.DWORD),
                ("time",        wintypes.DWORD),
                ("dwExtraInfo", wintypes.ULONG_PTR))

    def __init__(self, *args, **kwds):
        super(KEYBDINPUT, self).__init__(*args, **kwds)
        # some programs use the scan code even if KEYEVENTF_SCANCODE
        # isn't set in dwFflags, so attempt to map the correct code.
        if not self.dwFlags & KEYEVENTF_UNICODE:
            self.wScan = user32.MapVirtualKeyExW(self.wVk,
                                                 MAPVK_VK_TO_VSC, 0)

class HARDWAREINPUT(ctypes.Structure):
    _fields_ = (("uMsg",    wintypes.DWORD),
                ("wParamL", wintypes.WORD),
                ("wParamH", wintypes.WORD))

class INPUT(ctypes.Structure):
    class _INPUT(ctypes.Union):
        _fields_ = (("ki", KEYBDINPUT),
                    ("mi", MOUSEINPUT),
                    ("hi", HARDWAREINPUT))
    _anonymous_ = ("_input",)
    _fields_ = (("type",   wintypes.DWORD),
                ("_input", _INPUT))


def _check_count(result, func, args):
    if result == 0:
        raise ctypes.WinError(ctypes.get_last_error())
    return args

user32.SendInput.errcheck = _check_count
user32.SendInput.argtypes = (wintypes.UINT, # nInputs
                             LPINPUT,       # pInputs
                             ctypes.c_int)  # cbSize

# Functions

def PressKey(hexKeyCode):
    user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):
    user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))

def AltTab():

    PressKey(0x43 )
    PressKey(0x4C )
    PressKey(0x49 )
    PressKey(0x4E )
    PressKey(0x54 )

if __name__ == "__main__":

And here is the code I am using for the ultrasonic sensor.


import RPi.GPIO as GPIO
import time

def checkdist():
    GPIO.output(16, GPIO.HIGH)
    GPIO.output(16, GPIO.LOW)
    while not GPIO.input(18):
    t1 = time.time()
    while GPIO.input(18):
    t2 = time.time()
    return (t2 - t1) * 340 / 2 * 3.28084

GPIO.setup(16, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(18, GPIO.IN)
    while True:
        dist = checkdist()
        if dist < 30:
            print ('Distance: %0.2f ft' % dist)
except KeyboardInterrupt:

For those who are calling it a duplicate- A its not a motion sensor, that is infrared. This is a distance sensor, that is ultrasonic. B they were staying on the pi. My goal is to use it on windows through the pi. If I was wanting it just on py I could have had it done and wouldn't be here.

  • You should clarify the physical relationship -- this sounds like attaching it as a USB HID device would be appropriate, unless you don't want it physically attached. In which case things like bluetooth or plain 'ol TCP/IP spring to mind.
    – goldilocks
    Jul 6 '18 at 21:30
  • @goldilocks yeah, USB was my original intent. I am not afraid of wires, nut at the same time if wireless would work, that would be great. Also, the pc doesn't have Bluetooth.
    – Clint
    Jul 6 '18 at 21:34
  • Edit the details into the question. The more specific you are, the more other people will be inclined to spend their time providing information, etc., because the less specific you are, the more likely they are to end up wasting their time ("Oh that's no good to me because [some detail I didn't mention earlier]").
    – goldilocks
    Jul 7 '18 at 1:59
  • @goldilocks Okay, thanks. How is it now?
    – Clint
    Jul 7 '18 at 2:04
  • it would be easier to use an Arduino Leonardo or one of its clones .... the HID keyboard sketch is already in the example sketches
    – jsotola
    Jul 7 '18 at 3:01

If you can't use bluetooth, your only real option is a networked client/server architecture on top of TCP/IP. It does require a network, but sans one, it is not that hard to configure one or another device as an access point (with no uplink). It can also be done via direct ethernet cable without modifying your application.

If you haven't done any network programming before, this is going to be a bit of a learning experience, but realistically it is something you have to do sooner or later if you do not want to paint yourself into a corner.

  • Okay, thanks a lot! It is a Raspberry Pi 3 B VL.2, will that work with USB? And you have a good point about network programming, where online do you think the best place for me to get started with that is?
    – Clint
    Jul 7 '18 at 15:34
  • Whoops, I dunno where I got the impression it was a Zero -- I must have just assumed it because of the emulate HID thing. So you are now down to one option ;)
    – goldilocks
    Jul 7 '18 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.