0

I am currently doing research for a project of mine. My goal is simple: I want to pass input from a physical mouse, to a microcomputer to process the input and modify, and send the input in the form of USB HID to a PC.

Mouse ---> Microcomputer (input modified) ---> PC

The Microcomputer preferably should be able to both send data to the PC (in the form of USB HID inputs as a mouse) and receive data from the PC.

I found the arduino Leonardo can act as a USB slave and emulate mouse movement, half of what I want. I need some microcomputer with capabilities to act both as a USB host and as a USB slave. I don't have experience with microcomputers, and I don't know how to find something with this feature.

  • Do you want to be able to change settings in the mouse from the computer? Can you explain what you want to modify? The mouse speed? Could it be possible to do this on the computer with a special driver? Which operating system? – Jot Jun 15 '18 at 6:09
  • I want the middleman computer to be able to modify the input to the main PC based on data from the main PC. A simple file pipe or something like that is enough for what I need. I assume it's possible with a USB controller in slave mode, because I've seen software based RGB keyboard controls, etc. However, in this case I don't need to access the mouse. – James Meas Jun 15 '18 at 6:25
  • What do you want to modify? The mouse speed? Buttons? Auto-repeat? – Jot Jun 15 '18 at 7:01
  • I want to move a physical mouse, modify the movement in my microcomputer (e.g. multiply coordinates by two), then send it to the PC (the microcomputer will act as a virtual HID). – James Meas Jun 15 '18 at 7:04
  • I'm not sure if that will work. A mouse does not know coordinates. If it is possible then it can be done on a linux computer as well without Arduino. I agree with the answer by @gdsports , attach a usb host shield. – Jot Jun 15 '18 at 9:55
-1

The cleanest solution to this problem would be to use an MCU with dual USB interfaces, one capable of being a USB host. There are a few such parts in the STM32F4 lineup, and likely other brands as well, but not immediately clear if there are any with existing Arduino support. Hardware wise, I believe you can do it with an inexpensive STM32F446 "Nucleo" board, though the pins of the USB interface are only available on headers, which you would need to wire to USB connectors.

A USB host shield is a possibility, but it's a bit "tacky" as a solution since it involves hanging a fairly sophisticated controller off a more primitive MCU, making an "upside down" architecture, and more expensive than an all-in-one solution, but it could be where you'll find the most existing code to support your effort.

One of the simplest things you could actually do would be to use a ps/2 mouse instead of a USB one, and interface that by bit-banging its simple serial interface. Then you could use a board like a Leonardo or one of the Teensy series which has a customizable USB device interface, to present to the host computer as a USB mouse.

  • I was thinking about using a pi as USB host, then passing coordinates over GPIO to an arduino slave. But I feel like there will be input delay. – James Meas Jun 15 '18 at 21:42
  • I like the nucleo as an option, I'm just worried that it may be too complex for me to understand, and I don't think I have the proper tools to solder on a header for usb (I have never purchased a small computer like this before). – James Meas Jun 15 '18 at 21:47
  • It will indeed be challenging integrating the firmware - while a lot more capable, the examples also are far less turn-key than Arduino code. In terms of attaching a USB port, what I did was to get a cheap USB extension cable, cut it in half, and crimp female header pins to it to plug into the board expansion headers (though watch out, the color code in cheap USB cables is usually completely wrong!). These are all skills worth learning, but each takes time. If this is the first time, you probably want to go with the host shield or the ps/2 mouse where you can stay purely Arduino. – Chris Stratton Jun 16 '18 at 1:27
  • thanks for the heads up. I found a nice little board while browsing adafruit, the Trinket M0 that i fcan couple with a USB host controller. github.com/gdsports/usb-metamorph/blob/master/README.md I found this github repo that has a lot of info about USB and stuff. I'm not even sure what the repo is about, I just skimmed over it, but the trinket m0 with USB host shield looks promising. – James Meas Jun 16 '18 at 4:43
  • Hmm, while that combination might work, I worry that could bring the risk of the worst of both worlds; the atypical,only quasi-Arduino M0 platform, and the indirectness of the host shield. – Chris Stratton Jun 16 '18 at 4:52
2

Plug a USB Host Shield into the Leonardo.

USB mouse --- USB Host Shield --- Leonardo --- PC

USB Host Shield Library

Circuits@Home Project

/*
 * USB Mouse pass through. Works at HID report level. HID report is not decoded.
 * Tested on Leonardo with Arduino USB host shield, IDE 1.8.5, and Logitech Marble
 * trackball/mouse. This is a proof of concept so is not guaranteed to work with 
 * all USB mice/trackballs.
 */
// USB host mouse from USB Host Shield Library. Install using Library Manager
#include <hidboot.h>

// USB device mouse library included with Arduino IDE 1.8.5
#include <Mouse.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class MouseRptParser : public MouseReportParser
{
protected:
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

void MouseRptParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
  Serial.print("MouseRptParser::Parse");
  // Show USB HID mouse report
  for (uint8_t i = 0; i < len ; i++) {
    Serial.print(' '); Serial.print(buf[i], HEX);
  }
  Serial.println();

  // On error - return
  if (buf[2] == 1)
    return;

  if (len > 2) {
    uint8_t mouseRpt[4];
    mouseRpt[0] = buf[0];
    mouseRpt[1] = buf[1];
    mouseRpt[2] = buf[2];
    mouseRpt[3] = 0;
    HID().SendReport(1,mouseRpt,sizeof(mouseRpt));
  }
}

USB     Usb;
HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);

MouseRptParser Prs;

void setup()
{
  Serial.begin( 115200 );
#if !defined(__MIPSEL__)
  while (!Serial) delay(1); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  Serial.println("Start");

  if (Usb.Init() == -1) {
    Serial.println("USB host shield did not start.");
  }
  delay( 200 );

  HidMouse.SetReportParser(0, &Prs);

  Mouse.begin();
}

void loop()
{
  Usb.Task();
}

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.