Under $40 keyboard USB splitter

Wait, I am not referencing a KVM that permits using one keyboard on either computer by hitting a button and switching between the two. What I am talking about is one USB keyboard to send keyboard/barcode scanner information to two computers at the same time.

That’s right! 1 USB Keyboard sending data to 2 computers at the same time. Not a PS/2, but a USB keyboard. I spent a butt load of time trying to find a device that will do this, but I couldn’t, so I built one.

In order to get this working, Arduino Due $20 (on amazon), 2x Arduino Mico Pro (3x $16 on Amazon). The rest is soldering connections, making a plastic box and cutting some holes.

Co-Worker build this better case.

Connections all in place and checked with the meter.

My first ghetto case. I wasn’t really good in shop class.

The Arduino Due has the ability to read keyboard input with the correct library. The Arduino Micro Pro has the ability to emulate a keyboard. Combined using the IC2 bus communications, the Due can read keyboard input, forward it over the IC2 bus to 2 or more Mico Pros at the same time. Then have the Micro Pros read the IC2 bus as characters and send the output to the USB interface. Some tweaks were needed in the code since some keyboard keys aren’t characters. For example, TAB, ENTER, CTRL. These had to be send as the integer ascii representation to the Pro Micro.
Aside from that, it seems to work very well and has reduced out time per piece in production, human error and saved us from an over priced software interface.

Best and have fun.

This entry was posted in Obsess and tagged , , , , . Bookmark the permalink.

9 Responses to Under $40 keyboard USB splitter

  1. Borislav Arnaoudov says:

    Do you have some instructions on the soldering and necessary code? Parts are easy to get but I cannot figure out the connections from the pictures. There is a similar Korean solution, but why spend 150$ when I can do it for 50$.
    youtube.com/watch?v=efs6DaTFLto

  2. Yes. I saw that and checked into it. The one in their video only does serial scanners to USB.

    I will send you my code for all the boards and write some details on the connections. The connections between the boards are just between the ground, SLC and SDA pins on the Arduino. This creates the bus between the boards. I have your email and will send you what I have tomorrow. Happy to help you out.

  3. As promised.

    Here is the hook-up pin-out for the micro pro.
    https://learn.sparkfun.com/tutorials/pro-micro–fio-v3-hookup-guide/hardware-overview-pro-micro

    If you look, pins 2 and 3 are labeled SDA and SCL. These are the pins used for the IC2 bus communications between the boards.

    Soldier all the SDA to pins connecting the SDA, all SCL to all the SCL and a common ground is shared is connected as well.

    Arduino Due has the SDA and SCL on pins 20 and 21 typically. Not sure if that is the same for all the clone board versions.

    Once all Micro Pro and Due have SCL, SDA and GND connected to each other, you only need the MASTER and SLAVE code.

    HERE IS THE MASTER CODE FOR DUE:

    #include Wire.h
    #include KeyboardController.h ## put Greater than and less than around these. WP keeps nulling it out.
    // #include
    USBHost usb;
    KeyboardController keyboard(usb);

    int inboundsource = 0;
    int subinboundsource =0;
    int hypheninboundsource =0;

    void setup() {
    Wire.begin(); // join i2c bus as MASTER
    Serial.begin(115200); //Uncomment to Debug keyboard input to serial monitor.
    }

    void loop() {

    usb.Task();
    }
    void keyPressed() {

    inboundsource = keyboard.getKey();
    if (inboundsource == 19){ //If the integer is 19 then make the sub use the DEC output for ENTER.
    //Serial.print(176); // Uncomment to debug serial console
    subinboundsource = 176;
    Wire.beginTransmission(8); //send to device #8
    Wire.write(subinboundsource);
    Wire.endTransmission(8);
    Wire.beginTransmission(7); //send to device #7
    Wire.write(subinboundsource);
    Wire.endTransmission(7);
    delay(10);
    }
    if (inboundsource == 0){
    subinboundsource = 179; // If the integer is 0 (for TAB) then use DEC 179 for TAB.
    hypheninboundsource = ‘-‘;
    Wire.beginTransmission(8); //send to device #8
    Wire.write(subinboundsource);
    Wire.endTransmission(8);
    Wire.beginTransmission(7); //send to device #7
    Wire.write(hypheninboundsource); // Use inboundsource as digital shipper needs the hyphen.
    Wire.endTransmission(7);
    delay(10);
    }

    else {
    // Serial.print(inboundsource); // uncomment to debug serial
    Wire.beginTransmission(8); // send to device #8
    Wire.write(inboundsource);
    Wire.endTransmission(8); // stop
    Wire.beginTransmission(7); // send to device #7
    Wire.write(inboundsource);
    Wire.endTransmission(7); // stop
    delay(10);
    }
    }

    ############ EACH SLAVE (Micro Pro) needs to have an assigned address. In the example above, I made one #7 and the other #8. I also created two separate IF statements as I want the hyphen to output as a TAB to one slave computer and output as a hyphen to the other. This is because we have two different softwares 1. Shipping and one Ordertracking. So a TAB is needed to separate the file output. You can customize and play with on your own. All CHARACTERS will send through the bus, but NON CHARACTERS need a TRANSLATION MAP creates in IF statements. I.E. If you want to sent ENTER you have to read the Integer for ENTER, then translate it to the ASCII code to send to the boards otherwise the slaves don’t get the correct code for ENTER.

    See “if (inboundsource == 19){ //If the integer is 19 then make the sub use the DEC output for ENTER.
    //Serial.print(176); // Uncomment to debug serial console
    subinboundsource = 176; ”

    If you enable the serial console you can see on the screen that when you hit enter 19 is displayed. The IF statement identifies the 19 and then I substitute the 19 for DEC code of 176 which is ENTER. That way it sends the correct DEC through the bus to the slaves.

    HERE IS THE SLAVE CODE FOR THE Micro PRO boards.
    #include # Wire.h
    #include # Keyboard.h

    void setup() {
    Wire.begin(8);
    Wire.onReceive(receiveEvent);
    Keyboard.begin();
    Serial.begin(115200); // start serial for output
    }

    boolean flagRx = false;
    char buf[40];
    void loop() {
    delay(10);
    if (flagRx)

    {
    if (buf == 176) { ##### not really needed as I changed it on the source, won’t hurt to leave it in.
    Keyboard.print(KEY_RETURN);
    }
    else
    {
    Keyboard.print(buf);
    }
    // Serial.print(buf); //uncomment for debug

    flagRx = false;
    }
    }

    void receiveEvent(int howMany) {
    int i;
    for (i=0; i

  4. nitin gupta says:

    Hi,

    I am looking at emulating whatever i type on one keyboard on multiple computers. How much would it cost if you decide to build it and ship it to india.

  5. Akebono says:

    Really cool. What did you use to separate the Due from the Micro Pros?

  6. I’m not in the business of building arduino keyboard splitters. You can order the parts and I will answer your questions if you get stuck. If I were in the business, there are too many logistical issues with building and shipping International let alone the amount of fraud issues that can be involved. If you have questions ask, and I will help.

  7. That white separation is just a piece for vinyl plastic, dilled some small hole in, and put the header pins on to make a shield for the arduino Due.

  8. Kahei Chin says:

    Thank you ,Andy!very helpful information ,it is exactly what I am looking for。
    Regards of the master and slave code ,could you please also send to my email?I can see part of the code,but it seems not the complete version。
    Thank you in advance!

  9. Done. You should have the files. If you’re trying to get it to run, but haven’t installed the wire library into your arduino IDE, that could be what you’re missing.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.