atmega16u2 virtual serial example using LUFA Library

Sending data from a microcontroller is a pretty common requirement in a lot of the projects I work on. One way of doing it is sending serial data out from the uC to a serial to usb converter chip to a computer. This has the advantage of involving very little code overhead for both the uC and the computer. It does also make it more difficult to route on a PCB (especially trying to fit it onto a single layer) and of course you have to pay for the serial/usb converter chip which in my experience range from about 2.50 to 5 euro per chip. An alternative to this is to have the uC communicate directly via usb with the computer. This can be done on a uC entirely in software – the V-USB library for atmel microcontrollers allows almost any atmel micro to communicate via usb. This creates a large CPU overhead as most of the uC’s time is spent maintaining the USB connection – leaving little time for anything else. uC’s with USB hardware in them offset this problem to a certain extent by including dedicated USB hardware so less CPU time is needed to use USB. The LUFA (Lightweight USB Framwork for AVRs) is a library aimed at taking advantage of this USB hardware. It comes with loads of examples that work with several types of atmel chips. The one that I chose is the atmega16u2 because it was pretty cheap and it was used the arduino uno as the usb-serial converter for the board. This meant that there was schematics of the board layout available online which came in very hany for making my own board. This board was intended to be used as part of the PlantBot project I’m working on but it ended up just being a LUFA virtual serial test board. Here are some pics of the board:

atmega16u2-virtual-serial-lufa-board
atmega16u2-virtual-serial-lufa-board

atmega16u2-virtual-serial-lufa-board-PCB
atmega16u2-virtual-serial-lufa-board

What I wanted the LUFA library to do was pretty specific – the atmega16u2 should show up as a virtual serial port so that the computer can connect and read data from it like any other serial port. All of the other ways of communicating over USB eg HID etc wouldn’t do it. There was one example that came with LUFA that fit the bill – VirtualSerial. There were a few problems with getting this example to run on the atmega16u2 so I’ll document them and what the fix was.

First problem was the compiler giving out about an undefined reference to the function clock_prescale_set(clock_div_1);
This turned out to be an avr-gcc problem. The power.h file (link to reference manual) didn’t have the atmega16u2 listed in one of it’s conditions include lines. There is a part in the file that looks like this:

#if defined(__AVR_AT90CAN32__) \
|| defined(__AVR_AT90CAN64__) \
|| defined(__AVR_AT90CAN128__) \
|| defined(__AVR_AT90PWM1__) \
|| defined(__AVR_AT90PWM2__) \
|| defined(__AVR_AT90PWM2B__) \
|| defined(__AVR_AT90PWM3__) \

and it had the atmega16u4 but not the u2 version so I just added it in and all was good. If you are looking for this file, on my pc it is located at C:\WinAVR-20100110\avr\include\avr\power.h and to find the relevant part of the file do a search for the following: clock_div_1 = 0,

The next problem was that this virtual serial example was based around a seperate usb joystick example. This joystick example would read input from certain pins and send a certain string over usb. The problem was that this example doesn’t work with the atmega16u2 because it uses PORTE all over the place in its code and the 16u2 doesn’t have a PORTE. The compiler was not happy and since this problem was spread over several include files I decided to just remove all joystick related code and just have the virtual serial send over a string on a loop (“testing123” in case you were wondering). After all of the joystick butchering the example finally compiled – I plugged in the board and it was recognised as a usb device. It turns out that for the VirtualSerial to work in windows you have to install drivers for it. the driver file is in the VirtualSerial example folder of the lufa library. After installing the driver everything was hunky dory, I used putty to check the serial data coming in.

So it’s a big thumbs up for the LUFA library – it’s nice have just a chip and a usb port on a PCB and having it send serial data to a computer!

The PCB schematic and board files as well as the modified VirtualSerial example (joystick-less) is all available for download here. The PCB was designed in KiCad.

Click image for PDF of schematic:

atmega-16u2-schematic-lufa
atmega-16u2-schematic-lufa

Board layout:
brd

One thought on “atmega16u2 virtual serial example using LUFA Library

Leave a Reply

%d bloggers like this: