Sunday, July 26, 2009

PIC 18f14k50 USB Interface Board: Part 2

This is the second episode about the PIC 18f14k50 USB Interface Board. This time I want to take about the usage of the JALLIB USB-Serial library and how it can be used in conjuction with the interface board.

USB is a fairly complex interface, besides the basic interface, there are defined a couple of higher level "protocols" which are target for specific "device" functions. Commonly used interfaces are the Human Interface Device(s) types, to support devices like keyboards, joysticks and other devices, another commenly used interace is the Communication Device Class (CDC), which is developped for a broad range of (serial) communication devices, like modems, RS-232 converters etc. HID devices will be discussed in another blog, today we're looking a bit closer on the CDC interface and how to talk to the PIC device with a terminal application via the USB interface.

In order to reduce the USB learning curve, we've devevlopped a special library (USB-Serial) to easily create firmware that behaves like a RS-232 port on the Host side (virtual COM port). The big advantage is that you can still use the good old terminal application(s) to talk with your PIC device via the USB interface (both on Windows and Linux and probably other Host operating systems)

As an example we use the 18f14k50_board_test.jal, we start of simple and show step by step how to use the usb_serial library.

USB Serial example code
We start of with a basic application, the code is listed below:

include 18f14k50                    -- target PICmicro

-- This program assumes a 12 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- Configuration bits may cause a different frequency!
pragma target clock 48_000_000 -- oscillator frequency

-- include libraries
include usb_serial
include print

-- initialize the USB serial library

-- main loop
forever loop

var byte ch

-- Service USB, call on a regular base to keep communcaiton going

-- check for input character
if usb_serial_read( ch ) then
-- nothing spectecular, echo ch + 1
if ch == "?" then
const byte str1[] = "Hi there \r\n"
print_string( usb_serial_data, str1 )
usb_serial_data = ch
end if
end if
end loop

The code is pretty straight forward, first the device file is included and the target clock speed is set. Then the usb_serial and print JALLIB libraries are included. The next step is to initalize the USB serial library by calling the usb_serial_init() procedure. Within the main loop, the usb_serial_flush() is called, so the USB serial Interface Enginge (SIE) is serviced on a regular base (the USB libraries are not interrupt driven, therefore this procedure must be called regulary.
The call towards usb_serial_read will check if there are character recieved from the USB Host, if a character has been received it will be echoed, unless the "?" character is send, then it will use print the "Hi there" string. Notice that the usb_serial library can be used in conjuction with the print and serial libraries, if the usb_serial_data argument is passed along (as the first argument) with the print related procedure calls.

Get it running
The code is compiled with jalv2 using the -loader18 -no-fuse. After compilation one can reset the PIC 18f14k50 USB Interface Board and holding down the program button. Now the PDFSUSB application can be used to download the HEX file file, after download reset the board. If everything went OK, it should recognize the USB-CDC device and ask for drivers (Windows only), select the driver (which can be downloaded from, file, by selecting the win2k_xp_vista32_64 directory. After installtion of the drivers, the host operating system will create a new (virtual) serial port.
After the (virtual) serial port is created, open the serial port with your favorite terminal appliction. The actual serial port settings does not really matter, once the serial port is opened, you can any send character, the character will be echoed unless the "?" mark character is sent, the it will respond by the "Hi There" sentence.

Wrap Up
So far about the usb_serial library, it shows how easy it is to create an PIC firmware application using which can comminicate with a Host PC via the USB interface. Upcoming blog will address more advanced usage of the USB interface by creating a HID device,.


  1. Thank you, this is very useful for me.
    I'm glad you are continuing the series.

  2. I can use usb_serial_flush() in an interrupt? In main loop I have delays and I don't want to loose usb connection...


  3. Hi Vasi,
    Tried it and it does not work correctly right now, how to investigate why it does not work.

  4. It works fine with HyperTerminal and the MiniTerminal in JalEdit but when I try to write my own terminal with Visual C# the serial port in C# doesn't work with the virtual USB serial port but works with a real com port. What's wrong ?

  5. The Visual C# serial port write function doesn't send the data but "times out" after the 9th attempt to send characters. The data appears to remain in the write buffer after closing because when I switch to the Mini Terminal in JAL Edit, the previous data is sent out imediatley after opening the virtual com port with Mini Terminal (or Hyperterminal).

  6. Hi T_Rex,

    I don't know if this help...
    This is what I encountered in Windows Vista. I'm using my board with both MiniTerm from Jaledit and this one written in C++ with Qt interface

    After a while, I installed some usb drivers for usb-to-serial device and a serial port for Win800 pic programmer. From this moment, I have same behaviour in both terminals as you have in C# application. I wasn't able to fix that by rolling back those drivers... maybe I did more than just installing those drivers...

    In Linux is still working as expected, no matter what I install...

    Unfortunately, my USB Serial CNC Router is not recognized by Mac OS X 10.4... It does not install a driver in /dev ... (ACM fail to install and is about some more restrictions added by Apple - relaxed on 10.5/10.6)

  7. Thanks Vasi for the tip on the QtSerialPort. It works very well on Windows Vista. I started learning about Qt Creator to write apps in C++ to communicate with the board and while I still need to learn a lot, I've had some success. Thanks again Vasi.