Giter VIP home page Giter VIP logo

usbhost's Introduction

USBHost Library for Arduino

Check Arduino status Compile Examples status Spell Check status

The USBHost library allows an Arduino Due board to appear as a USB host, enabling it to communicate with peripherals like USB mice and keyboards.

For more information about this library please visit us at http://www.arduino.cc/en/Reference/USBHost

License

Copyright (c) 2012 Arduino LLC. All right reserved. Copyright (c) 2011 Circuits At Home, LTD. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

usbhost's People

Contributors

aentinger avatar agdl avatar cmaglie avatar dependabot[bot] avatar facchinm avatar fede85 avatar karlsoderby avatar lauszus avatar per1234 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

usbhost's Issues

Numeric keypad support ?

Is it possible to add numeric keypad support to the library?
The /*-+ all work fine, however the 0-9 do not but do produce the following response
Actual Key pressed GetOemKey response
1 = 89,
2 = 90,
3 = 91,
4 = 92,
5 = 93,
6 = 94,
7 = 95,
8 = 96,
9 = 97,
0 = 98

5 second blocking delay

usb.Task() has a 5 second blocking delay in the KeyboardController and
MouseController examples. This makes it hard to use USB host with
other devices that need regular polling. For example, if data is
streaming in to Serial1 at 115200 bits/s, the incoming data will not
be processed for up to 5 seconds.

This can be seen by adding timing output to the examples. For example,
the following prints "delta millis 5000" when there is no keyboard or
mouse input.

void loop() {
  uint32_t delta, startMillis = millis();

  // Process USB tasks
  usb.Task();

  delta = millis() - startMillis;
  if (delta > 10) {
    Serial.print("delta millis ");
    Serial.println(delta);
  }
}

The problem is the input endpoint property defaults to wait until
timeout which is 5 seconds. The proposed solution is to set the
EpInfo.bmNakPower to USB_NAK_NOWAIT. This means if a single
NAK is received, input operations return with an error instead
of waiting for 5 seconds.

With this change usb.Task() returns in <= 10 ms when there is no input
from the device.

hidboot.h
@@ -464,6 +464,7 @@ void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint32_t conf, uint32_t iface, uint3
        epInfo[index].deviceEpNum       = (pep->bEndpointAddress & 0x0F);
        epInfo[index].maxPktSize    = (uint8_t)pep->wMaxPacketSize;
        epInfo[index].epAttribs     = 0;
+       epInfo[index].bmNakPower    = USB_NAK_NOWAIT;

        TRACE_USBHOST(printf("HIDBoot::EndpointXtract : Found new endpoint\r\n");)
        TRACE_USBHOST(printf("HIDBoot::EndpointXtract : deviceEpNum: %lu\r\n", epInfo[index].deviceEpNum);)

A pull request has been submitted with this change.

Keyboard: Unable to get mod keys w/o tapping a regular key

I'm using 2 Seeed Xiao's communicating via Serial1, one of them programmed with the 'GetModifiers" example from arduino.cc, the other doing simple serial passthrough to Serial Monitor. The mod value only changes when a regular key is tapped ex. 'a'.

WIth the windows key being a mod key, it makes it impossible to tap that key to open the start menu. Also, in general, I would like to pass through modifiers as they are pressed and released, just like if the keyboard was hooked directly into a computer. Is there some method that does this already that I'm missing? Is it possible to get mod keys to fire the same as basic keys?

HID-compliant Touchscreen

I'm trying to use a touchscreen (7" by waveshare) on the Due's USB Port. But it doesn't work.
I tried a mouse, that worked. I tried the touchscreen on a pc, that worked.
On the pc the touchscreen appeared as a HID-compliant Touchscreen. Because I thought it would be recognized as a mouse.
I suspect that that's why my code doesn't respond to it.

Maybe Touchscreen Data is different and we/I need a separate TouchscreenController.h/.cpp for this?

The code is just notifying to the serial monitor:

void mouseMoved() {
Serial.println("mouseMoved");
}
void mouseDragged() {
Serial.println("mouseDragged");
}
void mousePressed() {
Serial.println("mousePressed");
}
void mouseReleased() {
Serial.println("mouseReleased");
}

Strange behaviour with Yamaha THR10 USB device connected to Arduino Due native USB host port.

Hi ,
finally i got my "Yamaha THR10" (guitar amp, that can be configured via MIDI-SysEx) working with this library (arduino-libraries/USBHost) in conjunction with the" bbx10/USBH-Midi branch Due"-library on my "Arduino Due", but there were several problems to solve before:

Concerning this library (arduino-libraries/USBHost):

USB-Enumeration works only, if Debug-outputs are enabled in USBHost.h

#define TRACE_USBHOST(x) x
//#define TRACE_USBHOST(x)
otherwise device is not detected.

Don't ask me why...
Is it perhaps a timing problem, that is solved when a "printf" delays process at the right time?
EDIT:
In fact it is a timing issue, I found out after som research. There a two places to add delays (details at th bottom of this posting).

Just for further information

Issues concerning library (bbx10/USBH-Midi branch Due):

  • Adding an "else if" in descriptor parsing
        if( buf_ptr[5] == USB_CLASS_AUDIO && buf_ptr[6] == USB_SUBCLASS_MIDISTREAMING )
	{  //p[5]; bInterfaceClass = 1(Audio), p[6]; bInterfaceSubClass = 3(MIDI Streaming)
          isMidiFound = true; //MIDI device found.
          isMidi      = true;
        }
//**Yamaha THR10**
	else if( buf_ptr[5] == USB_CLASS_VENDOR_SPECIFIC && buf_ptr[6] == USB_SUBCLASS_MIDISTREAMING ) //**Yamaha THR10**
		{  
                   //p[5]; bInterfaceClass = 255(VENDOR), p[6]; bInterfaceSubClass = 3(MIDI Streaming)
		   isMidiFound = true; //MIDI device found.
		   isMidi      = true;
		}
		else
		{
#ifdef DEBUG
          Serial.print("No MIDI Device\n");
#endif
//          buf_ptr += total_length + 1;
//          bConfNum = 0;
            isMidi = false;
        }
        break;
  • Solving buffer problems:

always use (uint16_t) cast instead of (uint8_t) cast for epInfo[index].maxPktSize
e.g.
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
quick and dirty change for buffersize, that works for THR10 (just a work around, no proper solution, i guess!!!):

if( isMidi )
{
            if ((epDesc->bEndpointAddress & 0x80) == 0x80) 
   	   {
              // Input
              index = epDataInIndex;
              epInfo[index].epAddr	= (epDesc->bEndpointAddress & 0x0F);
              //epInfo[index].maxPktSize	= (uint16_t)epDesc->wMaxPacketSize;
	      epInfo[index].maxPktSize	= (uint16_t)2048;  //necessary for YAMAHA THR10
              pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].epAddr, UOTGHS_HSTPIPCFG_PTYPE_BLK, UOTGHS_HSTPIPCFG_PTOKEN_IN, epInfo[index].maxPktSize, 0, UOTGHS_HSTPIPCFG_PBK_1_BANK);
            }
            else 
	    {
              // Output
              index = epDataOutIndex;
              epInfo[index].epAddr	= (epDesc->bEndpointAddress & 0x0F);
              //epInfo[index].maxPktSize	= (uint8_t)epDesc->wMaxPacketSize;
			  epInfo[index].maxPktSize	= (uint16_t)2048;  //necessary for YAMAHA THR10
              pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].epAddr, UOTGHS_HSTPIPCFG_PTYPE_BLK, UOTGHS_HSTPIPCFG_PTOKEN_OUT, epInfo[index].maxPktSize, 0, UOTGHS_HSTPIPCFG_PBK_1_BANK);
            }

After that modifikations, i can send System-Exlusive Messages to THR10, like

uint8_t msg1[]= {0xF0,0x43,0x7D,0x30,0x41,0x30,0x01,0x01,0xF7}; //Lamp off
uint8_t msg2[]= {0xF0,0x43,0x7D,0x30,0x41,0x30,0x01,0x00,0xF7}; //Lamp on`
that switches the light of the Guitar-Amp.

But more important, I can send sound-Patches, that are created as a file before with the THR10-Editor on PC.

This way I can build a foot-switch / pedal to change sound patches on the fly like

THR10 foot switch

But this guy did it with an ordinary Arduino Uno and the USB-Host Shield.
With the Due I can use the native USB-Host-Port, have got more memory and speed.
I want to inject Samples to the THR10 with this footswitch as well, as it can also act as IN-/OUT Audio Interface.

EDIT:

After days of research and examination i found out, which delays in "USB.cpp" are necessary (instead of the " #define TRACE_USBHOST(x) x", that solved the issue as well, but gives lots of Serial Prints and slows down everything.)
I would suggest this as a pull request, if i would understand the reason, but without that it is just a kind of work around.

1.) Add a delayMicroseconds(300ul); in function "USBHost::ctrlReq" where the following lines occure:

Code:

if (dataptr != 0)
{
 if (direction)
 {
   // IN transfer
   TRACE_USBHOST(printf("    => ctrlData IN\r\n");)

   Add here---->   delayMicroseconds(300ul);  //necessary!! 275ul does not work!!
  1. Add a delayMicroseconds(120ul); at start of function "USBHost::dispatchPkt"

Code:

uint32_t USBHost::dispatchPkt(uint32_t token, uint32_t hostPipeNum, uint32_t nak_limit)
{
   uint32_t timeout = millis() + USB_XFER_TIMEOUT;
   uint32_t nak_count = 0;
   uint32_t rcode = USB_ERROR_TRANSFER_TIMEOUT;

---> add here: delayMicroseconds(120ul);  //NECESSARY!!  (100ul does not work!)

   TRACE_USBHOST(printf("     => dispatchPkt token=%lu pipe=%lu nak_limit=%lu\r\n", token, hostPipeNum, nak_limit);) 

Don't really know w h y this have to be done. But it does nor work otherwise.
;)

Example code for handling both keyboard AND mouse ?

I tried to merge the keyboard and mouse examples into one single example that would allow me to plug-in either a keyboard OR a mouse, without having to recompile each time I want to change between mouse and keyboard.

I tried the following, without success :

// Initialize USB Controller
USBHost usb;
// Attach mouse controller to USB
MouseController mouse(usb);
// Attach keyboard controller to USB
KeyboardController keyboard(usb);

=> It seems this library doesn't support having two controllers on the same USBHost instance. Could you confirm that ?

Then I tried the following, which also didn't work :

// Initialize USB Controller
USBHost usb1;
USBHost usb2;
// Attach mouse controller to USB
MouseController mouse(usb2);
// Attach keyboard controller to USB
KeyboardController keyboard(usb1);

=> Could you tell me which one of these two approaches should be the good one ? And then I suggest to add in the source code some assertions to avoid users making forbidden things (putting two controllers on the same USBHost instance and/or creating two USBHost instances at same time, etc.)

The idea behind that request, is I want to be able to use a mouse connected to my DUE, and sometimes, but rarely, I want to be able to disconnect the mouse, put a keyboard instead, type some phrase on it, and then remove it and plug-in the mouse again.
Thanks

PS3 dualshock 3 support?

Hi,
I'm trying to port code from the PS3USB.cpp at USB_Host_Shield_2.0 library for AVR microcontrollers, but I've having many problems as its a bit far from my expertise.
Has anybody attempted to port these Joystick controllers to the due platform?
Due has the advantage of having a native USB port unlike other AVR based MCUs that require the USB host shield.

Any information would be greatly appreciated, thanks!

Arduino Due Host

I want to use the USBHost library to create a USB host in arduino due, and a usb device in arduino uno. then perform communication between them..
USB_connect.xlsx

Add ASCII control codes

KeyboardReportParser::OemToAscii does not return ASCII control codes such as CTRL-A (0x01). It also does not return ASCII codes for the following keys: TAB, ESCAPE, and DELETE. It returns the wrong code for the ENTER key.

The proposed patch to has been submitted: #4

Problems with declaring variables

Hello,

I am trying to use this library to intervace with my Logitech extreme 3D pro joystick controller so I made a few additions to the source code. I basically followed the same format that the Mouse and Keyboard use but adapted it to be used for the joystick device.

JoystickController.cpp:

#include <JoystickController.h>

extern "C" {
void __joystickControllerEmptyCallback() { }
}


void OnJoystickChanged()  __attribute__ ((weak, alias("__joystickControllerEmptyCallback")));

uint8_t JoystickController::getButtons_a()      { return buttons_a; }
uint8_t JoystickController::getButtons_b()      { return buttons_b; }
uint8_t JoystickController::getSliderValue()    { return slider; }
uint32_t JoystickController::getAxesValues()    { return axes; }
uint16_t JoystickController::getXValue()        { return x; }
uint16_t JoystickController::getYValue()        { return y; }
uint8_t JoystickController::getHatValue()       { return hat; }
uint8_t JoystickController::getTwistValue()     { return twist; }

JoystickController.h:

#ifndef JOYSTICK_CONTROLLER_H
#define JOYSTICK_CONTROLLER_H

#include <hidboot.h>



class JoystickController : public JoystickReportParser
{
public:
    JoystickController(USBHost &usb) : hostJoystick(&usb), axes(0) , buttons_a(0), buttons_b(0) , slider(0) {
        hostJoystick.SetReportParser(0, this);
    };

    uint8_t getButtons_a();
    uint8_t getButtons_b();
    uint8_t getSliderValue();
    uint32_t getAxesValues();
    uint16_t getXValue();
    uint16_t getYValue();
    uint8_t getHatValue();
    uint8_t getTwistValue();

protected:
    virtual void OnJoystickChanged(JOYSTICKINFO *js);


private:
  HIDBoot<HID_PROTOCOL_JOYSTICK> hostJoystick;
    union { //axes and hat switch
        uint32_t axes;
        struct {
          uint32_t x : 10;
          uint32_t y : 10;
          uint32_t hat : 4;
          uint32_t twist : 8;      
        };
    };
    uint8_t buttons_a;
    uint8_t buttons_b;  
    uint8_t slider;

};

#endif

I added this to hidboot.cpp:

void JoystickReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
    bool match = true;
    JOYSTICKINFO *pjs = (JOYSTICKINFO*)buf;

    // Checking if there are changes in report since the method was last called
    for (uint8_t i=0; i<7; i++) {
        if( buf[i] != prevState.oldPad[i] ) {
            match = false;
            break;
        }
  }
    // Calling Game Pad event handler
    if (!match && pjs) {
        OnJoystickChanged((JOYSTICKINFO*)buf);
        //OnJoystickChanged(buf);

        for (uint8_t i=0; i<7; i++) 
            prevState.oldPad[i] = buf[i];
    }
}

and i added this to hdiboot.h:

/**
 * \brief JOYINFO definition.
 */

 struct JOYSTICKINFO
{
    union { //axes and hat switch
        uint32_t axes;
        struct {
          uint32_t x : 10;
          uint32_t y : 10;
          uint32_t hat : 4;
          uint32_t twist : 8;      
        };
    };
    uint8_t buttons_a;
    uint8_t buttons_b;  
    uint8_t slider;


};



/**
 * \class JoystickReportParser definition.
 */
class JoystickReportParser : public HIDReportParser
{
    union
    {
//      JoystickEvents      *joystickEvents;
        JOYSTICKINFO        joystickInfo;
        uint8_t             oldPad[7];
        uint8_t             oldHat;
        uint16_t            oldButtons;
    }   prevState;


public:
    //JoystickReportParser(JoystickEvents *evt);
    virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);

protected:
    virtual void OnJoystickChanged(JOYSTICKINFO *js) {};

};

in hid.h, added:
#define HID_PROTOCOL_JOYSTICK 0x03

And when I tried to implement this in an Arduino sketch, I got the following errors:

JoystickController:9: error: cannot declare variable 'joy' to be of abstract type 'JoystickController'

 JoystickController joy(usb);

                    ^

In file included from C:\Users\Aaron\Documents\Arduino\JoystickController\JoystickController.ino:3:0:

C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/JoystickController.h:11:7: note:   because the following virtual functions are pure within 'JoystickController':

 class JoystickController : public JoystickReportParser

       ^

In file included from C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/hidboot.h:24:0,

                 from C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/JoystickController.h:7,

                 from C:\Users\Aaron\Documents\Arduino\JoystickController\JoystickController.ino:3:

C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/hid.h:157:15: note:  virtual void HIDReportParser::Parse(HID*, bool, uint32_t, uint8_t*)

  virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf) = 0;

               ^

Using library USBHost at version 1.0.4 in folder: C:\Users\Aaron\Documents\Arduino\libraries\USBHost 
exit status 1
cannot declare variable 'joy' to be of abstract type 'JoystickController'

I searched for any differences in how the mouse and keyboard controllers were initialized and I couldn't find anything. I'm not very experienced in C++ so i need some help.

Thanks in advance,

Aaron

No USB Host examples that read/write to USB Mass Storage device

The Arduino Zero has USB Host capabilities.
(I don't mean having an Arduino Zero act like a USB mass storage device.)

There is currently no example that shows users how to read/write a USB Mass storage device that is connected to the Native USB port of, say, an Arduino Zero.

slow polling rate coming from arduino due native usb port

I have a mouse plugged into the native usb of a arduino due, then sending the inputs to a teensy. my issue is that i only get 100 polling rate from this.

i know the teensy is not a problem (i made a small script that made it move in a circle and tested, it got 500 polling rate with the INTERVAL in teensy header set to 2)

i should be sending information fast enough since im converting everything into bytes (i.e mouse position, buttons, etc)

using rx and tx pins to communicate between each other.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.