Homemade USB ,HID compatible, input device

My first homemade USB device, for use in my car. 


-I needed an input device that could provide some additional buttons for my Carputer.
-I needed an volume & menu control knob, using common keys did not give me the linear, fast control I needed.
-(on-screen volume slider on touch sensitive display was not good enough, because it consumed display space.)
-I wanted a circuit that could notify my computer about low battery voltage, and hibernate it in time.
-I wanted a circuit that could detect when  stopped the engine, so the computer could offer to hibernate automaticly.
-I hoped to avoid the need of own USB driver, so it had to be HID compliant device.

The result:

The following information, PCB , component list, schematics, is free for personal use.
This page contains all information you need to build this device.

The PIC16c745 is an OTP (one time programmable) device. You can program one yourself, but you need an programmer that can do it, and do it right on first try.
This is why I offer to sell preprogrammed 16c745 and the SMD resonator - because these are the parts people may have trouble finding.


The "optional" circuit is used to detect low battery voltage -  this triggers a software warning, and then hibernates the carputer.
The battery sensing circuit - takes only 2.5mA with a 5K resistor , (I recommend 15K - but I did not had it @home when I built this device)
2.5mA is so little, that even that won't depleat your battery for weeks. (if always connected directly to car's battery).

Component list:

Part       Value    
C1                10n     
C2+C3          10u 
C4             200n     
D1         1N4004   
R1             1k5      
R2...R9    10k      
R10            47k      
R11+R12    10k      
R22            15k       trimpot SP19L  
U$1            16C745    DIL28     
U$2            6Mhz      Resonator (SMD)
VolKnob  =binary counting rotating, stepping knob (optional)

PCB Layout (manual design)


PCB file :

Home made PCB

Assembled and working :

Pinput (on the picture above)
DIAG - (RA5)   When this jumper is removed, the device enter diagnostic mode.
JP1 - 1 -   GND
JP1 - 2 -    RC6
JP1 - 3 -    RC7
JP1 - 4 -    RB0
JP1 - 5 -    RB1
JP1 - 6 -    RB2
JP1 - 7 -    RB3
JP1 - 8 -    RB4
JP1 - 9 -    RB5
JP1 - 10 -    RB6
JP1 - 11 -    RB7

JP3 -1 -   GND
JP3 -2 -   RC2
JP3 -3 -   RC1
JP3 -4 -   RC0

Volknob -1 - +5Volt
Volknob -1 - Button (RA4)
Volknob -1 -  Vol0  (RA3)
Volknob -1 -  Vol1 (RA2)

The IC in the pictures is an windowed edition.
It is
used it for development, windowed edition (JW) is ceramic & gold plated, and is UV erasable, and way more expensive.


PCB Layout
PCB Print File (PCL ->  just dump it to any PCL compatible printer)
(burn on  a PIC16C745)

Inputs & what code(keypress) they send.:

Inputs RA0 and RA1  - checked each 5 seconds

This input pins are used for reporting low car battery voltage , ignition, or other signals
when active, they will ONLY send the key once each ~5'th second -  in order to avoid "spamming" the system with key presses that signal a state that might be permanent

RA0   - Active low  , Sends ALTGR-F8             - Active when battery voltage drops to 10volts. (or any preset voltage)
RA1   - Active low  , Sends ALTGR-F7             -

Input RA5 - Diagnostic mode

When this pin is NOT connected to GND (or jumper "Diag" is removed)  all keys sent to computer are sent as normal keys, as if ALTGR was released.
This allows simple testing - just pop up notepad and you can see all incoming keys in plain text.

Inputs RA2...RA4   . Volume & menu knob inputs

RA2   - Active high  , Sends ALTGR-A             -Volume wheel- signal 1
RA3   - Active high  , Sends ALTGR-B             -Volume wheel- signal 2
RA4   - Active high  , Sends ALTGR-C             -Volume wheel- button

The RA2 and RA3 reacts to change, when the bit-pattern is changing, one character is sent for each direction.

These inputs are used with a digital volume knob, the knob is a binary 2 bit counter , it count up when turned one way, and down when turned the other way, It can also be pushed, (as a button).

The volume knob acts like this , each step means one rotation to right.:

        Vol0       Vol1
        NC          NC
        NC         GND         
       GND       GND
       GND        NC

This way, the 2 bit shifting mechanism provides  reliable speed & direction detection.

Inputs RB0 ... RB4  can receive any bit combination, and send unique code for each combination

ALL RBx ports have internal pull ups, this means they are active when connected to GND

RB0  (Bit mapped input bit 0)   - these five bits can take up to 31 buttons
RB1  (Bit mapped input bit 1)
RB2  (Bit mapped input bit 2)
RB3  (Bit mapped input bit 3)
RB4  (Bit mapped input bit 4)

Here is the map:  

RB bit#                                        RB bit#      
43210   Sends                                   43210   Sends 
11111      N/A                                    01111   ALTGR-T
11110   ALTGR-9                               01110   ALTGR-S
11101   ALTGR-8                               01101   ALTGR-R
11100   ALTGR-7                               01100   ALTGR-Q
11011   ALTGR-6                               01011   ALTGR-P
11010   ALTGR-5                               01010   ALTGR-O
11001   ALTGR-4                               01001   ALTGR-N
11000   ALTGR-3                               01000   ALTGR-M
10111   ALTGR-2                               00111   ALTGR-L
10110   ALTGR-1                               00110   ALTGR-K
10101   ALTGR-Z                               00101   ALTGR-J
10100   ALTGR-Y                               00100   ALTGR-I
10011   ALTGR-X                               00011   ALTGR-H
10010   ALTGR-W                              00010   ALTGR-G
10001   ALTGR-V                               00001   ALTGR-F
10000   ALTGR-U                               00000   ALTGR-E

Example :  If RB bit 0 and RB bit#1 is pulled to GND,  then USB gets ALTGR-7

Inputs RB5...RB7

RB5  , when pulled to GND  - Sends "ALTGR-F9"
RB6  , when pulled to GND  - Sends "ALTGR-F10"
RB7  , when pulled to GND  - Sends "ALTGR-F11"

Inputs RC0...RC2

RC0  - Active Low, sends ALTGR-,
RC1  - Active Low, sends ALTGR-.
RC2  - Active Low, sends ALTGR-/
RC6  - Active Low, sends ALTGR-F7
RC7  - Active Low, sends ALTGR-F8