USB Demo

Code Example
by DT v1 Dec 30,2006 USBDemo.pbp (PBP & VB) v1 May 8, 2007 USBDemo_2455.pbp (PBP) v1 May 8, 2007 USBDemo_2550.pbp (PBP)

Daryl provided the community with a starting point for utilizing USB communications with the PIC 8-bit family of MCUs. The posts are dated 2007, they use the PIC18F25xx_45xx processors, PBP2.6/3.0, with PC .exe files based on Visual Basic v6. In other words, much of the information is outdated a bit. For the PC operating systems of the day, they worked as described. The first part of this Section will be dedicated to revisiting and explaining what Daryl created. The second part will be additional information relevant to current offerings.

Hi all,

Since the USB stuff is becoming more and more popular, we see more and more questions, so I decided to post my little contribution. OK, OK, you already asked… but I’m in a good mood today, so let me start as though it had never been asked before.

This project uses a PIC18F4550 and a 4MHz crystal, a few LEDs and 2 trim pots. You should be able to figure it out fairly easily. Sounds good, eh?

With this you can:
1 - Play with both CCP(PWM) Duty Cycles and show them on 2 LEDs attached to your PIC CCP I/Os (PORTC.1, PORTC.2)
2 - Modify each of the PORTB bits as you wish

You can also:
1 - See the results of AN<1:0> ADC results in the progress bars
2 - Monitor the status of push buttons attached to PORTA<5:2> Inputs (with pull-down resistors)
3 - Receive a text string
4 - Display your VendorName and ProductName

Almost everything covered in both codes should be EASY. I tried to stay away from the cryptic-type coding, but couldn’t resist using some Macros, etc. Maybe you’ll learn from it, who knows?

In the ZIP file you will find ALL FILES.pbp source code, VB6 source code, AND a ready-to-run USBDemo.exe file. Everything is generously commented, so read it carefully! It won’t hurt!

My original folder was c:\PBP_PROG\USBDemo. You will have to put it on your PC in a place that makes sense to you. NOTE: If you’re going to use LONG variables, you MUST copy the PIC18Xxxxx.BAL file in your source directory as well or you’ll get compilation errors. The .BAL file is located in the \BPB\USB18 directory. The routines are set up to use the USB Interrupts, even though PBP doesn’t use them that way. It just needs a “kick-start” to get it going. The “kick-start” is simply a tight loop servicing the USB until the driver gets to the “CONFIGURED_STATE”. After that, it takes off and handles itself. But the best part is that it doesn’t use ANY PBP system variables to service the USB. This means the whole thing can be treated like ASM Interrupts, tied directly into the USB_INT Interrupt. (Editor’s Note; Assembly Interrupts are covered in the PBP3 Reference Manual, 6.2, starting on page 248.)

This also seems to improve the response time since it reacts immediately to each step of the USB protocol, instead of at Timer intervals, or whenever ON INTERRUPT gets around to it (but I don’t have any hard data to back that up yet). The original code was for a PIC18F4550. You will need to rebuild the project in EasyHid for the 2550, XX55, K50, or 16F145X MCUs. There are several required files. The 2455 and 2550 files are available in ZIP files above, and the schematic is available as a PDF, linked above.

There have been some reported glitches, which you may or may not experience. (Due to the age of the original posts, the attached files & code have not been retested for this article. Reference the following as pertinent to your own experiences - Ed.)
1 - “INTCON = %10100000. ‘Enable Global & TMR0 Interrupts” may cause TMR0 to attempt to start servicing USB before it Initializes.
2 - When you disconnect the USB cable, the PIC will still try to send data, causing it to enter a Locked Loop, trying to send to an inactive bus
3 - There is not any indication that data successfully transmitted. If there is no incoming data, it just sets DutyCycle% from the previously received buffer
4 - There is no indication of the connection, when data was received, or when it’s OK to send
5 - With the 1 mS Timer0 USBService, it’s a bit sluggish when enumerating. Overall data rates suffer as well
6 - EasyHID no longer works with 2.60
7 - The PC files are Visual Basic v6. Newer versions (using Visual Studio 2010-2017) will translate the file to your current version. However, if you use Delphi (or something else) you may not have the mchid.dll file. It can be downloaded from Microsoft’s web site (use the search engine).

USB Tutorial

This section is intended as a GUIDE to understanding USB communication protocol. Hopefully it can help you better understand Daryl’s magic a bit better.

Way back when, communication between devices was accomplished using Parallel Data Ports. As the electronics became more sophisticated, Parallel gave way to Serial Data Communications. Twenty years ago the standard was still RS232 UART. Originally released in January of 1996 as USB 1.0, the USB communication standard has evolved to the current (as of 1-2018) USB 3.1. The different versions host unique baud rates as well as protocol rules. USB is a technology governed by The USB Implementers Forum, Inc. (USB-IF;

Some of the benefits of USB include cross-platform compatibility. Since the rules are governed by a single organization, these rules apply whether you use Windows, Linux, or a Mac Operating Systems. USB can provide power to the target device ranging from 100 mA (v1.0) upwards of 900 mA (v3.1). From the many versions of USB, communication speeds can be chosen ranging from slow (1.5 Mpbs) to SuperSpeedPlus (10 Gbps). PIC 8-Bit MCUs can support USB 1.0 and 2.0, which is ample for most applications that would use an 8-bit processor.

There are 16 Defined Classes for USB. The single most versatile Class is Human Interface Device (HID). Although HIDs typically include keyboards, mouses, pointing devices, and game controllers, the Class is versatile enough to be used for practically anything.

The first hurdle in developing a USB project is getting your PIC to talk to your PC. The handshake process identifies your PIC to the PC, and tells the PC about your PIC Device. On the PC side, Enumeration (the handshake) consists of:
1 - Learn about the PIC
2 - Assign a USB driver
3 - Assign an address to the Device (PIC)
4 - Read Device (PIC) Descriptors
5 - Load the assigned USB driver
6 - Set power requirement configurations

The PC will send Control Transfers containing standard USB requests. Specifically, the Enumeration sequence involves:
1 - Suspend
2 - Reset
3 - High Speed Detection Handshake
4 - Get Descriptor
5 - Reset
6 - High Speed Detection Handshake
7 - Set Address
8 - Get Device (PIC) Descriptor
9 - Get Device Configuration
10 - Get String lang IDs
11 - Get String Product ID
12 - Get Device Descriptor
13 - Get Device Configuration
14 - Get Device Configuration
15 - Set Configuration

All of these requirements must be met, as specified by USB-IF, or you will never connect (Enumerate). If you get any of the requirements wrong, you simply cannot connect. Unlike writing PIC PBP code, there is no ‘compiler’ offering clues as to why. You simply cannot connect!


To Enumerate, your PIC must be able to identify itself to the PC. All USB Enumerations will require critical information. Here is a break-down of the essentials, as per Daryl’s USB_Demo:


In order to communicate via USB, your device is required to have a valid USB-IF issued Vendor ID and Product ID. In USBDemo.pbp, the Vendor ID used was 6017, while the Product ID was 2000.

DEFINE USB_VERSION     1 	‘(0x0100)

This indicates the target device (PIC) wants to communicate under USB 1.0 requirements.


“Pedja089” becomes an ASCii String that is passed to the PC to identify the Vendor Name.


“USB Template” becomes an ASCii String that is passed to the PC to identify the Product Name.

DEFINE USB_SERIAL      “00001”

The Serial Number is an optional identification for the individual target being Enumerated. This could be a Device Release Number (or Version Number).

DEFINE USB_INSIZE      64    ;  IN report is PIC to PC (8,16,32,64)
DEFINE USB_OUTSIZE     64    ; OUT report is PC to PIC

The Input and Output Buffer sizes must be defined. Options are 8, 16, 32, and 64. These need to be spelled out for the PC.

DEFINE USB_POLLIN      10   ; Polling times in mS, MIN=1 MAX=10

Since the PIC (target device) cannot initiate a data transfer, only respond to requests, you can stipulate how often the PC requests the data you wish to send. For USB 1.0, the maximum time span per poll is 10 ms. Later versions allow longer and shorter intervals.

Probably as part of an Include file, the PC will also need to know the USB Class your device wishes to communicate under. The HID Class is a recommended versatile Class. There are specialty sub-Classes you could opt to use. These sub-Classes allow for certain short-cuts in the data packets that speed things up. Some of the obvious would be keyboards, gaming controllers, etc.

As illustrated below, Vendor, Product, and Device Descriptor values are Strings and must be spelled out in your Enumeration process. Here is the Device Descriptor String:

USBBufferSizeTX     CON 8       ' input 
USBBufferSizeRX     CON 8       ' output

USBBufferCount      VAR BYTE    '
USBBufferIn         VAR BYTE[8] ' store incoming USB data
USBBufferOut        VAR BYTE[8] ' store outgoing USB data       
DataToSend          VAR BYTE[8] ' store ADCs & pushButton data to send to USB
String1             VAR BYTE[8] ' hold 'USB DEMO' string       
        string1[3]=" "

In addition to the data contained in the String(s), a special byte of data must precede the Strings to indicate the length of the subsequent String. “USB DEMO” is 8 Characters (or Bytes) long. The Packet that transmits this Device Descriptor (along with other pertinent data) is as follows (first column is the decimal Offset):

 0	bLength			1 Byte		Descriptor size in bytes
1 bDescriptorType 1 Byte The constant DEVICE
2 bcdUSB 2 Bytes USB Specification Release No. (BCD)
4 bDeviceClass 1 Byte Class Code (use 0xFF for HID here)
5 bDeviceSubclass 1 Byte Subclass Code (if applicable, else 0x00)
6 bDeviceProtocol 1 Byte Device Protocol
7 bMaxPacketSize0 1 Byte Maximum Packet Size for Endpoint0
8 idVendor 2 Bytes Vendor ID Number (USB-IF Issued)
10 idProduct 2 Bytes Product ID (0-65,535, Vendor Assigned)
12 bcdDevice 2 Bytes Device Release Number
14 iManufacturer 1 Byte Index/string descriptor, Manufacturer
15 iProduct 1 Byte Index/string descriptor, Product
16 iSerialNumber 1 Byte Index/string descriptor, Ser No.
17 bNumConfigurations 1 Byte Number of Possible Configurations

As you can see, the transmission of data must be packaged into very specifically defined packets. The above illustrates the Device Descriptor Packet. Once the PC knows who you are (your PIC device actually), an Interface Descriptor must then be spelled out for the PC. Here is the Packet (all Fields are 1 Byte in length):

 0	bLength			Descriptor size in bytes
 1	bDescriptorType		The constant Interface
 2	bInterfaceNumber	Number identifying this Interface
 3	bAlternateSetting	A number that identifies a descriptor with alternate settings for this bInterfaceNumber
 4	bNumEndpoints		#Endpoints supported, not counting Endpoint0
 5	bInterfaceClass		Class Code (HID = 0x03)
 6	bInterfaceSubclass	Subclass Code
 7	bInterfaceProtocol	Protocol Code
 8	bInterface		Index of string descriptor for Interface

In addition, each used Endpoint requires a Descriptor:

 0	bLength			1 Byte		Descriptor Size in Bytes
 1	bDescriptorType	        1 Byte		Constant Endpoint
 2	bEndpointAddress	1 Byte		Endpoint Number & Direction
 3	bmAttributes		1 Byte		Transfer Type & Supplementary Info
 4	wMaxPacketSize		2 Bytes	        Maximum Packet Size supported
 6	bInterval		1 Byte		Service Interval or NAK Rate

When sending Strings, the Packet is formatted like:

 0	bLength			1 Byte		Descriptor Size in Bytes
 1	bDescriptorType		1 Byte		The Constant String
 2	bSTRING (wLANGID)	String Length.  ASCii/UTF-16LE String

As you can see, the formatting is articulated for you. On one hand, you do not have the “freedom” to create your own protocol. On the other hand, it can be simpler because there is no ambiguity as to how things should be done. The above examples are used to illustrate the protocol defined by USB-IF. To better understand what you must do to use these templates to accomplish your goals, visit

As an option, there are companies like FTDI that offer USB-to-Serial adaptors that allow you to write PIC code using UART SFRs and still communicate with your PC. If USB seems overwhelming to you, consider this as a viable option.

An additional factor when considering USB communications is the PC side programming. Many of us are proficient (at varying levels) at generating PBP3 code to control a PIC MCU, but have never touched the PC side of programming. Outlined below are some considerations and options for you.

PIC Options

The Daryl Taylor (and other contributors) USB files are getting “long in the tooth” (old) and outdated. One of the options open to you is to attempt to use Daryl’s original code, modify it, and make it work for you. This author (mpgmike) has successfully loaded and duplicated Daryl’s USBDemo. However, modifying it was beyond my abilities at the time (a few years ago).

If you REALLY want to master this USB thing, you need “USB Complete, Fifth Edition”, by Jan Axleson ((c) 2015, Lakeview Research, LLC, Jan Axleson; ISBN 978-1-931448-28-4). You may also need a few Microchip tools like:

  • The appropriate PIC Processor Data Sheet (Mandatory)
  • Microchip AN1144; USB Human Interface Device Class on an Embedded Host
  • Microchip AN1140; USB Embedded Host Stack
  • Microchip DS40001356C; Low Pin Count USB Development Kit User’s Guide
  • Microchip AN1233; USB Printer Class on an Embedded Host
  • Microchip AN1212; Using USB Keyboard with an Embedded Host
  • Microchip AN1189; Implementing a Mass Storage Device Using the Microchip USB Device Firmware Framework
  • Microchip AN1145; Using a USB Flash Drive with an Embedded Host
  • Microchip AN1143; Generic Client Driver for a USB Embedded Host
  • Microchip AN1142; USB Mass Storage Class on an Embedded Host
  • Microchip AN1141; USB Embedded Host Stack Programmer’s Guide
  • Microchip AN956; Migrating Applications to USB from RS-232 UART with Minimal Impact on PC Software
  • Microchip AN258; Low Cost USB Microcontroller Programmer The building of the PICkitTM 1 FLASH Starter Kit
  • Microchip AN26.21; USB Device Design Checklist

If you spend the time with at least some of these documents, odds are you might become USB fluent. However, in this author’s opinion, there is a much simpler way…

HIDmaker Software

I spent approximately 4 years reading about USB, purchased the Microchip DM164127-2 Low Pin Count USB Development Kit, read through the above mentioned Microchip documents, purchased Jan Axelson’s “USB Complete, Fifth Edition” and did more reading & breadboarding……. Finally I splurged and bought Dr. Bob’s HIDmaker Software ( Within 2 weeks I had my PCB board, sporting a PIC18F25K50, talking to my PC! Most of that 2 weeks was spent reading the generous wealth of documentation provided as part of the HIDmaker package; and practicing. As USB goes, those 4 years of reading & researching apparently weren’t enough.

What HIDmaker Software generates is skeletal code for the PIC, and a skeletal app for the PC. Both sides are blessed with ample comments to walk you through the process of adding your functional code; what code to add, where to add it, and other remarks to achieve your goals. (The Visual Studio software has both the Form part and the Code part. It is the Code portion that is amply commented by HIDmaker.) Simply put, HIDmaker generates the code that creates a portal for data; data variables you define. You define the Name, the Size, the type of variable, and the USB Address Code for that Variable (explained in the documentation). This becomes the vehicle to transport the Variable Values from the PIC to the PC and/or back again.

PC Options

Having an effective PIC powered device capable of USB communication does no good unless there is a PC side application capable of talking to it. Daryl’s PC apps were written in classic Visual Basic v6. The software needed to create apps with VB6 no longer works on modern Operating Systems; in fact, I had to use Windows 98! The resultant app may work with newer OS’s though.

If you are using Windows XP or newer, you’ll need a newer version of Visual Basic, which is now part of the Visual Studio Suite. Older versions like VS 2010 can be bought inexpensively. The current version is Visual Studio 2017. This author uses VS 2015. Microsoft offers free versions with limited abilities. This would be a good starting place. If PC programming is new to you (as it was to me up until just a few months ago), a couple of books might be in order to learn how to create useful apps. Here are a couple I would recommend:

  • “Visual Basic in easy steps”, by Mike McGrath ((c) 2016, In Easy Steps Limited, ISBN: 978-1-84078-701-6). I recommend this book to get your feet wet. It helps you get you started quickly. It sticks with the basics, so as you grasp the concepts, other books can fill in blanks more easily. (192 pages)
  • “Visual Basic 2015 in 24 Hours”, by James Foxall ((c) 2016, Pearson Education, Inc., ISBN-13: 978-0-672-33745-1, ISBN-10: 0-672-33745-2). Having studied several books on Visual Basic, this one added important details that helped me understand concepts better than did other books. With 588 pages, it has a wealth of information.
  • “Murach’s Visual Basic 2015”, by Anne Boehm ((c) 2016, Mike Murach & Associates, Inc., ISBN: 978-1-890774-98-1). This was the 2nd book I bought, the first being geared for advanced programmers (and not on this list). I spent about 3 months using this as my only resource. I got frustrated with my inability to do certain things and bought several more books (2 listed above). After studying concepts in other books, I found Murach’s book had the answers all along. I just didn’t know enough about VB to understand and implement them. With a functioning background in VB, this is now my primary resource. (904 pages)

The recommended books are based on the version of Visual Studio I use, which is 2015. The same authors & publishers offer similar material geared for other versions (2010, 2013, 2017, etc). There are many more books available. Read the publisher’s description, and when possible, read the reviews before buying. I’m confident these 3 will get most anybody fairly functional in PC programming quickly. Of course, you could create apps with Delphi or Mac’s X.

Other USB Considerations

Unlike older communications protocol, USB is governed by an independent entity with ultimate authority over the matter. If you recall, there is a Vendor ID required before your PC will talk to your PIC. If you are experimenting, you could use practically any number as a Vendor ID. HOWEVER, if you produce a product that incorporates USB, you WILL be REQUIRED to purchase your own unique Vendor ID from USB-IF ( A single purchase gets you the Vendor ID and 65,535 Product IDs. The price (last time I checked) is $5000 USD. Another option is to become a member for $4000 USD, which requires annual renewal (at $4000 USD).

USB requires a unique connector. Unlike a DB-9, it is harder to plug a USB connector into a bread board. Bench testing can have an added complexity.

Due to some of the higher baud rates, the length of connector cable is limited; in fact, the USB specifications actually dictate the maximum length of cable you can specify and use based on the version of USB you are using (5 meters for USB 2.0, 2 meters for 3.1).

Final Thoughts

USB is going to be around for many years to come, in one form or another. If you just want to get a single project communicating with your PC, consider one of the USB-to-Serial adaptors, like the FTDI offerings. In lieu of developing a PC app you could use HyperTerminal or ZTerm. If you want to add USB to your programming tool box, be prepared to commit to the steep learning curve. It took me 2 years to get functional. One individual reportedly grasped it in a mere 10 days. Statistical average is 6 months of relatively intense study.

In addition to conquering USB, PC apps will be needed to sort through the data, display values, and actuate events on the PIC side. This has its own learning curve. Considering the trends, I felt it worthwhile to invest the time and money to add USB to my arsenal of development tools. For now, you can get a taste with Daryl’s USB Demo.

Page last modified on March 14, 2018, at 11:36 PM