Ambitious Arduino newb.  Any help with USB?

I'd like to interface a usb keyboard with my arduino for input. Has anyone interfaced a usb cable or keyboard with an arduino before? Thanks for any replies!

You'll have much better results if you go ps/2. There is some information about ps/2 interfacing on the playground.

Would you be using it as a "full keyboard" reading all the keys, or just a few keys ?

What is it you want to control with the keyboard ?

My main interest in USB interfacing is because I'm interested in USB device hacking (such as xbox controllers, keyboards, mice, etc). Specifically, I'd like to implement a USB packet capturing/sending library and implement a keyboard echoing program that can recieve commands from the keyboard or pc, capture them, then send them. Basically, it'll end up being a USB echoing module. I feel that I could learn a lot from this, which is why I'm pursuing it so much. Thanks for the replies btw :)!

The peripheral end of USB, while complex, is a [u]lot[/u] simpler than the USB host end. The host part is well beyond the capabilities of the Arduino's ATmega chip. Think "full operating system needed." (Not entirely true, but gets you in the right frame of mind.)

There are some devices, such as the Vinculum discussed elsewhere on the forums for USB mass storage, that act as a USB host for a limited set of peripherals with a clearly defined interface.

It's far easier to hack USB devices before the signal ever gets to USB. A USB keylogger is a non-trivial device.

Now, it is within the capabilities of the ATmega to be a USB peripheral like a keyboard, mouse, or serial interface, but the Arduino isn't set up, hardware- or software-wise, to perform that job.

-j

If you can turn an arduino into a USB keylogger, that means you're interpreting a packet of data from the usb. All I want to be able to do is take a packet, store it in a logical block, and then simply send it back down the other end of the cable. I don't want to make a new peripheral or something that can drive a usb device, I effectively want to make a packet logger for USB devices.

I don't want to make a new peripheral or something that can drive a usb device, I effectively want to make a packet logger for USB devices.

Sorry, my mistake.

In any event, USB1.1 has data passing down the wire at 12MHz. About the only way I know of to make the Arduino compatible with USB is to run the Arduino at 12MHz. For logging that gives you one cycle to grab a bit, then bang! next cycle I have to grab a bit, too, which basically leaves me with no time to actually do anything with the bits, even store them to RAM.

I said you could modify the arduino to pretend to be a USB keyboard. That's a lot different than a keylogger.

I don't think the Arduino, or anything else in this microcontroller class, will do what you want.

-j

sad panda :'(

You could look up the data on the FTDI chip and see what it might be able to do for you.

This might help. http://www.flightsim.com/cgi/kds?$=main/howto/mind.htm

You may also want to get a dev kit for the USB AVR chips. http://www.atmel.com/dyn/products/devices.asp?family_id=607#1761

This is the dev kit which is a board that plugs right into the PC and I think it can do what you want though I'm not sure. http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3879 It's $31.92 from digikey.

sad panda :’(

If it was that easy an USB-analyzer wouldn’t sell for $400.
(That’s for the low-speed, low-cost version, sort-of bargain price…)
Me too sad panda

Eberhard

In any event, USB1.1 has data passing down the wire at 12MHz. About the only way I know of to make the Arduino compatible with USB is to run the Arduino at 12MHz.

I don't think the Arduino, or anything else in this microcontroller class, will do what you want.

One of the items on my very long to-do list is to look at if it's practical to enable the Arduino to act as a USB peripheral device using the AVR-USB code. My current (early stage) notes about Arduino and AVR-USB are available.

The current (non-Arduino) version of AVR-USB "can be configured to run off a 12 MHz or 16 MHz crystal clock or a 16.5 MHz RC oscillator clock."

A link to an Atmega32 USB host controller implementation can be found here or find the actual project here.

I suspect it's probably unrealistic to think you could "pass through" bits but you might be able to capture the bits for low-speed transactions. You've probably picked a good project to learn a lot from... :-)

--Phil.

sad panda :'(

If it was that easy an USB-analyzer wouldn't sell for $400.

just until somebody finds out it's that easy :-) not saying that it is though...

I was thinking AVR-USB as did follower... Can anyone explain the "per cycle" concept in the context of a standard Arduino?

If we run on on 16MHz, we have 16.000 cycles per second, right? Am i right that the ATmega168 can do "more than on" instruction per cycle? Is there a way to code precisely (keeping track of instructions) within the the Arduino IDE? I know they're doing it in ASSEMBLER. but is it possible using inline assembler? Is it possible to get the number of instructions that an arduino loop or command takes?

This reminds me of a lot that i wanted to find out in this life. can anyone help here?

i have a feeling that even passing through USB 1.1 data (while capturing what fits in RAM [first]) should be possible. i have not yet a clear image of what it takes to decode the stream though.

If we run on on 16MHz, we have 16.000 cycles per second, right?

16,000,000 cycles per second, actually (M = million)

Am i right that the ATmega168 can do “more than on” instruction per cycle?

No. One cycle per instruction (CPI). Compare to the lower end PICs, which are 4 CPI (4 clock cycles to execute a single instruction).

I think there are a few multiple-cycle instructions on the 168, but the datasheet will tell for sure.

Is it possible to get the number of instructions that an arduino loop or command takes?

Sure, just look at the assembly generated by the compiler and count instructions.

This reminds me of a lot that i wanted to find out in this life. can anyone help here?

i have a feeling that even passing through USB 1.1 data (while capturing what fits in RAM [first]) should be possible.

Sorry, ain’t gonna happen with an ATmega168.

IF you could run at double the USB bus speed (i.e. execute instructions at 24MHz) and you had plenty of RAM (not a safe assumption), you may be able to grab a USB packet as it goes by and store it. This actually assumes the loop overhead in your code is zero, which is not a valid assumption. Let’s add one cycle per iteration for looping, so we’re up to 36MHz for our minimum clock speed for capturing USB packets.

There may be hardware out there to help us out, but this is for a pure software solution.

-j

thank you for the help, kg4wsv. i think i got my picture straight.

16,000,000 cycles per second, actually (M = million)

i was talking about cycles per microsecond (cpms) ;) please, excuse the typo

Quote: i have a feeling that even passing through USB 1.1 data (while capturing what fits in RAM [first]) should be possible.

Sorry, ain't gonna happen with an ATmega168.

ok, the feeling has almost gone now. i just knew of of the term "instructions per cycle" not "cycles per instruction", so i assumed a number greater than 1. wrong assumption.

i think the reason i mixed this all up, was an article i read about how AVR-USB is done some time ago. i found it:

For a USB 1.1 compatible low-speed device, a bit stream of 1.5 Mbit/s must be decoded. For a processor clocked at 12 MHz, this means that we have 8 CPU cycles for each bit. Being a RISC processor, the AVR executes most instructions in a single clock cycle. This gives us roughly 8 instructions to do the following operations on each bit: [...]

( http://www.obdev.at/developers/articles/00003.html )

So we are talking about low-speed USB which is "only" 1,5 MBits/second (assuming all standard keyboards are low-speed). Which partly brings this feeling back... Still i'm aware of the limitations in RAM and the challenge to boil the code down to less than 8 instructions.

i didn't know that AVR-GCC would output any readable assembly. is there a way to read the hex files in text instructions rather than numbers? i think i don't need all this for what i'm doing, but surely interesting to know.

kuk

Hi kuk,

So we are talking about low-speed USB which is "only" 1,5 MBits/second (assuming all standard keyboards are low-speed). Which partly brings this feeling back... Still i'm aware of the limitations in RAM and the challenge to boil the code down to less than 8 instructions.

here go your last hopes I'm afraid...

This is from the wikipedia article on USB

USB signals are transmitted on a twisted pair data cable with 90[ch937] ±15% impedance,[5] labeled D+ and D[ch8722]. These collectively use half-duplex differential signaling to combat the effects of electromagnetic noise on longer lines. D+ and D[ch8722] usually operate together; they are not separate simplex connections. Transmitted signal levels are 0.0–0.3 volts for low and 2.8–3.6 volts for high in Full Speed and Low Speed modes, and +-400mV in High Speed (HS) mode.

So the voltage levels on the USB-cables are not even clean 5V or even 3.3V signals.You would need some kind of ADC conversion before you start to even think about storing the data.

Really, not with the arduino, no way ;)

Eberhard

I had forgotten about low speed USB (1.5Mbit). For some reason I had assumed that still went across the wire at 12MHz like the "full speed" (USB terminology doesn't make sense to me, so I could be using it wrong).

i didn't know that AVR-GCC would output any readable assembly.

Yep. From the gcc man page:

 -S  Stop after the stage of compilation proper; do not assemble.  The output is in the form of an assembler code file for each non-assembler input file specified.

It's not pretty, and how the structure of the assembly relates to the structure of your C code depends a lot on the optimization level, but it's there.

is there a way to read the hex files in text instructions rather than numbers?

A hex file is just ASCII-encoded machine code. Machine code can be dis-assembled to assembly, but it's pretty ugly (yes, even uglier than "normal" assembly).

So the voltage levels on the USB-cables are not even clean 5V or even 3.3V signals.

That's not as bad as it seems - what you are seeing is the specification for your basic 3.3V differential signal. Get a differential to single ended conversion IC and you're back to a "normal" signal. You may even be able to get it to 5V by the same IC, or you could put in a level translator (diodes, voltage divider resistor network, or a dedicated IC), or you could build an arduino-like ATmega system that ran at 3.3V (I think the lilypad does this?).

I have been discussing purely software solutions, too. It is entirely possibly that you can find some hardware for a USB interface that does lots of this stuff for you: differential to single ended conversion, clock recovery, decoding the data, maybe even some checksum calculations, etc. I've never seen such a beast, but I haven't looked for one, either. Most USB devices I have seen are monolithic, highly integrated devices.

-j

Hi kuk, here go your last hopes I'm afraid...

i don't actually have a need for a USB logger. i was just surprised about the clear "no chance" resonance here, when i thought that similar things have already been done. i just wanted to know what makes you think/know so and i appreciate that you take the time to explain.

concerning the USB voltages for logical HIGH/LOW... i don't think that's too bad and almost within limits for the 5V driven atmega... i just wonder why that is. i thougt USB was 5 Volts all over. Couldn't the voltage conversion be easiliy solved with a fast opto-coupler?

kuk

oh, i missed kg4wsv's answer. thank you for the all the gcc/assembly info.

Really, not with the arduino, no way ;)

You are aware of AVR-USB which enables an AVR to act as a low-speed USB client device? Does this not mean it must be possible for an AVR to both receive and transmit the correct signals?

--Phil.

You are aware of AVR-USB which enables an AVR to act as a low-speed USB client device? Does this not mean it must be possible for an AVR to both receive and transmit the correct signals?

Yes, capturing low speed is within the realm of possibility for the ATmega, but high speed isn't.

-j