Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
V-USB – A Firmware-Only USB Driver for Atmel AVR Microcontrollers (obdev.at)
117 points by colinprince on Oct 10, 2021 | hide | past | favorite | 31 comments


This has been around for a long long time now so it's super mature, and it's very cool! I've used it in the past to make some esoteric keyboard adapter.

You can do a lot with it, but you may run up against a ceiling once you've committed an AVR to V-USB use as the timing requirements even at low bit rates are very strict, and you might want to consider AVRs with built-in USB transceivers if this becomes limiting.


Me too! It's great. And one of the few samples of this sort of thing that worked right out of the box.


Many moons ago I "ported" V-USB to the Arduino platform (before any Arduino used an AVR with hardware USB support) & designed a small shield to enable the required hardware side:

* http://web.archive.org/web/20120204231721/http://code.rancid... (via http://web.archive.org/web/20200119053709/http://www.labrado... (No thanks to Google for screwing over Google App Engine early adopters.))

The project even got featured in a chapter in a book: http://web.archive.org/web/20120203210440/http://www.practic...

As I recall it, mine was not the first ever port of V-USB to the Arduino but was IIRC the first released with source & schematic.

Fun times & enabled some fun example projects (e.g. keyboards, "encryption" dongle, dynamic product/vendor ID driver fuzzing) before hardware USB support became more common & affordable.

I highly recommend the write-up of how they achieved the required throughput to make USB work: https://www.obdev.at/articles/implementing-usb-1.1-in-firmwa...

The write-up is the kind of engaging roller-coaster process of discovery narrative that I thoroughly enjoy reading. :)


Not to put too fine a point on it, but how can it be “usb 1.1 compliant” while ignoring “communication errors”?

Most of the devils in the usb protocol, the kind people resort to usb analyzers for are usually related to communications error states and transitions in the protocol that aren’t being handled properly.


For those curious:

Atmel AVR Microcontrollers are commonly sold as Arduino.

Some chips (not ATMega 328P but ATMega 32U4) have native support for USB. This allows them to be used as USB HID devices: a keyboard and mouse.

Here is someone else's tutorial:

https://codeandlife.com/2012/02/11/v-usb-tutorial-continued-...

And a shameless plug for an app that I wrote that uses an Arduino to turn your laptop into a keyboard & mouse, so you don't have to carry around an external keyboard for your Raspberry Pi.

https://hackaday.com/2015/06/27/keymouserial-solves-your-ras...

In practice I now use CNLohr's EspUSB because it's even smaller. I dug out the old KeyMouSerial code last week to turn a mouse scrollwheel and iPod clickwheel into a rotary encoder.

https://www.youtube.com/watch?v=FPBzOaLbWhM

V-USB can do much more besides: actuators (power switch, DMX), sensors (thermo, hygro), chip programmers, LCD displays... there are 170 projects listed on the Obdev page.

https://www.obdev.at/products/vusb/projects.html


I recently built a force feedback steering wheel from scratch, and used a 32u4 as the MCU. I started the project a few years years ago, but lost interest in favor of picking up 3D printing. It was a lot easier to finish now that I can make arbitrary 3D shapes. I ended up printing an inline 80:1 two stage gear reduction. Thankfully someone in 2020 implemented the HID PID stack for the 32u4. That dropped the firmware work from probably a month to only a few days. The AVR is a bit long in the tooth; I only get a few hundred loops per second while the USB stack is running. It's plenty fast enough for all the haptic effects to feel good, though. It helped to offload the quadrature decoding to a dedicated IC.

Years ago I made a control panel for Kerbal Space Program, and I used a V-USB based MCU to drive two analog voltage meters as fuel gauges. I also had an Arduino Uno in the control panel, but I used up every single IO pin on it doing a button matrix and LEDs. Enumerating the V-USB MCU is touchy, but once it's up it seems reliable enough to gamble Jeb's life with!


Is HID PID fully implemented on Windows / Linux (i.e. does it load a generic driver like USB ACM or USB HID mouse / keyboard). I remember that I looked into this, but couldn't find any recent devices that use this.


Yes, both windows and linux have generic driver support for USB force feedback devices. All the firmware needs to do is provide the appropriate HID descriptor. The tricky bit is that the windows driver doesn't fully comply with the protocol spec, though. So, vendors that rely on the generic driver implement their firmware to be out of spec so that their products work in windows. The linux driver is rather pedantic about the spec, and errors out during initialization if the firmware doesn't conform to it.

In order to get my wheel working on linux, I had to modify the arduino library to comply with the spec. It was clearly written to work with windows. I haven't tried it on windows yet, but I suspect that it wouldn't work. There are smaller wheel vendors with stale customer support tickets regarding linux incompatibility.

I assume this is one of the reasons that larger companies like Logitech provide their own custom drivers, despite being 90% compatible with the generic HID spec.

If you're curious, I forked the arduino library with my fixes: https://github.com/sgtnoodle/ArduinoJoystickWithFFBLibrary


Interesting. I know how tedious it can be to get this working across platforms (or even just one!). So, I guess it is possible to use this on linux (https://www.kernel.org/doc/html/latest/input/ff.html)?

I'm loosely involved with the HapticsIF (https://hapticsif.org). They are working towards a new haptic usage page. If I remember the sentiment of those meetings correctly, USB PID was considered very old and not easy to work with. Besides that a more recent haptics Usage page was considered limiting (only for single effects).


The USB protocol and driver are more a means for me than an end. What you linked to looks like the userspace facing API, rather than the USB PID driver specifically. My goal was to get Euro Truck Simulator 2 working. Presumably it's using the FF API, either directly or perhaps through a steam proton adaptor.

I got Dirt Rally sorta working too, but it wasn't really playable because the game doesn't seem to support multiple input devices, and I wired up my pedals through a separate 32u4 MCU.


Do you have any writeups, schematics, parts lists, and/or code you can share? I know folks in the flight sim community who would love to know more!


It's on my list of things to do, but I'm about 3 hobby projects behind documenting at the moment. :-)

The most interesting bit is probably the gearbox, since it's an 8:1 stage then a 10:1 planetary stage. It's all printed PLA, stainless steel bolts, and bearings from amazon. There's two motors (to make it look cool, since one motor with the 80:1 reduction is probably already excessive), and a 1024 count encoder on the sun gear, giving 40960 counts per wheel revolution. It's all designed around the mounting holes of the steering wheel I used, too, so it's very pretty.

The electronics are "boring" in that I used an Arduino Leonardo, a quadrature decoder IC, and a 13A rated H-bridge. The trickiest bit was adding a "braking resistor" to keep the power supply voltage from shooting up when applying deceleration torque.

Here's my fork of the Arduino library: https://github.com/sgtnoodle/ArduinoJoystickWithFFBLibrary

Here's my Arduino sketch containing my project specific code, including the motor control and stuff: http://sgtnoodle.com/files/steering_wheel.ino


I highly recommend using Dean Camera's LUFA stack if you are going to use the Atmel AVRs that have on-board USB hardware.

<https://fourwalledcubicle.com/LUFA.php>


Wow, I never would have thought it would be possible to bit bang USB. Did it once for a serial port and that was a big effort in itself


It's USB 1.1 low speed which is 1.5 mbps making it much more achievable than one might think on this class of hardware.


Only somewhat related, but what are some other cheap(~$1) MCUs for a few-key USB keyboard?


1. Any ATmega32U4 development board. Most commonly sold as "Arduino Pro Micro". Developing a keyboard emulator in the Arduino IDE is pretty easy; if you don't want to do that, LUFA is a great little USB stack.

2. Raspberry Pi Pico. Newer, so it's less well documented, but much more powerful.


Yes, Arduino, Raspberry Pi, and ESP8266 are the best "cheap MCUs" for personal use, quick shipping, good documentation, for a one-off USB keyboard.

For the RPi Pico specifically, the TinyUSB driver is the way to go. This also supports USB host (plugging a keyboard into the Pico), but that didn't support the mouse scrollwheel when I tried.

https://github.com/hathach/tinyusb/blob/master/examples/devi...

If you're interested in larger-scale manufacturing, and are willing to invest more time and effort in once-off R&D to reduce the per-unit cost, then there's a lot more options of other MCUs (e.g. PIC, Cypress, STM32).

https://en.wikipedia.org/wiki/List_of_common_microcontroller...

Mitch Davis gave a great talk at the Embedded Online Conference this year (which my wonderful manager assigned us time to watch during working hours!), where he bridges the gap between hobbyist Arduino development and professional Embedded engineering. (It's closer than you might think)

https://www.youtube.com/watch?v=mI4FDp5crhE

Miro Samek also has a great series of lectures (which I learned about in the same Embedded Online Conference), which then levels up from an Arduino-style "superloop" to an RTOS, Active Object design pattern, and beyond.

https://youtu.be/o3eyz1gEqGU?t=363

Welcome to embedded development, I hope you enjoy creating new gadgets, and don't forget to share your adventures with the community so we can encourage you along!


Slightly tangential, but I recently wanted a mechanical keyboard converter dongle with QMK.. the pro micro was there only viable option due to supported stacks.


I made such a thing using a board called "Teensy LC." I'm a long time user of Teensy boards for prototyping in an R&D environment, and the LC is the cheapest. My interest was just PgUp and PgDn buttons for a foot pedal page turner.

In addition, I programmed an ESP32 board to do the same thing, but as a Bluetooth keyboard. Both the Teensy and ESP32 can be programmed via the Arduino development environment.

Now there's cheap and there's cheap. The stuff I use is cheap in terms of, it won't break the bank for a R&D or hobby project. Then there's cheap in terms of wringing cost out of a commercial product, which I know little to nothing about.


> Then there's cheap in terms of wringing cost out of a commercial product

This is a very astute distinction that hobbyists wanting to go from Arduino to production often miss.

I went from the basically cost-unconstrained world of Medical Devices to wearable consumer sensors (e.g., heart rate monitors, etc.) and it was a bit of a shock to see just how much impact cost had. I mean, you know that in a "theoretical" sense, but it's completely different when you are dealing with it on a daily basis.


Thank you for commenting to ask your question, Hacker News does have many skilled people around from a variety of backgrounds including embedded systems! So your question is related.

The Edit feature is also very useful, and I often go back to add more details, like you added the (~$1) afterwards. In future, please can you write "Edit" when doing that? It appears that duskwuff has been downvoted, because they assumed that "cheap" meant for a personal hobbyist level, not a professional mass-produced level, and now their comment makes less sense because Arduino & RPi are more expensive than $1. Please do continue to use the Edit feature, it's cleaner than writing a new comment! Just please keep in mind how that affects others.

As for me, I use Arduino, RPi, and ESP8266 for personal use, and NXP i.MX RT1050 chips at work, all of which are outside the price range, so there's not much more I can say. I imagine that the chip shortage is raising many prices these days though.


There's a few variations of really cheap 8051 MCUs with USB support. https://hackaday.com/tag/ch554/


Are these ch554 family parts available in bulk? I don’t find them on mouser or Digikey for example.


The manufacturer appears to support direct purchase: http://www.wch-ic.com/services/buy_process.html

LCSC is another option: https://lcsc.com/products/Microcontroller-Units-MCUs-MPUs-SO...


You can find them on lcsc.


I wouldn't go any cheaper than stm32f0. Specifically there's STM32F070 for USB.


I've found the EFM8UB series to be some pretty interesting USB micros.


Thank you for puting the minimal circuit diagram right there. That was my first question.

Everyone else, make sure you check out the examples. Some of these are neat.

I have a feeling I'm going to have a lot of use for this later.


> Thank you for puting the minimal circuit diagram right there.

And I thank them for it being a proper schematic.

Far too many projects nowadays just give a drawing that is essentially a picture of how the circuit would be built on a solderless breadboard such as this [1].

[1] https://v6f7u6f8.rocketcdn.me/wp-content/uploads/2017/04/Mix...


Pretty cool to revive a bunch of old Arduino's as plug n play HID input devices across platforms!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: