NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Implementing a standard USB device interface

December 03, 2010
by d3adl0ck3
d3adl0ck3's Avatar

Howdy All, I tried searching the forums but USB is such a common acronym I can't find what I'm looking for. The project I am working on is a peripheral device and I'd like to talk to it from my mac the same as a standard USB device such as a mouse. Can anyone point me in the right direction? Examples of how to use the device from the computer in C/C++ would be awesome as well. Thanks!

December 03, 2010
by Ralphxyz
Ralphxyz's Avatar

To "talk" to peripheral device using a MAC you use Terminal and then Screen.

After entering the Terminal application, type "screen /dev/tty.PL* 115200" to start communicating over the serial port.

Search the forum for Screen and you will see more discussions. Once you are in Terminal you can run any number of scripts to communicate between your MAC and the peripheral device. If you are just starting out using a script is probable easier than using a C/C++ program. Now is a good time to learn Python, it will do everything you want to do, but then again so will the numerous scripting languages already install on your MAC. Python is used in a lot of Nerdkit projects.

Let us know what you are trying to do and if you need help.

Ralph

December 03, 2010
by d3adl0ck3
d3adl0ck3's Avatar

Thanks Ralph, I can read from the micro across the serial connection using screen and also from python using the serial module (both of these tricks I picked up in the forum, largely from your posts I believe ;-) but I want to integrate the output from the micro (angular positions) into a C++ opengl application to interact with a 3d model. I'd like to avoid reading the stream of text from the serial port or tailing a file/pipe dumped from the python script. Since the original post I found some references to hidusb and an example of its usage called hidkeys that seems to do what I am looking for but so far I haven't started to try and make it work for me. This approach seems interesting but I have no idea what I am getting myself into trying it. Anyone have experience with something similar? This is an extension to my first microprocessor project ever and I'm probably standing on the precipice of the deep end... This morning I was getting some funky output in my python script but I have since resolved that so in the interim I may just dump that output into a file and tail it in my opengl app and come back the pure USB solution later.

December 03, 2010
by d3adl0ck3
d3adl0ck3's Avatar

One additional note, trying to open the serial connection from C is doing something weird which I haven't figured out yet. I pilfered this code from somewhere in the forums to try and connect to the serial. In the example I looked at it was primarily writing and in my case all I want to do it read so I omitted everything after the open call. For some reason the open call is blocking. If I pull out the USB cable the program exits with an error (fd < 0) as expected so I know SOMETHING is trying to do something... I have tried with O_RDWR and O_RDONLY. Probably something dumb but while I have you I figured I'd try. Thanks again!

#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char **argv)
{
  int fd;

  // Open the device file. Change this to match your device.
  printf("open /dev/tty.PL2303-0000201A\n");
  fd = open("/dev/tty.PL2303-0000201A", O_RDONLY);
  if(fd < 0)
  {
    printf("Error opening port.\n");
    return 1;
  }
  else {
    printf("Opened port on %d",fd);
  }
  printf("Port opened.\n");
  // rest omitted
}
December 03, 2010
by Ralphxyz
Ralphxyz's Avatar

Not that I'll be much help but are you on Linux or Windows?

Just quickly googling "C USB code" I see that you would need a driver for Windows.

For Linux apparently there is a API.

In order to "get some thing done" I would just do a continuous parse of a Python file dump.

I think you would find that it would be near real time. Anyway that would get you moving.

Ralph

December 03, 2010
by Ralphxyz
Ralphxyz's Avatar

If you are on LInux here is a interesting post.

There syntax for the O_RDONLY is:

if ((fd = open (name, O_RDONLY)) < 0) {
        perror ("can't open dev file r/o");
        return 0;

Ralph

December 03, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi d3adl0ck3,

I think there are a couple of concepts that are getting confused here. The cable that comes with the kit has a USB-Serial converter chip inside it. There is a USB driver for the cable (which you installed when first setting up your kit). The driver can talk to the chip via the USB protocol and presents the device as a serial device to the operating system.

If you wanted to do a true communication via only USB, it would be possible to do it, but you would need to write quite a bit of code on the MCU side to implement the USB device stack, and then you would have to write a driver on the PC side to read your device. Unless you develop your device to act like a device that already has drivers for like a standard keyboard or mouse. This would require you to not use the the cable we send you but instead connect directly to the USB pins, probably by cutting off a standard USB extension cable. Regardless this is not likely what you want to do.

What you probably want to do is just read the serial device from C/C++. What you are doing in the code above is reading the file directly, while this might work, it probably wont because the serial port hasn't been configured with the right baud rate. Unfortunately setting these things is system dependent since its the OS that handles the serial ports. Languages like Java and Python have written layers to abstract that away and its relatively easy to talk to a serial port. I know there are modules for windows C++ that deal with the serial port. Perhaps you can find something similar in the XCode documentation and such. Hope that helps a little.

Humberto

December 04, 2010
by d3adl0ck3
d3adl0ck3's Avatar

Ralph, Humberto, Thanks to both of you for your information.

In the shortest of terms I can make due with the parse of the python file dump. I had a problem to begin with where in the mcu I was doing the printf with rn as the return combo which probably works fine on windows but on mac/linux usually just a n is expected. The end result was that every line that came in caused all the lines before it to be printed again.

As per Mac/Windows/Linux I am running all three on a combination of machines but have been working with my nerdkit only on Mac so far. Is there a preference for Linux?

@Humberto Yes, I am considering implementing the USB device stack on the mcu and chopping down one of the millions of usb cables I have lying around. If a USB device implements the 'human interface device' (HID) specification then for windows at least it doesn't require a driver. If that's true on windows I'll eat a bucket of mud if it won't work on mac/linux!*.

The reason I was considering this was (a it says in the nerdkits AWESOME guide)

First, it converts from the USB protocol (which many computers have) to a serial port connection (which are becoming increasingly rare).

As serial ports are going away and programming for them seems a bit platform specific (Ok, I bet USB is too) I wanted to look into 'real' USB as an alternative, primarily as a learning experience. I found this sample but it was a bit dense for a quick afternoon prototype session so I was wondering if anyone in the forums had a good starting point.

*I won't really eat a bucket of mud. Gross!

December 04, 2010
by d3adl0ck3
d3adl0ck3's Avatar

p.p.s. @Humberto

The C Code reading from the serial port goes on to configure it to the appropriate baud rate. I didn't include that code since I can't seem to get past the initial open call and I need the fd to go ahead and configure the baud rate. The code below as well as the above was picked up somewhere in the forums...

printf("Port opened.\n");
// Change the baud rate of the tty device.
struct termios term;
tcgetattr(fd, &term);
cfsetispeed(&term, B115200);
cfsetospeed(&term, B115200);
tcsetattr(fd, TCSANOW, &term);

Post a Reply

Please log in to post a reply.

Did you know that you can generate hundreds of volts AC from your microcontroller with a little bit of circuitry? Learn more...