The time has come to start using the code to communicate to peripheral devices. There are many devices which work well with microcontrollers. HID devices, such as keyboards, joysticks, and Radio Controller look-a-likes are useful and not too difficult to implement. Another good application of embedded USB host is digital camera control. Communication using Bluetooth and WiFi peripherals are also a possibility.
Today I’m going to show how to communicate with USB keyboard. Standard USB keyboard belongs to a class of devices, called HID (Human Interface Device). The format of data generated by HID device is quite flexible and each device stores it’s data definitions in structures called Report descriptor and Physical descriptor. Generally, to work with the device, report descriptor has to be retrieved and parsed. Because of HID flexibility, a universal HID driver will take many many lines of code. Luckily for us, if all we need is to talk to the keyboard, there is an easier way.
The so-called Boot protocol was designed to provide basic keyboard and mouse data exchange for cases when operating system resources are not available, i.e., during PC boot. Keyboard, configured for boot protocol, generates 8-byte packets in pre-determined format; the system does not need to parse report descriptors to understand the packet.
Boot protocol is described in USB HID class definition. It can be downloaded from usb.org. While you are there, grab a copy of HID usage tables also – it contains key codes for the keyboard (you won’t believe it but it’s not ASCII).
Take a look at the listing below. This is configuration descriptor of USB keyboard, obtained using “Get configuration” sketch from the previous article. This particular keyboard has extra buttons to operate web browser and media player applications. You can see two interfaces – the first interface is keyboard itself, the second interface is serving extra buttons. Let’s take a look at the first interface, starting at line 9. Class field is 03, which means HID. Subclass is 01, which means keyboard. Protocol field is set to 01, which means that boot protocol is supported.
The “unknown” descriptor in the listing is HID descriptor. We don’t need it for boot protocol. The endpoint which follows (line 23), is an interrupt endpoint that we will be polling to get keyboard state. The polling interval is set to 10ms, if polled more frequently, the endpoint returns NAK. This is the way I do it – poll at will and check for NAK.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | Configuration descriptor: Total length: 003B Num.intf: 02 Conf.value: 01 Conf.string: 03 Attr.: A0 Max.pwr: 32 Interface descriptor: Intf.number: 00 Alt.: 00 Endpoints: 01 Class: 03 Subclass: 01 Protocol: 01 Intf.string: 00 Unknown descriptor: Length: 09 Type: 21 Contents: 10010001223E000705 Endpoint descriptor: Endpoint address: 81 Attr.: 03 Max.pkt size: 0008 Polling interval: 0A Interface descriptor: Intf.number: 01 Alt.: 00 Endpoints: 01 Class: 03 Subclass: 00 Protocol: 00 Intf.string: 00 Unknown descriptor: Length: 09 Type: 21 Contents: 1001000122AB000705 Endpoint descriptor: Endpoint address: 82 Attr.: 03 Max.pkt size: 0008 Polling interval: 0A |
The format of the packet, returned by the endpoint, is as follows: first byte is a bit mask representing state of modifier key (Ctrl, Alt, Shift, Win), one bit per key, different bits for left and right keys. Second byte is so-called “OEM byte”, the value of which is constant. I have never seen it to be equal by anything but zero. Last six bytes of a packet is a buffer of sorts. It holds keys pressed since last poll. However, if the key was not released, it will stay in the buffer, therefore, the buffer restricts number of simultaneously pressed keys to 6 not counting modifier keys.
Not that we know how the protocol is working, let’s talk about programming sequence. During enumeration, our device receives an address of 1 and is ready to be put in configured mode. To switch to this mode, device needs to be told what configuration to use. This is done by sending “Set Configuration” request with appropriate value. Our device has only one possible configuration so we will be using value given in line 4 of the listing above. Next request will be HID class-specific request Set protocol with value of 0. This request tells the keyboard to switch to boot protocol. After this is done, we need to generate bulk IN request to endpoint 1 periodically to get information about key presses. Take a look at the following sketch:
/* MAX3421E USB Host controller keyboard communication */ #include <spi.h> #include <max3421e.h> #include <usb.h> /* keyboard data taken from configuration descriptor */ #define KBD_ADDR 1 #define KBD_EP 1 #define EP_MAXPKTSIZE 8 #define EP_POLL 0x0a /**/ EP_RECORD ep_record[ 2 ]; //endpoint record structure for the keyboard void setup(); void loop(); MAX3421E Max; USB Usb; void setup() { Serial.begin( 9600 ); Serial.println("Start"); Max.powerOn(); delay( 200 ); } void loop() { Max.Task(); Usb.Task(); if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) { //wait for addressing state kbd_init(); Usb.setUsbTaskState( USB_STATE_RUNNING ); } if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) { //poll the keyboard kbd_poll(); } } /* Initialize keyboard */ void kbd_init( void ) { byte rcode = 0; //return code /**/ /* Initialize data structures */ ep_record[ 0 ] = *( Usb.getDevTableEntry( 0,0 )); //copy endpoint 0 parameters ep_record[ 1 ].MaxPktSize = EP_MAXPKTSIZE; ep_record[ 1 ].Interval = EP_POLL; ep_record[ 1 ].sndToggle = bmSNDTOG0; ep_record[ 1 ].rcvToggle = bmRCVTOG0; Usb.setDevTableEntry( 1, ep_record ); //plug kbd.endpoint parameters to devtable /* Configure device */ rcode = Usb.setConf( KBD_ADDR, 0, 1 ); if( rcode ) { Serial.print("Error attempting to configure keyboard. Return code :"); Serial.println( rcode, HEX ); while(1); //stop } /* Set boot protocol */ rcode = Usb.setProto( KBD_ADDR, 0, 0, 0 ); if( rcode ) { Serial.print("Error attempting to configure boot protocol. Return code :"); Serial.println( rcode, HEX ); while( 1 ); //stop } } /* Poll keyboard and print result */ void kbd_poll( void ) { char i, j; char buf[ 8 ] = { 0 }; //keyboard buffer static char old_buf[ 8 ] = { 0 }; //last poll byte rcode = 0; //return code /* poll keyboard */ rcode = Usb.inTransfer( KBD_ADDR, KBD_EP, 8, buf ); if( rcode != 0 ) { return; }//if ( rcode.. for( i = 0; i < 8; i++ ) { if( buf[ i ] != old_buf[ i ] ) { for( j = 0; j < 8; j++ ) { Serial.print( buf[ j ], HEX ); Serial.print(" "); old_buf[ j ] = buf[ j ]; }//for( j = ... Serial.println(""); }//if( buf... }// for( i = 0... } |
Hi there
Your website is really exciting and informative.I am new to usb communication….I wanted to connect a bluetooth dongle to MAX3421E and use it for bluetooth communication.Since its possible connect any usb device to the MAX3421E…i belive it will work….But the problem is the software driver for it dongle.how exactly should i write my program to make it work……could u please advise me on this topic….thanks a lot!!! 🙂
The practicality of this depends on what you want to do with the bluetooth. Is it for serial or other ?
The bluetooth protocol adds further protocol layers on top of the USB layer and this is a challenge for complexity and also for the limited memory in the Arduino.
If you want serial or some protocol for which an existing bluetooth module is available, then best to use that.
The Max3421e will work to USB bluetooth dongle. I have it working on ARM processor and have now ordered boards from Oleg to try on Arduino. I use Max3421e here because existing modules do not support bluetooth HID which I use for PS3 and Wiimote. Even this is a challenge on smaller memory 168 Arduino. On top of the USB protocols which take almost half of the available Flash and RAM on a 168, I have to support two additional protocols for bluetooth (HCI and L2CAP) to get to the HID reports. I do not have space to include service discovery, or inquiry. It will be a challenge in the Arduino space and I will post progress here on the Arduino.
Software may also be dependant on the make of bluetooth dongle and it is hard to make general purpose in terms of drivers. I use dongles which use the CSR chip, because they are well documented. Many dongles have very poor or no documentation available.
Support of serial or IP would require additional protocol layers in bluetooth and on top.
I have just written a sketch to support the PS3 controller over wired USB for Oleg’s board, which should also support some wireless PS3 controllers such as Madcatz which come with a USB dongle. This is also needed so I can eventually pair the bluetooth PS3 controller to the arduino. When I get my board and have built and tested, I will post this first. Then I can work on the bluetooth part.
So give us some more detail of what you want to do, so we can better advise.
Hey Richard thanks for the info…
What i wanted to do is,use the P89LPC938 microcontroller from NXP to connect to a PC using bluetooth dongle.Since the microcontroller doesn’t support usb,i decided to use the MAX3420EECJ+ chip. The microcontroller sends some data to the Hyper terminal program.But it looks pretty complicated to implement this using bluetooth.I should try to implement the usb first 🙂 ….Can you please help me with this problem:-
The LPC938 microcontroller supports SPI interface.I want to use the MAX3420E chip to connect the microcontroller to PC using a usb cable.For test purposes,the microcontroller should send the hello world message to the Hyper-terminal program in windows.WHAT ARE THE THINGS I NEED TO KNOW ABOUT THE MAX3420E chip to write a C code to implement this usb connection?.I did read something about some usb enumeration code..but m not quite sure waht it means….Thanks in advance for you help… 🙂
Hi evreyboy ! I have a Blutooth USB dongle that contains A CSR chip ! Richard, you say that those chip are well documented, but I don’t manage to obtain them from theri website. I would like to register, but all my email adresses did not worked. Could you send them it is possible or tell me the correct way to download them ? Thanks
Hey guys, I just got an Arduino Deumilnove and I wanted to experiment with having it communicate through a usb bluetooth dongle. The arduino has usb connectivity built in so im hoping this could work since the bluetooth modems i saw were upwards of 60 USD where i found a dongle for 15 USD. I;d imagine that it might take some extra code to read but im uncertain of where to start. My arduino has the ATMEGA328 which i know has double the ram capacity of the 168. The dongle that i plan to use is a Ciraga BTA-6130. I chose this one because it has a 100m range. Any help would be appreciated.
Thanks
Showrov, The MAX3420E is a peripheral controller and not a host controller as well. This could be programmed to conect to a PC host, but not to a bluetooth dongle. I have never used the MAX3420 or the MAX3421 in peripheral mode. There are easier and in my opinion better solutions using readily available micros from Microchip, Atmel, Arm and others with already existing software.
Sprawly, The USB port on Deumilanove is also a USB peripheral specific for serial communication, so will not work to a USB dongle. You need the USB host sheild to use a USb dongle. If you just want serial connection, one of the modems is a lot easier.
Richard, you say that the CSR chip is well documented but I don’t finf anything on it. Could you help me ?
Hi Yannick, It does look like CSR have tightened their access policy, though I would suggest you talk to them to get access to bluecore 4 data. The CSR chips do comply very well to the bluetooth spec, so that is the base reference. If your device is BC41B143A as is mine, then I can send you datasheet.
I now have HCI layer working reliably on Arduino to Wiimote, and am working on L2CAP layer.
L2CAP layer is now working, so Wiimote buttons are working to Arduino over bluetooth. Still got some work to do to clean up disconnect process, only using about 70% of program and data space on AtMega168.
So we have WiiHID, on L2CAP, on ACL, on HCI, on USB, on MAX3421e, on spi! plus lcd and freemem as well.
Wow its awesome to finely found someone that did get a wiimote connected to an arduino directly. But could you please share your source and document it. I think it would do the community very good.
And besides that I have an project on my own for wich I want to use the wiimote but I’m just not capable of achieving what you have done.
I did find the datasheet here for the BC41B143A. The common $3 USB Bluetooth Dongles often use these.
http://pdf1.alldatasheet.com/datasheet-pdf/view/114802/ETC/BC41B143A-ANN-E4.html
Most programming information is in the Bluetooth spec. though for HCI and higher protocols.
This is an exciting platform. I would like to setup something like this:
1.) Arduino with bluetooth modem support to talk to
PC.
2.) This same Arduino to support USB host mode.
My goal is: Gather sensor data on external sensor device with USB interface –> Arduiono USB host mode –> Bluetooth –> PC.
Does this seem possible? The interface to the external sensor device is a simple serial interface.
Does this seem possible?
This can be done. However, I’d rather set it up differently – using regular Arduino connect USB Bluetooth adapter to the host shield and connect your sensor to the serial port of Arduino. Looks like it would be cheaper than Arduino with built-in BT.
hi,
I am trying to use an Arduino with USB Host Shield (http://www.circuitsathome.com/arduino_usb_host_shield_projects)
and a dongle bluetooth to read Wiimote for controling a DC motor.
I have already used the code at this link:https://github.com/ribbotson/USB-Host/blob/master/examples/wiiblue.pde
and now i’m trying to modify it .clearly it would be excellent if anayone can help
me to find functions to programme the bluetooth and usb (like :
Usb.setUsbTaskState( USB_STATE_RUNNING );
…etc
other than :http://arduino.cc/en/Reference/HomePage
thanks.
Hi
I am trying to communicate the usb shield to a Magnetic stripe card reader. The device recognize like a keybord. Here is the descriptor but i am not able to communicate with the device. i tried the code which is demontrated in this page. idont get any error and it successfully connect but the kbd_poll() doesnt print anything. Do you have any advice?
Thanks
Configuration descriptor:
Total length: 0022
Num.intf: 01
Conf.value: 01
Conf.string: 00
Attr.: A0
Max.pwr: 32
Interface descriptor:
Intf.number: 00
Alt.: 00
Endpoints: 01
Class: 03
Subclass: 01
Protocol: 01
Intf.string: 00
Unknown descriptor:
Length: 09
Type: 21
Contents: 10010001223F000705
Endpoint descriptor:
Endpoint address: 81
Attr.: 03
Max.pkt size: 0008
Polling interval: 0A
Enter configuration number:
Have you tried to swipe a card through the reader? Some devices won’t be returning anything until new information is available.
Thanks for the reply.
Yes i did, but nothing happens. There are 2 leds on the cardreader. a red and green. When i connect it to a pc before windows recognize it the green led blinks, but after some seconds it turns off and card reader read cards in any editor such as notepad. when i connect it to the usb-shield the green led never stop blinking. What do you think?
find how card reader is initialized by a PC – there are several free software-only usb sniffers out there. Then try to replicate it on Arduino.
I’m having the exact same issue. I used USBTrace to find out whats going on, but I have absolutely no idea how to replicate it on the Arduino.
Here is the log/trace:
http://leo.achargreaves.com.au/usb_trace.html
Can anyone shed any light?
Hello, did one of you suceeded to connect and read mag stripe badges with this shield?
Hello there,
I like your project, and I’m applying it on the USB keypad as well.
When I checked around its attributes, it has only one configuration and one interrupt endpoint and nothing else. So I assume it is like any other ordinary keyboard except the alphabets and stuff.
When it is Numlock-ed, it outputs when I pressed 1:
00 00 53 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 59 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 53 00 00 00 00 00
00 00 00 00 00 00 00 00
If it doesn’t have the Numlock, it gives me when I pressed 1:
00 00 59 00 00 00 00 00
00 00 00 00 00 00 00 00
I believed that the zeros in the 8-byte referred to the “key release” as what you mentioned in the blog, but I’m a bit confused of why it gives the sequence of zeros, 53, sandwiched inside is the command, and then the same sequence as the first one.
Or I should not worry as it is the programmers who wrote those sequences, and then it is all up to the user to exploit its commands, by testing the thing one button by one button?
Thanks.
Hello,
I am trying to work with a device in which the entries in the configuration descriptor are reversed – Class 03, Subclass 00, Protocol 00 comes first, followed by Class 03, Subclass 01, Protocol 01. Here is the configuration descriptor:
Configuration descriptor:
Total length: 0049
Num.intf: 02
Conf.value: 01
Conf.string: 00
Attr.: C0
Max.pwr: 32
Interface descriptor:
Intf.number: 00
Alt.: 00
Endpoints: 02
Class: 03
Subclass: 00
Protocol: 00
Intf.string: 00
Unknown descriptor:
Length: 09
Type: 21
Contents: 000100012220000705
Endpoint descriptor:
Endpoint address: 81
Attr.: 03
Max.pkt size: 0008
Polling interval: 0A
Endpoint descriptor:
Endpoint address: 01
Attr.: 03
Max.pkt size: 0008
Polling interval: 0A
Interface descriptor:
Intf.number: 01
Alt.: 00
Endpoints: 02
Class: 03
Subclass: 01
Protocol: 01
Intf.string: 00
Unknown descriptor:
Length: 09
Type: 21
Contents: 00010001223F000705
Endpoint descriptor:
Endpoint address: 82
Attr.: 03
Max.pkt size: 0007
Polling interval: 0A
Endpoint descriptor:
Endpoint address: 02
Attr.: 03
Max.pkt size: 0001
Polling interval: 0A
When I run the code provided, I get “Error attempting to configure boot protocol. Return code :5”. Is there a way to look up these return codes? Any suggestions?
Also, further information about the KBD_ADDR and KBD_EP variables would be helpful. I understand they are taken from the configuration descriptor but it is not obvious to me where you got these values from in your example.
Thank you.
Hello,…
is this USB shield only work with UNO? is the Duemilanove not support this?
thanks….
It does work with Duemilanove.
I have been running sketches for using the USB host and I have found a structure which I cannot find in the header files.
The structure is EP_RECORD and it is being called in the sketch for the keyboard.
http://www.circuitsathome.com/mcu/arduino-usb-host-part-4-peripherals#more-1075
where this structure and its function have been defined. In which header file this has been defined?
BR,
Vik
https://github.com/felis/USB_Host_Shield/blob/master/Usb.h#L71
Hi,
I’m a student working with a research team that is analyzing how USB Host Controllers operate. We’re trying to use your Host shield program and are receiving a strange error. We’re using an Uno and the first version of your Host Shield (from Sparkfun). The error that we’re receiving is that the byte declaration doesn’t work in newer Arduino versions, and the compiler recommends changing it to System.write() which doesn’t make any sense. This error appears the most in the MAX3421E and Usb header files that I grabbed from your github link.
Do you have any recommendations for fixing this problem or can you describe what the byte declaration is meant to do exactly?
Thank you,
Al
Hi – I am new to this forum, & was the one who bought an unsupported USB Host shield from Jameco & alerted Oleg to the problem. Obviously DFRobot has no real support to offer for their pirated design. I am trying to interface to a USB relay card from CANAKit (UK1104). It is a CDC type USB interface & Oleg’s Hub demo sketch will retrieve the device & configuration descriptors when I connect the host shield to a relay card via a 4-port hub, and the ACM-terminal sketch will retrieve the product descriptor: UK1104 |v2.1| http://www.CANAKIT.COM ID=C1, when the relay card is connected directly to the USB host shield & I use the Arduino Serial Monitor to send \r\n. It came with drivers for Windows terminal support (HyperTerminal, etc) & works fine with that using commands like RELx.ON, RELS.ON. RELS.GET & so on. The goal is to drive it directly with the Arduino UNO via the USB Host shield. I am unsure of the handshaking involved via the USB & what C/C++ statements are needed to send the right commands to the relay card. Thanks for any help you can give me.
It seems that everything is working and the issue is in the terminal program. Serial Monitor is not very good for interactive tasks – try something like Putty.
Thanks, Oleg. What I want to do, though, is use an Arduino sketch for full control. The plan is to use the USB relay card for switching on my HO railroad (complex sequences of railroad switches set, cleared & power reversed for different parts of the layout – too complex for grand kids to do successfully – I just want them to set a switch connected to an Arduino digital line & have the Arduino do everything in proper sequence). I already have C code for computing scale speed & direction based on magnetic switches triggered by the engines on Arduino digital lines, and displayed on a 4×20 lcd display. The next step is to add code to control the USB relay board connected to the switches & power lines to the track. I don’t want a PC in the loop at all. The relay card using USB seemed like a good way to go to add multiple relays isolated from the Arduino, except for the USB cable. The card responds properly in tests using HyperTerminal, but how do I send the commands (RelsON, etc) using C code in an Arduino sketch? Thanks
You said earlier that you can talk to the relay board using ACM terminal. This is how you send data to the board -> https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/acm/acm_terminal/acm_terminal.pde#L78 , the first parameter is number of bytes and the second parameter is a pointer to the data.
Thanks for your help, Oleg. I was finally able to use the Acm.SndData command to communicate with the UK1104 relay board, though not entirely reliably (my problems). I am new to C++ so have been doing a lot of studying. I decided I would try writing an UK1104 library class based on your acm_terminal code. I see the data types uint8_t & uint16_t & assume these are unsigned 8bit & 16bit integer types. Where are these defined? some base class I assume, but I can’t locate it. I have been using TextPad as an editor – looks to be worth buying. Thanks, Oleg
uint is unsigned int, 8, 16 is length in bits. They are standard C types. IIRC they should be defined in stdint.h You don’t need to worry about defining them, just use them ( and int_x for signed, valid lengths are 8, 16, 32, and maybe 64).
Thanks, Oleg. Your acm_terminal example code seems to communicate ok with a relay/IO board I have, which is a CDC class device. It supports about 75 character-based commands (like “RELAY1.ON”) & I have specified these in a character array. The plan is to pass a pointer to the desired command in the array, & use Acm.SndData to write to the device. I have an existing sketch which contains code for other activities for an HO train layout, which would pass the right code at the right time. My question is this: should I attempt to incorporate your acm_terminal code, along with the relay specific code & commands into a class library, or should I just put all the code into the original sketch. I am new to C++, but can see that it is powerful & is probably worth learning. In my working days as an engineer we used FORTRAN. Ha. Thanks, Oleg
greg
This would depend on what you want to do with the code – if you going to distribute a standalone application, it doesn’t matter, if you want to have a library of functions than combining them into a class makes sense. I don’t think you need acm_terminal, this is just a demo of send/receive.
Thanks for the advice, Oleg. Yes, I know there is some stuff in acm_terminal I don’t need, like code used for communicating with the terminal, but the USB related stuff & things like class ACMAsyncOper seem like they’re probably needed for handshaking with the relay device for proper communication. Is that the case? Also I don’t know the purpose of the LINE_CODING block of code (all the lc. stuff. Thanks again, Oleg.
greg comegys
You need to provide the
lc.
implementation. There are several ways to do this depending on how comfortable you are with c++. Since you just started the easiest way would be to just expand the terminal example implementing all the device-specific code in the sketch.Oleg – the manual for the relay board says “the actual serial port speed & parameters are not important as the port is a virtual port. If required set the baud rate to 115,200, Data Bits to 8, Parity to N & Stop Bits to 1”. Does this mean I can remove the Line coding related code. It seems to work & reach an ACM Configured state with the Line Coding statements commented out.
Hi,
I am new to this forum, I am trying to connect a temp datalogger to host usb shield in order to retry data to my Arduino.
My what I have with board_qc test:
Circuits At Home 2011
USB Host Shield Quality Control Routine
Reading REVISION register… Die revision 03
SPI long test. Transfers 1MB of data. Each dot is 64K……………. SPI long test passed
GPIO test. Connect GPIN0 to GPOUT7, GPIN1 to GPOUT6, and so on
Test failed. Value written: 00 Value read: FF
Press any key to continue…
GPIO test passed.
PLL test. 100 chip resets will be performed
Resetting oscillator
Reset number 0 Time to stabilize – 651 cycles
Reset number 1 Time to stabilize – 649 cycles
Reset number 2 Time to stabilize – 649 cycles
Reset number 3 Time to stabilize – 649 cycles
Reset number 4 Time to stabilize – 649 cycles
Reset number 5 Time to stabilize – 650 cycles
Reset number 6 Time to stabilize – 651 cycles
Reset number 7 Time to stabilize – 648 cycles
Reset number 8 Time to stabilize – 649 cycles
Reset number 9 Time to stabilize – 649 cycles
Reset number 10 Time to stabilize – 649 cycles
Reset number 11 Time to stabilize – 650 cycles
Reset number 12 Time to stabilize – 651 cycles
Reset number 13 Time to stabilize – 651 cycles
Reset number 14 Time to stabilize – 649 cycles
Reset number 15 Time to stabilize – 649 cycles
Reset number 16 Time to stabilize – 648 cycles
Reset number 17 Time to stabilize – 650 cycles
Reset number 18 Time to stabilize – 649 cycles
Reset number 19 Time to stabilize – 649 cycles
Reset number 20 Time to stabilize – 649 cycles
Reset number 21 Time to stabilize – 650 cycles
Reset number 22 Time to stabilize – 650 cycles
Reset number 23 Time to stabilize – 651 cycles
Reset number 24 Time to stabilize – 649 cycles
Reset number 25 Time to stabilize – 649 cycles
Reset number 26 Time to stabilize – 649 cycles
Reset number 27 Time to stabilize – 649 cycles
Reset number 28 Time to stabilize – 649 cycles
Reset number 29 Time to stabilize – 649 cycles
Reset number 30 Time to stabilize – 649 cycles
Reset number 31 Time to stabilize – 651 cycles
Reset number 32 Time to stabilize – 651 cycles
Reset number 33 Time to stabilize – 650 cycles
Reset number 34 Time to stabilize – 651 cycles
Reset number 35 Time to stabilize – 649 cycles
Reset number 36 Time to stabilize – 649 cycles
Reset number 37 Time to stabilize – 649 cycles
Reset number 38 Time to stabilize – 649 cycles
Reset number 39 Time to stabilize – 649 cycles
Reset number 40 Time to stabilize – 649 cycles
Reset number 41 Time to stabilize – 651 cycles
Reset number 42 Time to stabilize – 650 cycles
Reset number 43 Time to stabilize – 650 cycles
Reset number 44 Time to stabilize – 651 cycles
Reset number 45 Time to stabilize – 649 cycles
Reset number 46 Time to stabilize – 649 cycles
Reset number 47 Time to stabilize – 649 cycles
Reset number 48 Time to stabilize – 649 cycles
Reset number 49 Time to stabilize – 649 cycles
Reset number 50 Time to stabilize – 649 cycles
Reset number 51 Time to stabilize – 650 cycles
Reset number 52 Time to stabilize – 650 cycles
Reset number 53 Time to stabilize – 650 cycles
Reset number 54 Time to stabilize – 651 cycles
Reset number 55 Time to stabilize – 649 cycles
Reset number 56 Time to stabilize – 649 cycles
Reset number 57 Time to stabilize – 649 cycles
Reset number 58 Time to stabilize – 649 cycles
Reset number 59 Time to stabilize – 649 cycles
Reset number 60 Time to stabilize – 649 cycles
Reset number 61 Time to stabilize – 649 cycles
Reset number 62 Time to stabilize – 651 cycles
Reset number 63 Time to stabilize – 651 cycles
Reset number 64 Time to stabilize – 651 cycles
Reset number 65 Time to stabilize – 649 cycles
Reset number 66 Time to stabilize – 649 cycles
Reset number 67 Time to stabilize – 649 cycles
Reset number 68 Time to stabilize – 649 cycles
Reset number 69 Time to stabilize – 649 cycles
Reset number 70 Time to stabilize – 649 cycles
Reset number 71 Time to stabilize – 649 cycles
Reset number 72 Time to stabilize – 650 cycles
Reset number 73 Time to stabilize – 651 cycles
Reset number 74 Time to stabilize – 651 cycles
Reset number 75 Time to stabilize – 649 cycles
Reset number 76 Time to stabilize – 648 cycles
Reset number 77 Time to stabilize – 648 cycles
Reset number 78 Time to stabilize – 649 cycles
Reset number 79 Time to stabilize – 649 cycles
Reset number 80 Time to stabilize – 649 cycles
Reset number 81 Time to stabilize – 649 cycles
Reset number 82 Time to stabilize – 650 cycles
Reset number 83 Time to stabilize – 651 cycles
Reset number 84 Time to stabilize – 651 cycles
Reset number 85 Time to stabilize – 649 cycles
Reset number 86 Time to stabilize – 649 cycles
Reset number 87 Time to stabilize – 650 cycles
Reset number 88 Time to stabilize – 649 cycles
Reset number 89 Time to stabilize – 649 cycles
Reset number 90 Time to stabilize – 649 cycles
Reset number 91 Time to stabilize – 649 cycles
Reset number 92 Time to stabilize – 651 cycles
Reset number 93 Time to stabilize – 651 cycles
Reset number 94 Time to stabilize – 650 cycles
Reset number 95 Time to stabilize – 649 cycles
Reset number 96 Time to stabilize – 649 cycles
Reset number 97 Time to stabilize – 649 cycles
Reset number 98 Time to stabilize – 649 cycles
Reset number 99 Time to stabilize – 649 cycles
Reset number 100 Time to stabilize – 649 cycles
Checking USB device communication.
Device connected. Resetting
Reset complete. Waiting for the first SOF…
Getting device descriptor
Descriptor Length: 12
Descriptor type: 01
USB version: 0110
Device class: 00
Device Subclass: 00
Device Protocol: 00
Max.packet size: 40
Vendor ID: 10C4
Product ID: EA60
Revision ID: 0100
Mfg.string index: 01
Prod.string index: 02
Serial number index: 03
Number of conf.: 01
All tests passed. Press RESET to restart test
It seems all ok, but when I try to use this datalogger…it don’t respond, seems that the device is not supported…
I search and find that VENDOR_ID and PRODUCT_ID are not correct for the library…
Have any idea?
Thanks
Simona
Could you please post all descriptors from the device? https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/USB_desc
Hi
these all descriptors…
Start
01
—
Device descriptor:
Descriptor Length: 12
Descriptor type: 01
USB version: 0110
Device class: 00
Device Subclass: 00
Device Protocol: 00
Max.packet size: 40
Vendor ID: 10C4
Product ID: EA60
Revision ID: 0100
Mfg.string index: 01
Prod.string index: 02
Serial number index: 03
Number of conf.: 01
Configuration descriptor:
Total length: 0020
Num.intf: 01
Conf.value: 01
Conf.string: 00
Attr.: 80
Max.pwr: 32
Interface descriptor:
Intf.number: 00
Alt.: 00
Endpoints: 02
Intf. Class: FF
Intf. Subclass: 00
Intf. Protocol: 00
Intf.string: 02
Endpoint descriptor:
Endpoint address: 81
Attr.: 02
Max.pkt size: 0040
Polling interval: 00
Endpoint descriptor:
Endpoint address: 01
Attr.: 02
Max.pkt size: 0040
Polling interval: 00
Addr:1(0.0.1)
It seems that your device is proprietary ( Interface class FF ). Try to contact a manufacturer; alternatively, find out of your device works in Linux and if yes look for Linux driver source code.
Thanks!
I found cp210x.c that is driver source code…
Now what should I do? I should try to use it whith your library?
It won’t work with my library. You can use this source code to develop your own driver, if you’d like to.
Hi Oleg. I am having trouble getting the following block of code to compile. The USB relay device I am using requires a \r\n to be sent before a command, & the command (in this case RELS.ON) needs to be terminated in \r\n (“RELS.ON\r\n”). I am using string concat to do this. Thanks, Oleg.
String CMD;
String CRLF = “\r\n”;
String str1;
uint8_t rcode;
uint8_t buf[64];
uint16_t rcvd = 64;
uint8_t * dataptr;
Usb.Task();
if( Acm.isReady()) {
rcode = Acm.SndData(strlen(CRLF),(uint8_t *)CRLF); //send CRLF for :: return
delay(150); //wait for ::
CMD = “RELS.ON”; //will normally be supplied as a parameter in function call
str1 = String(CMD + CRLF); // add \r\n to the end of command
rcode = Acm.SndData(strlen(str1), (uint8_t *)str1);
delay(50);
error: cannot convert ‘String’ to ‘const char*’ for argument ‘1’ to ‘size_t strlen(const char*)’ &
error: invalid cast from type ‘String’ to type ‘uint8_t*)
Hi,
I’m having issues getting my device to work reliably with the FTDILoopback example. It works only sometimes, a lot of the time Usb.getUsbTaskState() returns 0xA0 USB_STATE_ERROR or just hangs. Is there something else I need to be aware of? Do I still need to manually set EPInfo like is done in this example? my usb description is:
—
Device descriptor:
Descriptor Length: 12
Descriptor type: 01
USB version: 0200
Device class: 00
Device Subclass: 00
Device Protocol: 00
Max.packet size: 08
Vendor ID: 0403
Product ID: 6001
Revision ID: 0600
Mfg.string index: 01
Prod.string index: 02
Serial number index: 03
Number of conf.: 01
Configuration descriptor:
Total length: 0020
Num.intf: 01
Conf.value: 01
Conf.string: 00
Attr.: E0
Max.pwr: 00
Interface descriptor:
Intf.number: 00
Alt.: 00
Endpoints: 02
Intf. Class: FF
Intf. Subclass: FF
Intf. Protocol: FF
Intf.string: 02
Endpoint descriptor:
Endpoint address: 81
Attr.: 02
Max.pkt size: 0040
Polling interval: 00
Endpoint descriptor:
Endpoint address: 02
Attr.: 02
Max.pkt size: 0040
Polling interval: 00
Addr:1(0.0.1)
I know it says that the device is proprietry but its just an FTDI device.
Thanks in advance
I’m using the latest version of the library with an arduino mega ADK (I have enabled the ADK in settings.h)
hi, Can you please provide me with a code and connection diagram to transfer data to and from into a pendrive using usb host shield and a leonardo board??
Mass storage code won’t work on Leonardo, you’ll need Mega or Teensy.
Working on a project with my son, we have a Mega 2560 and a USB Shield V2. We are interfacing a Logitech 3d Pro joystick, we have the joystick working to control motor controllers that drive motors for an ROV but here is the issue.
Things seem to work fine as long as we are plugged into the PC USB port to power the Arduino and the shield, once we unplug from the PC and attempt to hard wire the Arduino to 12V the shield seems to stop working and the motors stop working, plug everything back into a PC and it works again, something to do with data on inputs the Arduino?
This is strange. Usually, it’s the other way around – things work well while powered with external supply but stop when power is provided via USB. Check if your external supply is adequate – measure 5V and 3.3V rails on the side connector when external power is applied while USB is disconnected.
Hi Oleg, how can I add something like Keyboard.read function to the Keyboard library? I want the Teensy 2++ setup as a USB keyboard to be able to read keyboard commands from PC host like reset command (0FFx during a warm boot or restart).