PIC18F4550 microcontroller has USB module which can work as a HID (Human Interface Device). The USB HID device doesn't need any additional driver because it's already installed in most of modern operating systems.
Using PIC18F4550 as a HID device we can easily transfer data between PC and the microcontroller as shown at the following URL:
PIC18F4550 USB HID Example using CCS PIC C
This topic shows how to build a simple USB HID mouse using PIC18F4550 microcontroller (PIC18F2550 can also be used).
Required Components:
- PIC18F4550 Microcontroller ( or PIC18F2550)
- 8MHz Crystal Oscillator
- 2 x 22pF capacitors
- 470nF Capacitor
- 6 Push-Buttons
- USB Connector
- +5V Power Supply (USB VCC can be used)
- Protoboard
- Jumper Wires
USB Mouse using PIC18F4550 CCS C code:
The CCS PIC C compiler has USB Mouse driver which allows us to build a USB mouse more easily. The following line is used to add this driver to this project:
#include <usb_desc_mouse.h>
In this project there is no need to receive data from the HID device, we have only to send data to this device using the following line:
usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE);
Where out_data is an array of 4 elements (4 bytes):
Byte 1 corresponds to button status. The left button of the mouse is represented by 0x01 and the right button is represented by 0x03.
Byte 2 and byte 3 correspond to X axis and Y axis directions.
Byte 4 for the mouse wheel which is not used in this project.
The X axis and Y axis bytes are signed int8 which can vary from -127 to 127. The ( - ) sign indicates direction ( for X axis left/right and for Y axis up/down) and the number means number of steps at a time.
The complete C code is as the one below:
USB Mouse using PIC18F4550 video:// PIC18F4550 USB Mouse CCS C code // http://ccspicc.blogspot.com/ // electronnote@gmail.com // Use at your own risk #include <18F4550.h> #fuses HSPLL PLL2 CPUDIV1 USBDIV VREGEN NOMCLR #use delay(clock = 48000000) #include <usb_desc_mouse.h> #include<pic18_usb.h> #include<usb.c> #use fast_io(B) char out_data[4]; void main(){ setup_adc_ports(NO_ANALOGS); // Configure all AN pins as digital output_b(0); // PORTB initial state set_tris_b(0x3F); // Configure RB0 to RB5 as inputs port_b_pullups(TRUE); // Enable PORTB pull-ups usb_init_cs(); // Initialize USB hardware delay_ms(1000); while(TRUE){ usb_task(); if(usb_enumerated()){ // If the device has been enumerated by the PC while(!input(PIN_B0)){ out_data[0] = 0; out_data[1] = 1; out_data[2] = 0; out_data[3] = 0; usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); } while(!input(PIN_B1)){ out_data[0] = 0; out_data[1] = -1; out_data[2] = 0; out_data[3] = 0; usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); } while(!input(PIN_B2)){ out_data[0] = 0; out_data[1] = 0; out_data[2] = 1; out_data[3] = 0; usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); } while(!input(PIN_B3)){ out_data[0] = 0; out_data[1] = 0; out_data[2] = -1; out_data[3] = 0; usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE); } while(!input(PIN_B4)){ out_data[0] = 1; out_data[1] = 0; out_data[2] = 0; out_data[3] = 0; usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); } while(!input(PIN_B5)){ while(!input(PIN_B5)); out_data[0] = 3; out_data[1] = 0; out_data[2] = 0; out_data[3] = 0; usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); } out_data[0] = 0; out_data[1] = 0; out_data[2] = 0; out_data[3] = 0; usb_put_packet(1,out_data,4,USB_DTS_TOGGLE); } } }
This video shows a simple hardware circuit connected to PC where the screen is divided into two parts, the left part is a recorded video of the PC screen and the right side shows the hardware circuit.