860.255.8324

P.O. Box 156
Terryville, CT 06786-0156

Easy USB HID example for the PIC18F14K50 Breakout Board in Mikroelektronika’s mikroC

In this article we’re going to explore creating a simple sample for getting the PIC18F14K50 USB Breakout Board up and running as a USB HID device. Unlike last time, we’ll be using MikroElektronika’s mikroC PRO for PIC (version 4.60.0.0). In this example we won’t be using Microchip’s USB HID Bootloader, but rather programming the board directly with a programmer.  I’ll be using the PICkit 3.

I like mikroC for a few reasons. The IDE itself is a pleasure to use, and I find many of the included libraries to be extremely helpful and very usable. Comparing this to other C compilers, I believe most people who are just getting started with microcontrollers and or C will find this compiler one of the easiest to use.

In this example, we’re using the USB library which will allow us to get our sample running in a very minimum number of lines of code which are also extremely easy to read. There are a few details along the way specific to the PIC18F14K50 so be sure to pay close attention.


Project files and code for this tutorial can be found on github: Click here

Our first step is to prepare our project.

Click “File” then “New” then “New Project…” This will display the New Project Wizard.

Click “Next

Select the appropriate device. In this case, seeing we’re using the Tautic Electronics PIC18F14K50 USB Breakout Board, we’ll select PIC18F14K50. Then, click “Next

For “Device Clock” enter 48 for the MHz. This is the speed at which the internal clock will be running – more on this later. Click “Next

Choose a location for your project directory, and click “Next

You might get a popup if your project folder doesn’t exist yet – click “Yes” if you’d like the folder created

Step 4/6 allows us to add any pre-existing files to the project. We don’t have any, so simply click “Next

Step 5/6 allows us to choose whether we want to include all available libraries in the project. I typically choose to “Include None” and select them later – we’ll talk more about this in a bit. Click “Next

In Step 6/6 you definitely want to check off the “Open Edit Project window…” checkbox. This will allow us to set the configuration bits for the device.  Click “Next

Edit Project Settings

There are a few changes we need to make to the “Edit Project” screen in order to allow the code to operate on our board.  This screen in particular sets the configuration bits for the device. If at the end of this article you’re having trouble getting your board to function – the most likely place to start looking for errors is here. If you miss this step, you can always access project settings by going to “Edit” and then “Edit Project Settings“.

 

Here are our changes:

  1. Make sure that Oscillator is set to “HS”
  2. 4 X PLL Enable bit should be set to “Oscillator Multiplied by 4” – This one is critical. Our board has a 12 MHz crystal, but we want the PIC to run at 48 MHz for compatibility with USB. This setting allows the PIC to run at this higher speed by using an internal PLL.
  3. Make sure that MCU Name is set to “PIC18F14K50”
  4. Make sure that Oscillator Frequency [MHz] is set to “48.000000”
  5. Click “OK

One last step before we start coding – on a previous screen we had chosen not to include all libraries. Now we’ll go in and select the library we need for this project.  On the right side of the IDE, you’ll see a tab called “Library Manager” – hover over this, and the list of available libraries should display.  Scroll all the way to the bottom, and check the USB library.

Now it’s time to get started with the code. We will be using a modified version of MikroElektronika’s USB Library demo – with a few tweaks to make it operational on the PIC18F14K50.

Our code will be in two parts (or files in this case). We’ll have our main code file, in my project I call it USBHIDExample.c, and we’ll also have a file called USBdsc.c which is the code for our USB Descriptor. In short, every USB device needs to be able to identify itself, and its function or utility to the host on initialization. Our descriptor file contains the details which the library will use to send back to the host. In this case we’re creating an HID device, so the code will define this. USB Descriptor files can get fairly complicated – fortunately for HID device code, mikroC includes a utility called the “HID Terminal” which not only lets us test out our device (we’ll use this at the end of this article just for that), but also has a code generation capability geared towards creating a USB descriptor file for HID devices. So let’s create that file now.

Open the “HID Terminal” tool by clicking “Tools” and then “HID Terminal

Click on the “Descriptor” tab, and enter the values shown in the screenshot. In summary, VID and PID are used to set the Vendor ID and Product ID for the USB device, which can be used later in code on your host to identify your device. Report Length specifies the number of bytes sent or received in a data transfer to or from your USB device. Vendor Name and Product Name are both strings that could be displayed on your host and further describe your device to the user.

Make sure “mikroC” is selected, click “Save descriptor”, navigate to your project’s root folder and save the descriptor file as USBdsc.c You can close the HID Terminal for now.

It is important to note that USB devices are licensed, and require a valid VID and PID in order to be sold. Each manufacturer must register for a Vendor ID, and then use Product ID’s under that Vendor ID. For our own testing however, we can use these “made up” values –just don’t plan to sell your new device using these! In the past, Microchip has offered the ability for users to register to use their VID with a specific Product ID for a limited number of devices, provided you’re using a Microchip Micro in your device. This could be a very cost effective option if you’re not looking to sell a bunch of devices. The last time I checked, this gave you permission to distribute up to 1000 devices with that Product ID.  Check out Microchip’s web site for more details if you plan on using USB in a sellable design.

Now that we’ve generated the descriptor file, we need to add it to our project so that it is compiled. Click on the Project Manager tab on the right side of the IDE, then right click “Sources” and click “Add file to project…” navigate to the new USBdsc.c file and click “Open”.

Code

Okay now back to the fun stuff, coding!

At the top of the file, in my case called “USBHIDExample.c” we’ll start by defining a few unsigned char variables which will act as our read and write buffers.  These are unique in that we will be specifying where the compiler should place these in the PIC’s RAM by specifying an address with the absolute directive. The locations below are specific to the PIC18F14K50, and I find they work for this example.

You can see we’ve specified an address of 0×280 for the read buffer, and 0x2C0 for the write buffer. We’ve also defined a char variable called cnt – we’ll use this later.

 

Now, seeing we’ll be using an interrupt for USB servicing, we’ll need to include this in our code as follows:

This interrupt will fire periodically and execute the library function for USB servicing.  This is critical, without it, your USB device will not function. Among several operations one of the most critical that are handled here are somewhat of a watchdog or keepalive type function that periodically contacts the host to keep the connection in place – otherwise your host would report your device as disconnected.

Now we’re ready for the main function.

One important takeaway from that portion of code is how we are looping through our 64 byte buffer, and then when we write our buffer to USB through HID_Write, note that we must send the entire 64 bytes, even if we’re only using a portion of them.  This goes back to our descriptor where we specified the “Report Length” – our communication packets must always match this length.

So in total, our USBHIDExample.c file should now look like this:

That’s just 18 lines of code to get a simple example running, not bad at all!

Now that the code is done, it’s time to compile. Press CTRL+F9 or go to “Build” and click “Build”. You should see the compile process in the Messages window at the bottom of the screen, and hopefully the last message will start with “Finished successfully”. If there are any errors, go back and double check your code.  Common mistakes are to forget to check off the USB library in the Library Manager, or to forget to include the USBdsc.c file in your project. Either will produce several errors.

It’s time to program the firmware into your PIC18F14K50 USB Breakout Board.  I’m using a PICkit 3 to do this. It’s just a matter of going to MPLAB and importing the .hex file, or using the standalone PICkit 3 Programmer application.  Be sure if using MPLAB that you leave the setting to use configuration bits from code.

Once programmed, disconnect your programmer form the breakout board.  Now, make sure the power jumper is set to BUS, and disconnect any external power you may have been using. We’ll be using bus power for this example.

Now that the board has been programmed, we’re ready to test.  Plug the board into your host PC via a USB cable. You’ll likely see a short delay while windows tries to find a driver for a generic HID device – once that is complete, your device should be connected. If there are any issues, you may see a popup regarding an unrecognized device. This is a pretty generic error but I find it is typically related to configuration bits not being set correctly which results in the board not being able to communicate with the host.

Now to test functionality.  Back in the mikroC IDE, go to “Tools” and click on “HID Terminal”. Click on the “Terminal” tab. You should see your device listed in the HID Devices list, if you used the same product name as in the example above, it will show up as HID Test. To test, simply enter some text into the Communication’s section text box, and click “Send”. Your message will be sent to the breakout board, and you should see the message echoed in the bottom text box.  If you change the format to HEX or DEC, you’ll see your message (in the corresponding format) as well as trailing filler data (either 0×00 or 0 depending on format).

Congratulations, you just finished your first USB device program with the PIC18F14K50 USB Breakout Board, and mikroC!

While this tutorial was pretty detailed and of significant length, now that you’ve gone through the process you can see the actual code required to get everything working is pretty minimal.  From here you can add your own functions to start creating your own custom USB enabled device.  It would be pretty simple to take this as a starting point, and create a USB device which communicates with an external peripheral over I2C – such as an accelerometer – and returns the data to the host PC. We’ll leave that for another post.

Project files and code for this tutorial can be found on github: Click here

Feedback is always welcome – if you enjoyed this tutorial, or have ideas for improvement or for another tutorial please feel free to leave a comment here or in our Forums.  Thanks for reading!

 

 

Jayson
View all posts by Jayson
Jayson's website
Post Tagged with , ,
  • Sameera

    This is a very nice tutorial for beginners like me. I have read many tutorials regarding the USB HID with PIC. But most of them are difficult to understand and its a pain.

    Your tutorial is easy to understand. I am going to make a C# application which can communicate with PIC. In PIC side it is storing all the data in external EEPROM which received through USB interface and send data stored in EEPROM to PC.

    I’ll develop this with a help of your tutorial and send status for you. If you have anything related to this please send me for reference.

    Thank you,
    Sameera

    • Jayson

      Thank you for the feedback. I had been looking as well for a good tutorial, and while there are some nice examples there weren’t any that went over all steps in detail. I wanted to make sure to not leave anything out, I think I accomplished that.

      There is a lot of good information on interfacing with USB HID devices, I plan to write a blog on this in the near future as it’s the next logical step. I plan to have my demo include a custom base HID library to make this simple to implement. Until I have that, you can experiment by including the “HID class.dll” file in Microchip’s custom HID device samples available in the Microchip Application Library download at http://www.microchip.com/mal

  • jayagk

    The demo has a code size limit of 2k how can I compile your code?

    • Jayson

      Yeah that’s the one down side of MikroC, the demo compiler pretty much excludes USB development. This demo is intended for those who have a registered version of MikroC.

  • http://www.microchip.com/mal Titus

    hello sir
    i was struggling in USB HID programming PIC18F2550. i was selected 48MHz freq in project settings and i chosen 8Mhz crystal in hardware ckt…i got compiled and got hex file but if i connect with PC means ,then it was not detecting and nothing so plz do the needful as soon as possible

    • Jayson

      Have you verified the rest of your schematic? Also check your USB plug, any shorts will cause the device not to show.

      What oscillator type have you selected for the project settings? This could have an impact as well.

  • http://www.iu.edu Randy Young

    The download link for your project is broken, please advise…

    • Jayson

      Hi Randy,

      Thanks for pointing that out! You can now find the source for this project over on github: Source Code

      I’ll update the reference in the post as well.

      Best Regards,

      Jayson

  • Mike

    Hi Sir,
    i have pic18f2455(usb) and my clock is 30 mhz.
    i have configured my pic according to your tutorial.
    but when i connect my my pic to my pc i get “unrecognized device”.
    could you please help me.

    Best Regards,
    Mike

    • http://www.tautic.com Jayson

      What speed crystal are you using?

    • http://www.tautic.com Jayson

      You need to make sure your clock is operating at the correct rate for USB, if you’re running a different base clock, you’ll have to change your settings to match.

  • John R

    Thanks for the tut! I purchased one of your boards a while ago and have finally got around to starting on this project – I’m also a MikroC user so this is perfect.

  • homermike

    this is a great tutorial and very easy to understand…

    i have question, if it is possible that the PIC18F14K50 can be interfaced with an existing HID device, not to a computer… i mean we will create a device that can communicate to a HID device…

    currently i have a weather monitoring system that can be connected to a computer and has a software that we can read the data from the device.. temp, wind speed, wind direction and etc… now this device is an HID device as detected by the computer… now i would like to interface this system to a PIC with GSM… first i would read the data from the weather device then send the data via SMS using the GSM module… well GSM module interfacing has no problem with me at all since i already tried doing it successfully… the only thing we need is to get data from a HID device…

    thanks and more power….

    • http://www.tautic.com Jayson

      I haven’t seen any code examples of the 14k50 acting as a USB Host, you’d likely need to use another chip from the series.

  • Fernando

    Hi!
    I want to make a USB HID host application to communicate with a pic18f4550.
    So i need an example written in visual c++ 6.
    Any one can help me?

    Best Regards
    fernando

  • Botanic

    Hi All!
    I try this example and have a some trouble: device connecton to PC is Ok! But it sends me echoed message only once! On the second time I push ‘send’ button its nothing echoes. And on the third time i push it – HID terminal stops to request :( What’s wrong?

    • http://www.tautic.com Jayson

      It could be a few things, but the first I’d check is to make sure that your code is always sending the same number of bytes as you have specified in the descriptor. Sending fewer (or more) bytes could cause a similar lock up.

  • Øyvind

    Thanks for the tip on using the mikroC USB library. I’ve wanted to try out USB on the 18F14K50 for quite some time, but I’ve always gotten too hung up in unnecessary details. After reading your post I got the USB functionality to work in no time!

    • http://www.tautic.com Jayson

      Excellent, glad you found it helpful!

  • Botanic

    Thanks, Jayson!! I check the code and found wrong read&writebuffer adresses! Now i fixed this – works fine! I think i incorrect read the datasheet…
    sorry for my english ;)

  • tarakan

    What board did you use?

    • Anonymous

      I used one of my USB Development boards which has a PIC18F14K50.  Very similar to this one: http://store.tautic.com/breakout-boards/pic18f14k50-pth-dev-board.html

  • Rebhi

    On the right side of the mikroC PRO, in the “Library Manager”  there is no USB library or HID library in the list of available libraries. How can i add it.?

    • Anonymous

      I had this as a default option when I installed MikroC, if it’s not showing up I’d suggest contacting MikroElektronica’s support department – there may be a configuration issue with your installation.

  • http://lab.buddika.info/ Buddika

    Thanks a lot for your great tutorial.I was able to make USB work on PIC18F2550 as on this :D with proper USB RAM values from the datasheet :)

    • Genusepurpose2012

      I am using PIC18F2550 and the changes made to the USB RAM location readbuff[64] absolute 0×500; and writebuff[64] absolute 0×540 according to datasheet~ The rest of the code remain the same EXCEPT the ext oscillator clock I have is at 20Mhz~ The pc do not detect the PIC at last.What so you think?

  • Ali

    a message 0 357 main function is not defined main function is not defined is appeared