Simple USB control - how to blink an LED via code?
June 25, 2009 1:28 PM   Subscribe

This is something that's been bugging me for a while.... Given a USB port and an LED (perhaps more components required?), and a program running on the PC, how do you get from here, to the simplest case I can think of - making a line of code flip the state of an LED? Either a practical example, or some recommendations for topics that would drag me in the right direction.

My interest in this is because although I get computers, I don't entirely get how they control the hardware that is attached. I have a vague sense of it, but it's too fuzzy to call knowledge.

So I guess I'm curious about very simple driver development, just as a conceptual link to understanding what goes on when something gets plugged in.

If it helps, my language of choice is Python because of the speed and flexibility of development, plus the interpreter which is a great way to get a feel for the language. Is Python up to the task? I'd prefer not to code in C/C++, and I'd really like to avoid Java. Windows preferred, but I've got Fedora and Ubuntu on other PC's if it drastically simplifies it.
posted by BishopsLoveScifi to Technology (12 answers total) 9 users marked this as a favorite is probably of interest. Note that those prices are in Canadian dollars.
posted by XMLicious at 1:48 PM on June 25, 2009

Best answer: Well, USB is probably a bad example, as it is very complicated. The USB 2.0 specification, for example, is over 500 pages long, not counting various associated specifications and errata. A better place to start is probably with the RS-232 serial port.

What exactly do you want to know? How device drivers are handled at the kernel level in Windows? Or do you just want a high level overview of what goes on when you plug in a USB device?

Or do you want to see userspace code that interacts with some kind of removable device? If that's what you want, here are the plans and specifications for a simple USB-based device with various LEDs and sensor inputs that uses a Python program called PlugUSB and USB library called PyUSB to collect data.

Here is a wiki with some more examples of how to use PyUSB. And information on how to install PyUSB on Windows.
posted by jedicus at 2:02 PM on June 25, 2009

Best answer: The USB spec is enormously complicated and there's no simple way to just toggle the state of one of the I/O lines. If your computer fully implements the USB port spec, then there should be a system call to disable the port power (in fact, the system should do it automatically if no device "phones home" in something like 100ms), and you could just connect directly to the 5V/GND lines and turn the port on and off. Unfortunately, hardly any manufacturer actually implements the full port spec (which is why, for example, you can build a USB humping dog).

Sadly, I think the "easiest" solution is to use a FTDI USB chip and then send a serial command that will toggle one of the output pins.

This whole function stopped being easy when parallel ports went away -- if you still have one (probably on a desktop PC), you've got 15-20 pins of glorious digital GPIO.

If you really want to over-engineer, this DAQ board will do exactly what you want and has plugin modules for Visual Basic & VC++.

Be careful if you go cutting into USB cables -- if I accidentally short 5V to GND on a cable, my Macbook is smart enough to (usually) just shut down the port, but my PC immediately shuts down the motherboard.
posted by range at 2:05 PM on June 25, 2009

Seconding the FTDI USB chip. However, be aware that this chip is basically "Serial output on a chip" -- there's functionality in there that makes the chip look like a serial port to software your computer, thus avoiding the complexity of USB I/O.

If your interest is controlling the physical world via your computer, you might want to look into Arduino, which is an opensource microcontroller board combining an ATMega328 microcontroller and the FTDI chip. You program the microcontroller in C, and can talk to it from your computer with any language that can address a serial port.
posted by Alterscape at 2:20 PM on June 25, 2009

Oh, and I should add -- the FTDI USB-Serial chip solution, in any form, simply simulates a serial port. A lot of USB peripherals use other device classes. For example, there's USB HID (human interface device) peripherals like your keyboard, mouse, etc. PIC (a competitor to Atmel's AVR microcontrollers) makes a few microcontrollers that can handle USB directly, and can implement HID or other profiles. I don't have any experience with them, though, and from what I've seen they're not as beginner-friendly as Arduino.
posted by Alterscape at 2:27 PM on June 25, 2009

Response by poster: These are all fantastic answers from all - just dropping a note to thank you and let you know I'm just busy reading what's been posted, and it's definitely all helpful.

I have to give a shout out to the humping dog thing - brilliant! It's about that level of sophistication (electrical, not intellectual) that I'm aiming for right now.... If I can make an electrical device do a repetetive motion I'll feel like I've accomplished something.

range: 'send a serial command that will toggle one of the output pins' - at the basic level that's exactly what i want. So I presume an FTDI chip or similar is just a basic requirement so that one can get the easy to understand toggling of pin voltage I'm after.

Perhaps I am confounding myself by trying to dig too deep into a black box (stuff that happens on that chip converting USB digital signals, to voltages on a pin) that should just be left as an abstract notion.

As I see it (however wrongly) at the PC end you write the code, which interfaces with a USB protocol library in your chosen language, which sends nicely formatted byte size data nuggets to the USB port. These are I assume buffered at the other end, re-formed and processed by a microprocessor which then sets the appropriate voltages it's been programmed to send in response, thus doing something.

Arduino is something to look at (familiar with Processing already whihc I think may help), but at the moment I'm just looking to examine the simplest case to get my head around the interface.

Apologies if some of this makes little sense - I'm having trouble defining what I know I don't know!
posted by BishopsLoveScifi at 3:10 PM on June 25, 2009

Best answer: In addition to all the other excellent suggestions in this thread, I'd like to point you at the USB Bit Whacker.

Your basic understanding is basically correct. At bottom (after some fairly complex exchanges to introduce the device to the host when it's plugged in) the host sends a brief serial message to the device; typically, hardware on the device stores it in a buffer and acknowledges with a response packet; the device's microprocessor reads the buffer and interprets it as a command to change the voltage on a pin or send some stuff out a serial line or something. (Note that the "serial" in "universal serial bus" is a high speed balanced synchronous signal that's pretty unlike the low-speed asynchronous serial of an rs232 port.)
posted by hattifattener at 3:30 PM on June 25, 2009

Best answer: That's right -- USB is a complex format meant to carry signals to a bunch of devices all multiplexed off the same connector (which is how you can buy $5 USB "splitters"). The data is sent in packets (more or less) whenever the computer decides would be a good time, and is addressed to the appropriate device. So there's no really good way of arbitrarily setting the state of one wire in the bus. You need to somehow emulate an older, dumber device (like a serial or parallel port) to get direct bit control.

Even serial is a little bit of a stretch; you would either have to fill the transmit buffer with 0xFF or 0x00 to toggle a pin state (in this case, the TX pin) or hope that you could get control of a handshaking pin (CTS, DTR, etc) -- I can't remember if the FTDI chip handles those automatically or if you can use them like (bad) general purpose IO.

Something like the humping dog (or fan, or, at my house, USB jack o'lantern) is way easier, because you just take advantage of the fact that 2 wires in the USB cable are 5V and GND, all the time, at probably 100mA -- but this isn't transmitting any information from the computer, just stealing power.
posted by range at 4:42 PM on June 25, 2009

range: The FTDI chips often have some actual GPIO pins in addition to their UART, and some can be put into modes for other behaviors (I2C, JTAG, MCU bus emulation, etc).
posted by hattifattener at 4:57 PM on June 25, 2009

Consider arduino or teensy. With either one, you can write what are essentially C programs (but typically very simple ones), There are some Arduino examples that talk to Python on the PC. Or you could try out something like bitlash (also on Arduino) which has a pretty complex commandline and seemingly is pretty powerful.
posted by jepler at 5:32 PM on June 25, 2009

It might be worth noting that the humping dog gets its repeating motion from a physical process, not an electronic one. A motor leaches power from the USB connection and runs at a constant speed converting it into reciprocating motion with a lever attached to the motor. There is no communication with the computer or even any logic on board the device. It's very easy to make a device like this that only draws power from the bus.

You can also got the other way with something like a MintyBoost, a simple little kit which will provide power to a USB connection from a couple AA batteries.
posted by Ookseer at 7:48 PM on June 25, 2009

Yep an arduino is the simplest way to do it.

The default "hello world" example that comes built in on the board blinks an LED.
posted by trialex at 9:36 PM on June 25, 2009

« Older minty fresh   |   What takes good photos that takes good photos? Newer »
This thread is closed to new comments.