This device connects to a computer’s usb port and controls two small electric motors using the L293D. The atmega microcontroller uses the firmware-only USB driver from objective development.

Device description

The usbmot device controls up to two small motors, 600 mA current each, 1.2 A peak each, with an atmel atmega microcontroller connected to some host device via USB. The speed of the motors can be controlled with PWM.


Both firmware and host software are in the software package at the end of this page. In order to recompile the firmware, you will need an avr build chain (for example avr-gcc and avrdude), which you probably have if you found this page. To compile the host software, you will need a c++-compiler and the qt development package.

To compile the firmware, change into the firmware folder. Then edit the makefile and adjust device type and programmer. In order to remake the hex file, type “make hex”, and to transfer it to the device, type “make flash” (jumper 1-1 needs to be set).

To compile the host software, change into the qusbmot folder. You will need qt and libusb with their respective tools and header files to successfully compile. If both are properly installed, typing “qmake && make” should compile the program, which can then be executed by typing “./qusbmot”.

Usable AVR Microcontrollers

So far I’ve used this board only with an atmega 168. Due to pin compatibility, it should work with at least an atmega 8, 48, 88, 168. Since 12 MHz speed are needed, the low-voltage versions will not work. The firmware size is about 2 kiB, so all are a bit oversized, but in low quantities this is no problem.

USBAsp roots

The PCB is based on the USBAsp Layout. It can still be used as a programmer, however the USBAsp Firmware has to be modified since I changed the USB port and pins to use the output compare pins for PWM.

Jumper description

  • JP 1-1: Self programming: Needs to be set in order to program the device, and must not be set if the device is operating. Sorry, this is a bit inconvenient, a residue of the usbasp roots.
  • JP 1-2: Programmer Power: Powers the device logic from the Programmers power source.
  • JP 5: coupled power: Connects the motor and logic voltages. Might work for really small motors(take care that the current of the motor is much higher when under heavy load) or strong USB power sources.

Two red LEDs hack

When all that separated my board from completion were the two 3V6 Z-diodes, I asked for help in the – chat, and Loetmichel told me the 3.6 V Zener diodes can be replaced by 2 red LEDs each. If incorporated into the PCB, this might even look really nice, and add some information.

Free pins

in the pcb, some of the atmega’s pins are connected to pinheads, so the board can be extended. I’ve tested a rather crude servo control for PC2…PC5, but unfortunately, if there is activity on the usb bus, the timing will get disturbed and the servos will move without being told so. I guess one could use the two 8-bit timers with their pwm pins to avoid being disturbed by the high-level usb interrupt, maybe in the next version. If however you can live with a bad servo control, try the “trunk” package.

Board problems

  • JP 5 is too close to the power connector.
  • The L293D is a bit old and can only power rather small motors. There are some nice automotive ICs, but unfortunately, those chips aren’t that easily available. Another Problem of the L293D is the low allowed pwm frequency – with 5 kHz in a region that is acoustically displeasing.
  • The holes for screws are placed randomly.
  • Setting the jumpers for programming is not that comfortable. I guess I will use a USB bootloader for the next version, saves some wires, too
  • Probably a lot more.

License and warnings

The software for both the microcontroller and the host is available under the terms of the GPL, in the hope that it might be useful for someone out there. In Addition to the terms of the GPL, obdev, who provide the firmware-only usb driver, kindly ask and require additional terms that especially apply as long as the shared obdev vid/pid pair is used.

The atmega, especially if powered by 5 Volts as in this device, cannot comply to the electrical part of the USB standard. Nevertheless, it works well with a large range of computers. However, there is no guarantee that it will not destroy your USB controller or your entire computer, so keep in mind the last sentence of the GPL: This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

link to photos/elektronik/usbmot//usbmot_assembly_diagram.png link to photos/elektronik/usbmot//coll.png link to photos/elektronik/usbmot//usbmot.png link to photos/elektronik/usbmot//usbmot_in_action.jpg link to photos/elektronik/usbmot//usbmot_screenshot.png

filetype usbmot_software.tar.bz2 (723.15 kiB, 2008-11-03)
filetype usbmot_trunk.tar.bz2 (759.19 kiB, 2008-11-21)
filetype usbmot_schematic.pdf (93.99 kiB, 2008-10-29)
filetype usbmot_pcb.pdf (194.58 kiB, 2008-10-29)
filetype usbmot_eagle_pcb.tar.bz2 (73.22 kiB, 2008-11-21)

This entry was posted in Electronics and tagged , , . Bookmark the permalink.

12 Responses to usbmot

  1. paryl says:

    Andreas, this is awesome stuff. Exactly what I’ve been looking for! I’ve got it working using your example programs, but what I really need is a python version.

    Have you managed to control it using python? I’ve been trying for a few weeks now using pyusb, but nothing I do lets me communicate. I suspect it’s an issue with not knowing the proper endpoints, or something to do with the data I’m sending. I consistently get “error submitting URB: No such file or directory”.

    I’d love some hints if you have any to give…

  2. Andreas Goelzer says:

    Thanks a lot, nice to hear it helps you :)

    I don’t know how pyusb works, and this control-endpoint stuff is not exactly comfortable. But with vusb, options are limited. I’m planning to redo this with an at90usb162, that could then have a nice serial interface and work in more environments.

    If you just want to control this device from python, you can have python call the commandline-program with os.system(“./usbmot-cmd write 1 2000″) or such stuff, but that’s more a hack than a real solution.

    I hope you somehow get it working, good luck :)

  3. Alex says:

    Nice job…

  4. laosoi says:

    Hello Andreas Goelzer,
    Thanks for your project!
    Please tell me how to control 25A, 12V, 3800rpm brushless motor using this project?
    Help me, i want to control high rpm motor using usb!
    Many thanks

  5. Alec says:

    Is it possible make controler for 3 step motors based on atmega8 + L293D+USB ?

  6. tobi says:

    hi this is exactly what i was looking for..but how could i bring the firmware and host software to pc and to the atmega8?

    im am new at ansi c.

    at the moment i compile my c code with avr studio 4 and bring it on the atmega via yaap

    but i dont know which file from the software.jar i have to open to get the gui on pc and i dont know which file i should compile to bring it on the atmega8.

    in ur descritpion u say “Type” do u mean type in the DOS-console of the pc?

  7. Andreas Goelzer says:

    Sorry for answering so late. I’ll anwer anyway, for future readers…


    That is quite hopeless, this is for a small motor (500 mA max.). You’ll need some big mosfets for 25 A, and careful planning.


    One (small) bipolar stepper motor might work with this if you do some firmware rewrite. If you want 3 stepper motors you’d need 3 usbmot-boards, or design something else, I have something like that flying around here.
    If you want to build a cnc mill or some other 3-axes device, i’d advice against it. The l293d is too weak for serious stepper motors, and you can get more power out of stepper motors with constant current instead of constant voltage.


    sorry for not answering to your first post. Haven’t used this for a while, this firmware-usb with its inherent lack of a working communicating device class (cdc) just was too much hassle.

    The “usbmot” folder inside the archive is the firmware, the “qusbmot” folder is the host software.

    Yes, typing means on the console, but the article was written with linux in mind. in windows, after compiling just click on the qusbmot.exe.

    However i do not know how difficult it is to compile the host application in windows, the qt part is more or less trivial with the qt sdk (open the .pro file, hit run), but the libusb part needs some work. There is a mingw-version, so it might be doable or even simple for an experienced windows coder, but I’ve never used it in windows.

    If you plan on using java as host software, you might want to consider rewriting the firmware with the almost-working firmware-cdc (*) or using something like the ft232rl as i did with my usbservo project.

    (*) firmware usb allows only low-speed devices, and the usb standard does not allow cdc for low-speed devices. obdev’s v-usb implements it anyway, it works with some operating systems, your mileage may vary. The big advantage of cdc is that the software on the pc only needs to open a serial port, possible in almost all programming languages without libraries.

  8. Enda Asenjo says:

    Hi, i just believed i’d submit and allow you to know your blogs layout is truly messed up on the K-Melonbrowser. Anyhow maintain up the very good function.

  9. jesus says:

    Hi Andreas your project its great, sorry about my english I am from Mexico, I have some doubts the compiling process you comment that we have to adjust the uC type and programmer and then type “make hex” or “make flash”, but here is my problem that command where do i have to type it, in the windows command prompt? or where… I have an AVR programmer based on the USBASP so it’s really simple and I don’t know where exactly to type those commands because when i have to program my uC I do it via command prompt on windows , also I’m using Codevision for compiling, what program did you use AVR studio?, I hope you can clarify my doubts.

  10. Andreas Goelzer says:

    jesus: I wasn’t using an ide, just text editors. Yes, it would be the command prompt in windows, but that requires some setup(as make is still quite unix-centric).
    Compiling my code in codevisionavr should be easy, but unfortunately it uses an old version of obdev’s vusb that might be more difficult to compile. You might have more success replacing it with a newer vusb version and adjusting my code.

  11. Davis nuñez says:

    Hello, Wow that is interesting about this interesting project, but, could you help me?, I have not really aware of how to compile, What I mean, you could send the host and the. Hex? Greetings my email is

  12. Matt says:

    Hi Andreas,

    Thank you for sharing this interesting software. However, when i tried to build the Hex firmware,

    $ make hex

    I receive the following errors:
    avr-gcc -Wall -Os -finline-functions -DF_CPU=12000000 -Iusbdrv -I. -DDEBUG_LEVEL=0 -mmcu=atmega168 -c usbdrv/usbdrv.c -o usbdrv/usbdrv.o
    In file included from usbdrv/usbdrv.c:12:0:
    usbdrv/usbdrv.h:451:6: error: variable ‘usbDescriptorDevice’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    char usbDescriptorDevice[];
    usbdrv/usbdrv.h:457:6: error: variable ‘usbDescriptorConfiguration’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    char usbDescriptorConfiguration[];
    usbdrv/usbdrv.h:463:6: error: variable ‘usbDescriptorHidReport’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    char usbDescriptorHidReport[];
    usbdrv/usbdrv.h:469:6: error: variable ‘usbDescriptorString0’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    char usbDescriptorString0[];
    usbdrv/usbdrv.h:475:5: error: variable ‘usbDescriptorStringVendor’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    int usbDescriptorStringVendor[];
    usbdrv/usbdrv.h:481:5: error: variable ‘usbDescriptorStringDevice’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    int usbDescriptorStringDevice[];
    usbdrv/usbdrv.h:487:5: error: variable ‘usbDescriptorStringSerialNumber’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    int usbDescriptorStringSerialNumber[];
    usbdrv/usbdrv.c:70:14: error: variable ‘usbDescriptorString0’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    PROGMEM char usbDescriptorString0[] = { /* language descriptor */
    usbdrv/usbdrv.c:80:14: error: variable ‘usbDescriptorStringVendor’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    PROGMEM int usbDescriptorStringVendor[] = {
    usbdrv/usbdrv.c:89:14: error: variable ‘usbDescriptorStringDevice’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    PROGMEM int usbDescriptorStringDevice[] = {
    usbdrv/usbdrv.c:111:14: error: variable ‘usbDescriptorDevice’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */
    usbdrv/usbdrv.c:142:14: error: variable ‘usbDescriptorConfiguration’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
    make: *** [usbdrv/usbdrv.o] Error 1

    What could be the issue? Thanks very much.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>