What started as a quick re-factoring effort transformed to a major redevelopment, but finally all pieces fit together tightly and I am pleased to announce that initial release of USB Host Shield library ver.2.0 has been posted to github. This new version contains several major improvements:
- Only 5 Arduino pins are now required for USB Host Shield to function – 3 standard SPI pins (SCK, MISO, MOSI) and 2 remappable pins (SS and INT).
- The low-level interface to MAX3421E has been re-designed. Arduino pin manipulation routines has been replaced with mechanism inspired by Konstantin Chizhov’s C++ AVR pin templates. As a result, low-level transfers became approximately 3.5 times faster. Also, pin reassignment can be done much easier by passing pin numbers into MAX3421E template during instantiation.
- The high-level interface to USB devices has been re-designed as well. It is now possible to connect USB hub to the shield and have many devices on USB bus, up to 7 daisy-chained 8-port hubs plus up to 44 devices connected to hub ports left after daisy-chaining, memory permitting. Also, a standard mechanism of device initialization/polling/releasing has been added to enumeration.
Several minor code improvements has also been made. NAK_LIMIT is now tied to an endpoint – it is now possible to have NAK_LIMIT set to 1 for interrupt endpoint and 32000 for bulk endpoint of the same device simultaneously. Control transfer function now accepts callback in order to split long chunks of data, if necessary. inTranser() function now is able to return actual number of bytes received.
Support for several popular device classes has been added. Device initialization and event handling is now moved to a library specific to device class, therefore user application does’n need to do this and only needs to process actual device data. The following devices are now supported by the library code:
- Human Interface Device AKA HID. Keyboards, mice, game controllers, bar code scanners, magnetic card and RFID readers – the list goes on. Initialization, polling, report descriptor parsing, as wellas reading and sending reports is possible.
- Asynchronous Serial over USB AKA CDC. Devices of this class provide serial connectivity. For example, newer Arduino boards, such as UNO and Mega 2560 communicate to a PC using CDC ACM-class device, while older boards, such as Duemilanove, use FTDI FT232 USB-to-serial converter. 3 main types of converters are supported – CDC ACM (newer Arduinos and most modern cell phones), FTDI FT232 (older Arduinos plus a ton of standalone converters ) and Prolific PL2303 (mainly used in USB cables for various cellphones).
Several other device classes are in the works and will be available soon. They include:
- Mass Storage Devices – Flash Drives, USB sticks, card readers, etc.
- PTP – a protocol used in digital cameras. The PTP code is being transferred from current PTP project with minor changes.
- Android ADK protocol, recently introduced in versions 3.1 and 2.3.4 of Android OS. Simple lightweight protocol for bi-directional communication with Android phone or tablet.
In addition to that, USB hub is supported by its own class; however, in order to use it nothing special needs to be done apart from defining an instance of hub class for each hub.
Library code is compatible with current revisions of USB Host Shield, i.e. full-size shield r2.0 and Mini shield r1.1. Older shields can be made compatible with new library by performing a simple hardware modification. I will add a section to hardware manual eventually, in the mean time, if you still have an old shield and want to know how to mod it to make it compatible with new library, drop me a line. It also should be noted that due to extra code needed for multi-device support binaries compiled from this library are larger than old one – before migrating your existing project make sure it will fit into your Arduino.
A hub_demo
directory under examples
contains a sketch demonstrating hub functionality. The sketch goes from hub to hub initializing devices and then prints their device and configuration descriptors. As can be seen on the title picture, I have a 24 port hub, which actually consists of four daisy-chained 7-port hubs, 3 cell phones, couple mice, USB-to-serial converter, Xbee plugged into Explorer board, digital scale, a pair of RC controllers, digital camera, and RFID reader. The output of a sketch running this setup can be seen here.
The following lines:
USBHub Hub1(&Usb); USBHub Hub2(&Usb); USBHub Hub3(&Usb); USBHub Hub4(&Usb); |
create hub instances, if you need more than four (up to 7), add USBHub Hub5(&Usb);
, USBHub Hub6(&Usb);
, USBHub Hub7(&Usb);
. If you need to address more than 16 devices, including hubs, increase USB_NUMDEVICES
in Usb.h
.
Except for hubs, the sketch doesn’t make any attempts to configure any devices, it can be run with any USB devices which are available.
At present, I only have one other sample sketch in acm
directory. It is a simple terminal intended to be used with cell phones. I will post details about using it soon. In the mean time, take a look at the cdoe, run sketches and let me know what you think.
Oleg.
Great work!
Thank you so much Oleg.
Hi!
Great to see usb-hub support!
What version of mini-usb are compatible with new library version?
The current (r1.1) Mini is compatible. Do you still have 1.0?
Hi Oleg,
Does the USB host library 2.0 make use of quantum leaps framework to process event?
Will you update the EOS Camera control lib to make use USB host Lib 2.0? What about focus function and video mode?
I’m trying to do with my 7D but I don’t have enough experience in Cpp.
I’m a C language..
Host library 2.0 doesn’t use QP. PTP is ported to a new library, I’m testing it right now. Focus and video will be added at some point too.
I see you used QP for the old PTP library. (QP is already released for arduino now.)
Do you still use QP framework for the new PTP library when porting to Host library 2.0?
According to your experiences, is it really benefit to make use of QP framework?
Thank you so much for your sharing Oleg
PTP library doesn’t use QP. Qhsm component of QP was used in a couple of sketches – this was before QP was ported to Arduino.
Fantastic, Oleg!
I’m wondering if there are optimizations at the newest library to use less SRAM.
About PTP: Mweerden is a friend of mine at the CHDK project. He sent me the source of the PC application and gave some orientations about their own PTP implementation. It gives access to an unlimited PTP Remote Control by sending/executing customized scripts even on newer cams without PTP RC from factory. However, I’m not familiar with the low level code at the PTP lib.
Do you want me to send it to you with his orientations for you to give it a try?
Thank you! I haven’t looked too hard at SRAM – it was never an issue. New code uses less RAM for endpoint structures but more RAM for hub support.
I’d love to see CHDK PTP code; maybe I can add support for CHDK-modified cameras to the library.
I sent you an email with all the details I got from him. 😉
wow this is really great. it took an hour or two of poking around before i realized how easy you actually made it. just so people are aware: to get a keyboard connected to a hub communicating properly, this is what’s required:
USB Usb;
USBHub Hub1(&Usb);
HID keyboard(&Usb);
…
loop()
{
Usb.Task();
}
This will start printing raw data into your serial monitor when you use the keyboard. you’ll have to write some helper methods to pull the data out (from what i can tell) but the hard parts are taken care of.
Glad you got it figured out :-). This was the intent – to create a device driver template of sorts with standardized initialization and event handling. HID is almost complete, I’m hoping to get the code cleaned up and post some examples in a week or two.
Very cool. 🙂
I was wondering how I might go about receiving input from multiple devices (2 USB mice, in this case).
USB Usb;
USBHub Hub1(&USB);
HIDBoot Mouse(&Usb);
Initializing both mice can’t be as simple as duplicating the third line…right?
Any insight and/or help would be greatly appreciated.
The object names must be unique. Something like this:
As long as they are connected to the same ports of the same hub they will be initialized in the same order.
Hmm. Seems to only connect to one mouse still.
Reads the one mouse fine though.
Powered USB hub has both ports w/ mice lit (powered).
USBHIDBootMouse sketch has been modified as such:
USB Usb;
USBHub Hub1(&Usb);
HIDBoot Mouse1(&Usb);
HIDBoot Mouse2(&Usb);
...
Mouse1.SetReportParser(0,(HIDReportParser*)&Prs);
Mouse2.SetReportParser(0,(HIDReportParser*)&Prs);
USBHIDBootMouse sketch outputs this during initialization:
Start
BM Init
Addr:9
BM Init
getDevDescr:D
BM Init
BM Init
Addr:A
BM configured
dx=1 dy=0
Have I done something wrong? Any ideas?
How many hubs do you have?
1 hub. 4 Ports. Powered.
This looks like a bug. I’ll try to replicate it. In the mean time, try to initialize your mice using different classes (one using boot protocol class and another one using report protocol class).
I can see the bug. My mice are both initialized, however, I can’t see reports from the second one. I’m looking into this.
cool. i came back to report that it’s not actually working 100%. 🙂 i noticed after awhile that it works “mostly”, but it sounds like you’re aware of that. i started tracing out the return codes from inTransfer and they are almost always nrNAK (0x04) or hrTOGERR (0x06).
I tested this with 2 different keyboards, with and without the hub, and i get the same results. It’s probably something simple but it’s not obvious to me what could be wrong.
NAK is normal – it means device has nothing to say to you. Toggle error most likely happens when you’re trying to read too many bytes (more than report size/max.packet size). Some devices are OK with that, others are not.
[…] sure you stop by Circuts@Home to check out the full details like the current/future supported device classes and supported […]
Hi Oleg. Some minor changes required for Arduino running on Linux because of case sensitivity in file names. I fixed it as follows (but you could fix it the other way to “max3421e.h” as well):
mv max_LCD.h Max_LCD.h
mv max_LCD.h Max_LCD.h
#change from max4321e.h to Max4321e.h in
address.h, line 22
cdcacm.h, line 23
cdcftdi.h, line 23
cdcprolific.h, line 23
examples/acm/acm_terminal/acm_terminal.pde, line 2
examples/board_qc/board_qc.pde, line 2
examples/hub_demo/hub_demo.pde, line 2
examples/pl2303/pl2303_xbee_terminal/pl2303_xbee_terminal.pde, line 5
hid.h, line 23
masstorage.h, line 23
max_LCD.cpp, line 18
Usb.cpp, line 20
Usb.h, line 25
usbhost.h, line 23
usbhub.h, line 23
The board test / QC program also doesn’t newline properly on Arduino in Linux. Changes required (change from ‘\r’ to ‘\r\n’):
board_qc.pde: line 116, 160, 166, 179, 218, 222
BTW, I didn’t have any success getting the V1 library to fire interrupts on transfers, rather than polling (on a USB keyboard). Is there some implicit limitation in the hardware, or should this work in V2, assuming I set the correct registers?
Nice work, by the way.
Thanks,
Colm
Hi Oleg,
Will you release the Camera control PTP library for USB host library 2.0 soon, or it take some more long time?
Sorry for the question, bc I just love your Host library 2.0 so much and waiting for PTP librar.. LOL
It’s almost ready, just need to finish testing.
Hi, Oleg,
do you have any estimates on date when the camera control ptp library will be released?
It is almost ready – I’m hoping to post something next week.
That is great news!
Thank you so much for your work!
In case you’d like some help on testing. I can help you on that.
I’m using 7D with Arduino Pro mini + Usb mini shield V1.1 + LCD…
I have experiences with C for a long time with Microcontroller like Arm-Cortex M3, Pic, dspic… But not C++
Thank you again Oleg..
WGL,
Jack
oleg: Hi, is it possible to run these 2.0 library on usb host shield from sparkfun? They have link to Your code on their website, but they had probably tested the older library. I tried these 2.0 and it doesnt work, maybe it is necessary to remapp some pins but i dont understand these new way to communicate with arduino with SPI … in older MAX3421E.h were defined MOSI,MISO etc. pins now I see SE0,SE1 …
maybe You didnt like to help with other board than Yours, I will understand, but when I bought this sparkfun shield I didnt know about this project…
Thank You Jan
I don’t know if this is possible or not – ask Sparkfun, it’s their product.
I didnt realize that your new board have SPI communication done with ISP header, maybe it will work with reassigned pins. I will try… Thanks Jan
Do you have a library or an easy way to access the GPIO pins on the board? I’m having a difficult time (probably just me being a novice) of finding the addresses of the pins. I tried looking at your examples of the EOSRemote for reading an encoder but it isn’t clear to me. Is there something I’m missing? Even something as simple as turning on an LED with the GPIO pins would be helpful.
Thanks,
Steve
there are 2 functions in MAX3421 template or anything that derives from it, like USB class. The functions are gpioRd() and gpioWr(). They read/write the whole byte, in order to manipulate single pin use bitmasks, look at max_LCD library to get an idea.
Hi,
I have an old USB host shield (5v version). What is to do to make it compatible with the lib v2?
Regards
Nils
Hi Oleg,
I have an old USB host shield v1.0. What hardware changes are necessary for the new library?
Regards
Nils
Hello Oleg,
I have the 1.0 mini USB-Host-Shield. What modifications do I need to make it work with the new revision of the library?
Ciao Martin
Seems the right basis for a project I am just starting to combine an aquino with a Nokia phone to make a remote controlled camera on a remote controlled car. Does the USB functionality extend to interfacing to Wi Fi devices to allow connection to a netwok.
Hello Oleg,
First – I am very impressed with your work – keep it up 🙂
I am completely new to Arduino. I have done a little reading and soldered a USB Host Shield I purchased from you lately to an Arduino Mega 2560 (which I received just yesterday).
I downloaded version 2 of the library from GitHub and placed it in the libraries folder.
I tried running the board_qc example and looked at the Serial Monitor.
The following is what I got:
—
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…
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…
—
Did I solder the USB Host Shield incorrectly? What could be the reason for this?
Thanks and Kind Regards,
Avri
The soldering looks correct. The GPIO test is failing because you don’t have GPIO loopback. Just press any key on the keyboard and the test will continue.
Thanks Oleg!
I have commented out the press_any_key() function call and all further tests succeeded! 🙂
I do not have a keyboard to test with, I am using an RFID dongle, acting as an HID keyboard device.
I’d like to get it to print to the Serial all the “keypresses” it sees (when I place an RFID tag next to it).
Is there any sample sketch that simply prints out keypresses to the serial port?
Thanks again and Kind Regards,
Avri
Hi Oleg,
I came back to check on updates and see that you removed the HID class! Presumably due to instability or bugs or whatnot… if this something you plan on working on again or did you remove it for good?
Sorry just curious… using this with HID is the only purpose I have for the USB Shield currently :!
HID code was posted by mistake 🙂 – I will release it for sure since it’s such a useful class. No ETA yet.
Eagerly awaiting the return of the HID class.
Hi Oleg,
I want to connect USB Gamepad (HID) and touchscreen display(HID) using hub built in into the display. I believe you had HID class in the library 2.0 but not anymore. I am sorry but I need to develop this project really urgently. Can you guide me how can I do that without HID class?
Many thanks!
HID class is going to be released today or tomorrow.
Wonderful news!
thank you so much sir!…waiting for it..:D
Hi oleg i have the old revision how can i make that compatible with the new host shield?
BTW its the full board
I’m using this shield (new version) and a duemilanove. I’m using usb host 2.0 library, and the SPI long test fails every time. (short test runs, die revision 03) My understanding is that the reversed reset and gpx pins were resolved, but I still get “Test failed. Value written: 01 read: 00” on the long SPI test.. if I comment that out and allow the other tests to run, I get GPIO test passed, current oscillator state unexpected, then “OSCOKIRQ failed to assert”. I do have external power connected as well, 12v 800mA. Any ideas? Much appreciated in advance =)
er I’m sorry I’m using the sparkfun shield (second revision), I copied/pasted from there and forgot to edit =)
If I knew what I know now I would have bought your shield for sure… sparkfun’s version seems to suck (especially for a newb like me)
Does the sparkfun work with the old library? 2.0?
I’m not familiar with Sparkfun shield, sorry.
What functions will be in your PTP library? Get Objects? Which objects from Canon 500D?
Canon functionality is the same. File operations will be added in the future.
With your file operations… Can I get a small buffer at a time? Send it serially thru USB before I get another? Or do I need more memory to store it all at once? Have you planned this yet? Looking forward to it!
PTP Transaction reserves 64 byte buffer which you can use using PTP file operations with callback derived from PTPReadParser class. PTPReadParser::Parse method receives the buffer pointer and buffer length as arguments. If you use PTP-derived class along with Hub and one of CDC classes you can receive file data from camera connected to one port on hub and send it serially to another device connected to another port. It’s theory, but it was not tested by now.
This is what Oleg means when he refers to adding file operations. I’d have to handle all these issues if I wanted to begin before he is done? Hopefully it will be easier with his library.
There are several methods in PTP class which implement file operations:
uint16_t GetStorageIDs(PTPReadParser *parser);
uint16_t GetStorageIDs(uint8_t bufsize, uint8_t*pbuf);
uint16_t GetStorageInfo(uint32_t storage_id, PTPReadParser *parser);
uint16_t GetObjectHandles(uint32_t storage_id, uint16_t format, uint16_t assoc, PTPReadParser *parser);
uint16_t GetObjectInfo(uint32_t handle, PTPReadParser *parser);
uint16_t GetObject(uint32_t handle, PTPReadParser *parser);
uint16_t GetThumb(uint32_t handle, PTPReadParser *parser);
The first three methods provide you with information about storages (flash cards) and their IDs. The next two provide you with file ids and info. The last two allow you to download files and thumbnails from the camera. You can not upload files TO the camera. That functionality is not implemented in the current version of PTP library.
Can you show me an example of how to use these methods to send an object via Xbee? Or at least give me a hint about how many lines of code it will take? I’m still in the planning stages while I’m waiting for more hardware…
Where is the best place for me to look, to see when file operations are added? Github? Here in the Comments? Or will you create another post?
I’ll surely make an announcement when file operations become available. I don’t see any practical application for such functionality, however, so it can take a while.
Wouldn’t it be cool to send a small thumbnail or large image via Xbee? The camera could be far away. Not possible? Not useful?
Hi,
I have an Arduino Mega ADK (from Arduino) and a Sparkfun USB Host Shield – maybe I should have bought yours… Anyway.
Is there a possibility to have a single USB library for all three of them? A define at compile time would be fine for me to switch. The ADK version of the USB 2 lib runs fine with the ADK but not with the Sparkfun shield.
Is there a link to the ADK version of the USB 2 lib? I can’t find in here…
This library does not work on the Mega ADK board while the previous one does.
It always reports “Failed to assert…”
To use this library, you need my shield.
So what library do I have to use to make the USB-host on this Mega ADK board work?
There is any reason because doesnt work with Mega ADK?
Its because of harware? missing pins or it just remaping, What pins are need SPI and INT or more?
Mega ADK (as well as all other xxxADK boards) is based on legacy design; it is not supported in rev.2.0.
Hello, Oleg! My USB Host Shield (Rev 2.1) passed board_qc test (except GPIO), when i connected my USB mouse. But when i connect my CDMA modem dongle it is endlessly waiting for device. I wish to send it AT commands. Is there a documentation on your library? I see only classes, methods but i don’t know what they are for, in what order to use them…
What is rev.2.1?
Sorry, rev. 2.0, don’t know why did i missed it. I can add that this dongle is used by my router without any problem. But USB shield can not detect it.
*did i miss
Have you tried any other devices?
Oleg, I’ve tried today my USB flash drive, it was detected without any problems. Keyboard was detected also. But Anydata ADU-310A
CDMA modem is not working (http://www.anydata.com/dev/11092010/modems.php#modem6). When i plug it in working arduino, in 70% cases it stops functioning (sometimes with garbage displayed in my serial monitor), even reset doesnt work (only unplugging power works). I guess it consumes too much power. But when i plug it in before turning arduino on, arduino works fine, modem loads (diods are ok on it), but it is still not detected by USB shield.
So, maybe i can check some registers of USB host shield processor and detect if there are some changes in their values?
P.S. i need this device really hard for my country-house alarm system, all works fine except modem USB shield. And CDMA is the only internet available there.
This could be because this device uses proprietary protocol instead of standard ACM. Do you have configuration descriptor from it?
I tried this with external power supply, same thing. Modem is 100% functioning, i use it with my wifi router.
Answering for your September, 21st post.
Following the code, in board_qc example arduino receives USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE for every Usb.getUsbTaskState();. So, it doesnt branch to USB_STATE_RUNNING condition and Usb.getDevDescr(…); is not issued. Device descriptor is a parent of configuration descriptor, so no configuration descriptor is queued for this modem. So the issue is surely in Usb.Task(); function.
Just tested that modem on my laptop. Without drivers, Windows detects it as combined(or composite?) USB device and two data interfaces. I can read some system parameters about this device from Windows device manager, but found nothing useful for me there. I can tell them on your request.
P.S. If you still want Configuration Descriptor, how can i get it?
Sitting in WAIT_FOR_DEVICE state means host controller can’t detect device attachment. Which shield variant are you using?
http://www.ebay.com/itm/ANDROID-ADK-USB-Host-Shield-ARDUINO-UNO-MEGA-/130558046999?pt=LH_DefaultDomain_0&hash=item1e65ddb317 – i have this.
I suggest contacting the seller – I don’t support clones.
I noticed my modem would not connect when connected to this board I had to have a 9V battery pack attached to Arduino
I had 12V adapter attached to Arduino – didnt help
My intention was to control a Nikon camera which was supported in your PTP 2.0 lib
but it looks like I might forget about this with this now useless mega adk board 🙁
Thanks anyway 🙂
Can I establish Bluetooth Connection with this Rev 2.0?
Or Should I need more works for recognize BT chipsets?
If you have any idea, Please let me know.
Thanks.
The Bluetooth code for rev.2.0 is not ready yet, you’d have to write your own.
Thanks for answer.
so, can I use BT code[https://www.circuitsathome.com/mcu/bluetooth-code-for-arduino-usb-host] with rev 1.0?
you can use this code to connect two Arduinos via BT.
Can I establish Bluetooth Connection by Bluetooth Dongles with this Rev 2.0?
Or Should I build more library for recognize BT chipsets?
If you have any idea, Please let me know.
Thanks.
Hello. If you got a code for version 1 that says:
EP_RECORD ep_record[ BT_NUM_EP ]; //endpoint record structure for the Bluetooth controller
What should you do to make it work it for version 2, as well? 🙂
You can’t. The data structures in r.1 and r.2 are different, the r.1 code won’t work with r.2, you’ll need to re-write it.
Just received USB shield, that was fast. Thanks!
Need to change pins for SS and Int as have a couple of other shields using pins. Baseboard is Uno.
The docs have software mod for old library, what is the mod for 2.0 version of lib?
Thanks.
https://github.com/felis/USB_Host_Shield_2.0/blob/master/Usb.h , line 48 .
Did anyone try to use this library with the Arduino 1.0 release candidate?
I gave it a shot. Went through all the files and changed all includes for wprogram.h to arduino.h (that file had its name changed) but then I ran into a bunch of compilation errors that I don’t really understand.
Any suggestions?
In file included from C:\Program Files (x86)\arduino-1.0-rc1\libraries\USB2\cdcprolific.cpp:17:
C:\Program Files (x86)\arduino-1.0-rc1\libraries\USB2\/cdcprolific.h:135: error: expected identifier before numeric constant
C:\Program Files (x86)\arduino-1.0-rc1\libraries\USB2\/cdcprolific.h:135: error: expected unqualified-id before numeric constant
C:\Program Files (x86)\arduino-1.0-rc1\libraries\USB2\cdcprolific.cpp:19: error: expected unqualified-id before numeric constant
C:\Program Files (x86)\arduino-1.0-rc1\libraries\USB2\cdcprolific.cpp:25: error: expected unqualified-id before numeric constant
Arduino 1.0rc uses ‘PL’ name internally. If you don’t need Prolific drivers, just remove cdcprolific* files from the distro. If you do need them, change the name of the class.
Thanks!
Also, in message.cpp, print(c,BYTE); needs to be changed, probably into write(c); as it seems the BYTE keyword has been removed.
Now everything is compiling. Maybe it even works.
Fredrik
I just changed it to print(c) and that seemed to fix the last compile error (after fixing all the Wprogram references.)
I got the USB shield talking to a USR USB modem just fine.
Thenks to Oleg for his fine work!
Mark
Hi –
Thanks for USB shield (super fast shipping!) and libraries. It is working fine, i.e. the QC test is passing and I can run examples for USB mouse etc.
However, other pins seem to cause conflicts, which seems to be a software issue. For example 2 servos are connected on pins 11,12 (tried re-mapping to various pins), which work fine without initializing USB. However, as soon as the servos are physically connected, USB won’t work any longer. In case of the USBHIDBootMouse example, the output simply becomes: Start / OSC did not start (also, one of the servos is moving in some quick pattern after reset).
Any idea what is going on? Am I missing something?
Thanks!
USB Host shield uses pins 9 through 13 by default. Only pins 9 and 10 can be relocated. You need to move your servos from pins 11 and 12. See UHS hardware manual for more info -> http://www.circuitsathome.com/usb-host-shield-hardware-manual
Oleg,
I’m interested in using the FTDI portion of your library but there is no example code include. I thought I could try to be enterprising and modify the pl2303_gps code to fulfill my needs in interfacing with a GPS device which happens to use the FTDI chipset rather than Prolific.
Unfortunately, I’ve run into some issues. I was hoping you could steer me in the right direction.
First off, it wasn’t quite as easy to replace all references to Pl to Ftdi. It seems that the two classes are a bit different. Rather, the way they deal with AsyncOper objects is. The Prolific header file doesn’t declare the PlAsyncOper. Therefore in the example code you can declare one, inherit from CDCAsyncOper and implement the OnInit function. But FTDI is a bit different. There is an FtdiAsyncOper class declared in the .h. It is an abstract base class though, as it has a pure virtual function OnInit in it. Additionally, it isn’t a child of CDCAsyncOper. Nor do the FTDI and PL classes inherit from the same parents.
Therefore, I assume that I need to create my own class (call it MyFtdiAsyncOper) which inherits from FtdiAsyncOper and implements the OnInit function. Unfortunately, I don’t know what this function really needs to do. On the Prolific side it sets up some of the basic comms configuration (baud rates, etc.) However, the FTDI class seems to provide mechanisms to carry this out directly.
Anyway, I carried out this approach (with a child AsyncOper and implementing OnInit… but with nothing inside). I can get the code to compile. But upon execution I’m seeing the following from the serial monitor (and not seeing any of the data I know is being pushed through on the serial channel):
###BEGIN OUTPUT###
Start
baud_value:1A
baud_index:0
FTDI Init
Addr:1
NC:1
0000: 09 02 20 00 01 01 00 A0 2D 09 04 00 00 02 FF FF
0010: FF 02 07 05 81 02 40 00 00 07 05 02 02 40 00 00
Conf.Val: 01
Iface Num: 00
Alt.Set: 00
Endpoint descriptor:
Length: 07
Type: 05
Address: 81
Attributes: 02
MaxPktSize: 0040
Poll Intrv: 00
Conf.Val: 01
Iface Num: 00
Alt.Set: 00
Endpoint descriptor:
Length: 07
Type: 05
Address: 02
Attributes: 02
MaxPktSize: 0040
Poll Intrv: 00
NumEP:3
Conf:1
OnInit:60
###END OUTPUT###
So… my basic questions are: 1)Why is the structure of the Prolific and FTDI code slightly different here? 2)And more importantly, how could I get the FTDI code working? Any chance of some example code? If not… what should I do in MyFtdiAsyncOper’s OnInit()?
Thanks so much for reading through my detailed questions and any help you can provide.
Here is FTDI example -> https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/ftdi/USBFTDILoopback , you’ll need to loop back TX to RX on FTDI chip to see it working. Code is different because chips are different.
Oleg, thanks so much for the super fast response and the example code I’ve been waiting for! I’ll play with this and let you know if I have any further questions.
I guess I understand the chips are different but I was hoping you’d be able to abstract that all away and expose the same SW interface… but that’s probably just my naive hopes and not very possible in this situation 😀
Oleg… I can’t tell you how great it is that you’re actively watching this page and helping people out!
I have one more (hopefully quick) question for you, if you don’t mind.
It seems that you’ve changed where the MAX_SS constant lives in the 2.0 version of the library. I tried following the directions in the hardware manual… but the constants .h file you mentioned doesn’t even exist in the new library.
After some hunting and grep-ing, I finally found line 48 in Usb.h:
typedef MAX3421e MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560
It seems I could change P10 to P6 were I to want to change SS from pin 10 to pin 6. I’ve already made the HW changes needed for this. Unfortunately, if I do change this line to represent P6 for SS and P9 for INT, and then re-compile the FTDI example you offered, it no longer works. (It just prints “Start” onto the Serial Monitor and nothing else). Further, when I jumper the board’s SS trace back to P10, it works again. So it seems like even though I’ve changed the .h file, that change hasn’t registered.
Am I trying to change the SS pin number in the wrong place? Do I need to do anything special to ensure this updated .h gets compiled into the sketch?
Thanks, again.
Darn HTML tags messing things up… that line 48 from Usb.h actually reads:
typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560
You are modifying the correct line; make sure to restart the IDE after you made the changes.
Thanks for the response but I still can’t seem to get this to work in the 2.0 library. SS seems to stay on pin 10 no matter what I do to the .h file. I’ve restarted the IDE a few times but with no luck.
Then I ran across this line (line 51 in usbhost.h) which seems to set a different pin as SS no matter what. Does this line need to be modified too? For instance if I wanted to change from pin 10 to 6 on an Uno, I’d change from:
typedef SPi< Pb5, Pb3, Pb4, Pb2 > spi;
to:
typedef SPi< Pb5, Pb3, Pb4, Pd6 > spi;
Or is this unnecessary? Can you think of anything else I’m missing in changing the SS pin (I swear, I’ve made the HW changes correctly). Has anyone else been able to successfully modify the 2.0 version of the library to use a different SS that could comment?
There are two pins called SS. One of them, which is assigned as SS in AVR SPI system, must be set as output (or an input set to 1 externally) in order for AVR SPI to act as a master. Another SS is the pin which is used to select MAX3421E as a slave for the SPI transfer. You can change the latter SS to whatever pin you want. For the former one, you can use it as output only.
Alright… it got the SS swap successfully done. It certainly is Usb.h line 48 that needs to be changed (or an additional #def put in place if you want to be slick). And usbhost.h can indeed be left alone. Others who want to modify SS inside of the 2.0 library… go change Usb.h line 48.
It turned out that all of my problems were from the Arduino IDE and multiple copies of the USB Host 2.0 library. I had a copy that I had made some other changes to and it seems that Arduino was always using its .h files rather than the correctly modified .h’s we’re talking about here.
Thanks for all the help and quick back and forth!
Oleg,
A colleague of mine, Ashish, posted something similar to the following message recently but it hasn’t yet been moderated. I wanted to post again incase it flew under your radar.
We are interfacing with a FTDI serial device. We are using your recently uploaded 2.0 library example code (USBFTDILoopback example).
Our use of the device doesn’t require us to send any data to the device… we’re just listening.
We know what data should be sent, periodically, to the host. However, we’re consistently missing some of it. What we’re missing changes from time to time. However, we can’t go more than about 100 or so bytes without missing A FULL LINE (yes, that’s right… not just individual characters/bytes, but always a full line). In its place is an unfortunate “Ret: 06” print out. The 06 is the return code from the call to the receive function.
After some header file sleuthing, it seems that this error code is defined in max3421e.h, as:
#define hrTOGERR 0×06
Any thoughts what could be causing an hrTOGERR error? Whenever the receive function ends up causing a hrTOGERR error, we end up losing the entire “line” of data (meaning, up to and including the \n at the end of the line).
In a previous posting, you mention something about how the packet size of the sent data seems to be more than the packet size at receiving end. Could you help us understand if this is happening to us?
Thanks so much for your time and any assistance you can offer!
Dave (and Ashish)
I have never seen toggle errors in correctly written code. Do you have issues with FTDI example from the library?
Yeah… a slightly derivative version of your FTDI loopback example.
We’ve noticed 2 issues, detailed below.
One issue we’ve seen is with a device that has the FTDI chip integrated and is constantly spitting out a stream of data (think of like a GPS receiver or similar).
The other issue we’ve seen is with a proto-boarded FTDI chip that has RX/TX looped back together (so essentially exactly what you said we should use for your example code).
1.) This is a USB FTDI serial device which is constantly throwing data at 57600 baud. To begin our work with this device we took your example code and made just a few small necessary changes. We changed the baud rate as appropriate. Since the device requires no input, we commented out the section of code which sends data to the DUT.
We tried running code with just those changes but after initialization print outs we see nothing coming in from the device. With some trial and error we eventually saw that if we increased the receiving buffer to 100 bytes, we’d start to see data come through. So, nothing seemed to happen (except for just the first “.” being printed”) with a small buffer. But with larger buffers (we tried many sizes between 100 and 256) the data would start to appear as expected.
Unfortunately, the data isn’t always complete. This is where we’d start to see “Ret: 06″ printouts in place of data we expected. One more thing I just noticed is that very often there are two new characters ” `” (that’s a space followed by tick mark) thrown inline with legitimate data. Please let me know if you’d like some scrubbed examples of what we’d expect to see vs. what we actually see.
This was with the FTDI Loopback code modified only for the correct baud rate, removal of sending, and lengthening of receive buffers. Also, let me know if looking at the exact code running would shed some light on this.
2.) The other oddity we saw with the FTDI loopback was in using exactly your example code with a loopbacked FTDI chip. With your code, as-is, it worked fine. However, when we changed the outgoing string buffer to >13 characters and the corresponding buffer size parameter in the SndData function, all printing to the serial monitor stops. I guess this indicates that the data isn’t getting out successfully as none of the receive code changed at all. Do you see the same issue? Instead of “DEADBEEF” try “DEADBEEFSTEAK” and “DEADBEEFSTEAKS”. With the 13 char version, all seemed fine. But the 14 char version seemed to stop sending. Again, we did modify the SndData’s length parameter appropriately.
Thanks again for your help and insight. Though my messages always seem to be so negative, I can’t tell you how great it is that there is someone who has made this shield and actively supports the corresponding library! Let me know if we can ever help give back in any way. Not sure if you’d be interested but we’re working on an USB Serial Ethernet translator project. At first, it will expose a serial stream as a TCP (telnet-able) data stream.
Sincerely,
Dave
Oleg,
Happy Holidays.
Have you had any more thoughts about what could be happening with these toggle errors that I’ve seen? Please let me know if there are any more details you would need or any strategies you’d like me to try out to pinpoint the issue.
Sincerely,
Dave
Not yet – I need to find time to replicate an error that you see.
Understood. I’ll likely play with it some more this week and will report if there are any additional tidbits of interesting information I notice.
Also I will be happy to be more specific about any part of the test setup I am using to help out. Don’t hesitate to ask if you’re curious. I really appreciate your support.
Sincerely,
Dave
Take a look at new https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/ftdi/USBFTDILoopback that I posted the other day. I made some changes to it, it’s now capable of receiving strings up to 61 characters in length plus null termination. FTDI places control information in first 2 bytes of 64 Byte buffer and fill the rest with data. Therefore, if you want to move > 62 bytes you’d have to add some buffer processing on top of
RcvData()
.I have a very similar problem. I would love to know if you solved this issue.
Thank you in advance!
Regards,
Sebastian
I am trying to get USB Host Shield working along with Ethernet shield. Rewired MAX_SS from pin 10 to pin 7, changed https://github.com/felis/USB_Host_Shield_2.0/blob/master/Usb.h, line 48 from to .
HID keyboard/mouse test does work, but after attaching Ethernet shield I am getting “OSC did not start” (tried two Eth.Shields from different shops). Ethernet shield (at least rev.06, which I am using), uses only pins 00-04, and pin 10. Is it possible interference on ICSP connector? What kind of workaround is possible?
You might have SPI conflict. Check to see if Ethernet Shield releases SPI bus when not selected. I know old version of Ethernet Shield was holding SPI even when SS was set high, not sure about later revisions.
I had to insert Ethernet initialization lines in order to get them both working. Looks like this issue has been resolved.
Thanks!
Hello,
First, Happy new year 2012!!
I’m investigating the feasability to port the library on the AT90USB1287 or AT90USB647. Since these MCU are USB host native (OTG) I don’t need MAX host shield.
I suppose it concerns the low-level interface to MAX3421E.
Is the impact on the code heavy? What is your analysis?
Regards,
Michel
You’d have to code AT90USB1287-specific Usb.cpp layer and everything below it.
If you plan to use the AT90USB1287 or AT90USB647 then you should use Lufa:
http://www.fourwalledcubicle.com/LUFA.php
Hey,
I’m still a bit confused how to use this library the right way.
What do I have to do to send/recieve data to/from a Usb device? My code doesnt work yet.
First, I select the right device by Using Usb.ForEachUsbDevic() (to get the address)
and the following code to check whether Vendor and product descriptor match:
if (descr.idVendor == GTR_VENDOR_ID && descr.idProduct == GTR_PRODUCT_ID)
{
Gtr = dev; //Assign usb device
Serial.println(“GTR found”);
}
That does work. Next, I want to send data. Since i know the endpoint (from usb_hub demo sketch and software on my pc), i use the following code:
(the array gtr_code_a has the length of 9 bytes and is definitely filled with data)
//Using Endpoint 0x02
result = Usb.outTransfer(Gtr->address,0x02,9,gtr_code_a);
As a result, the Library returns the code 0xDB. That means that I have to configure the Endpoint in the device-table first? But how do I do it?
(Does it matter if I use a usb-hub between the Shield and the Device?)
Regards,
Arthur
You don’t need to know device’s address. I’m assuming you’re writing your own device driver – in this case, take a look at how other drivers are written. The
Init()
method is called after device is reset and has address 0. The address is obtained from the pool and is assigned to the device and stored inbAddress
. The endpoint data structure is also filled inInit()
, there are several ways: for proprietary devices, take a look atadk.cpp
, for generic –hiduniversal.cpp
Thanks, i wrote a driver like the adk.cpp and it works now. However, I got the problem that after sending 2 arrays of data i always get the result 0x04 – wich means NAK, right? – that my device is busy. Is there any way to solve this? I tried waiting with delay() (tried from 1 ms up to 200ms) and several calls of Usb.Task() and the repeated try of sending the packet and waiting after it… But it seems that the Error stays there forever. Are there any other ways this problem could be solved? (I got software on my pc that interfaces with the device, written by me, and haven’t had this error there)
Oleg: Thank you for your response. I’ll check Usb.cpp
Richard: Yes! I know LUFA, but it does not support USB hub. This is the feature I need.
Another question: did someone succeed in interfacing with WIFI USB sticks?
Regards
Hi I’m interfacing to a USB device that acts a HID device but doesn’t return either a hid descriptor or a hid report descriptor, however I do know the format of the report returned based on information read elsewhere. What is the best way to tackle interfacing to this. Which code should I look at.
Thanks
Michel, You might try a hybrid of the Lufa with the hub code from Oleg, until Dean gets Hub support into Lufa. Are you wanting to drive multiple devices or just to hop over an integrated hub in a device ?
For the Wifi, though I guess not impossible there are major challenges. There are a very large number of dongles each with different proprietary interfaces. The interfaces tend to be undocumented in the public domain, so the only source of information is the source code from the Linux drivers. There are also hardware challenges due the large amount of RAM required for the entire data packets. Also many dongles download firmware, so you may need flash space for that too. You might consider one of the SPI or serial interface WiFi boards instead.
Richard, I want to drive multiple devices.
So, you mean it would be easier to “hack” LUFA with the hub code rather than modifying the Oleg’s library?
For the WiFi, I’ll consider the alternatives you recommand. Thank you.
Oleg,
I’m attempting to use the Arduino USB shield (rev.2.0) along with the Arduino Ethernet shield.
I have modified Usb.h line 48 to move SS to P6:
<blockquote cite="typedef MAX3421e MAX3421E;”>
I have also cut the SS “fuse” connecting it to P10, and soldered a jumper from SS to P6.
When I use the USB shield by itself, it works (I can see a mouse when I attach it.)
When I also connect the Arduino Ethernet shield it stops working with “OSCOKIRQ failed to assert”.
Just for grins, I ran the Circuits At Home QC test, board_qc, and I get this output, when connected to just the USB shield with no USB device attached:
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…
When connected to both the USB Shield and the Ethernet Shield with no USB device attached, I get:
Circuits At Home 2011
USB Host Shield Quality Control Routine
Reading REVISION register… Die revision invalid. Value returned: 00
Unrecoverable error – test halted!!
0x55 pattern is transmitted via SPI
Press RESET to restart test
Any thoughts on what I may be doing wrong?
Oops – I tried to use “block quote” so that the typedef would show up correctly. line 48 in Usb.h is everything between “”
you need to stack ICSP connectors on both shields. AFAIK Ethernet shield comes with pre-installed connectors and ICSP is cut. On USB Host Shield you can leave 2×3 pins uncut so that you can place Ethernet Shield on top of it and have everything connected. Is that what you’re trying to do?
Yes, I stacked the USB Shield on top of the Uno and the Ethernet shield on top of the USB Shield with ICSP connectors connecting them all. That’s when the “OSCOKIRQ failed to assert” message starts.
The code, below, works with just a USB and Uno. When I add the Ethernet, I get the OSCOKIRQ error.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include “pgmstrings.h”
class ACMAsyncOper : public CDCAsyncOper
{
public:
virtual uint8_t OnInit(ACM *pacm);
};
uint8_t ACMAsyncOper::OnInit(ACM *pacm)
{
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);
if (rcode)
{
ErrorMessage(PSTR(“SetControlLineState”), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 115200;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage(PSTR(“SetLineCoding”), rcode);
return rcode;
}
USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
void setup()
{
Serial.begin( 115200 );
Serial.println(“Start”);
if (Usb.Init() == -1)
Serial.println(“OSCOKIRQ failed to assert”);
delay( 200 );
}
void loop()
{
Usb.Task();
if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
{
uint8_t rcode;
/* reading the keyboard */
if(Serial.available()) {
uint8_t data= Serial.read();
/* sending to the phone */
rcode = Acm.SndData(1, &data);
if (rcode)
ErrorMessage(PSTR(“SndData”), rcode);
}//if(Serial.available()…
delay(50);
/* reading the phone */
/* buffer size must be greater or equal to max.packet size */
/* it it set to 64 (largest possible max.packet size) here, can be tuned down
for particular endpoint */
uint8_t buf[64];
uint16_t rcvd = 64;
rcode = Acm.RcvData(&rcvd, buf);
if (rcode && rcode != hrNAK)
ErrorMessage(PSTR(“Ret”), rcode);
if( rcvd ) { //more than zero bytes received
for(uint16_t i=0; i < rcvd; i++ ) {
Serial.print(char(buf[i])); //printing on the screen
}
}
delay(10);
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
}
Sorry – I obviously don’t know how to include formatted code…
I tested with several example sketches. With USB_desc, and USBHIDBootMouse, and hub_demo, I get an “OSC did not start” error. With acm_terminal (the basis of the code, above) I get the OSCOKIRQ failed message.
They all work when the Ethernet Shield is not connected.
Ethernet Shield apps seem to work fine whether or not the USB Shield is in the middle of the stack.
It looks like SPI conflict. USB Host Shield releases SPI bus when not in use. I don’t know if Ethernet Shield does the same – you need to talk to the authors.
you can use “code” “/code” pair – use angle brackets instead of quotes
Thanks for taking a look. Also thanks for the tip on including code.
Also, when I comment out the GPIO test, connect a USB device (a mouse) and run board_qc, I get:
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
PLL test. 100 chip resets will be performed
Resetting oscillator
Reset number 0 Time to stabilize – 520 cycles
.
.
.
Reset number 100 Time to stabilize – 556 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: 08
Vendor ID: 046D
Product ID: C00C
Revision ID: 2110
Mfg.string index: 01
Prod.string index: 02
Serial number index: 00
Number of conf.: 01
All tests passed. Press RESET to restart test