PIC32MX: USB Communication with a PC

From Mech
Jump to navigationJump to search


In the past, the RS232 cable has been used to communicate with a PC. However, the PIC32 is capable of communication through the USB cable as well. This form of data transfer is preferable for a number of reasons. First, the circuit is much simpler (in our case non-existent). Second, the speed is significantly faster. However, as you will see later on, the code associated with USB can be very complicated.

The average speed of the RS232 tops out at about 100 kb/s. It was found that USB transfer can reach an average speed of about 2 mb/s, which is 20 times as fast.

In order to send and receive 1000 bits through USB, an interface program is required. MATLAB was used in this case. The point of the following code is to sends 1000 bits 100 times. Each time 1000 bits are sent, then are echoed back to the PC by the PIC. It timed how long each transaction took and averaged them out. It also remembers the sequence of bits that were sent and compares them in order to determine if any mistakes were made.


There is no circuit required for USB communication with a PC. The USB cable that powers the PIC is the same that transmits data in and out.


C Code

The C code for USB communication is very extensive. The main file alone is more than 600 lines of code, and incorporates thousands more in include files. Download the main file here. This main file is to be inserted into the project for the CDC device Basic Demo that was automatically installed with MPLAB. This will allow you to easily get the necessary includes. Make sure to add the NU_32 hardware profile to the workspace as well. This code follows the model set by the example "Microchip Solutions/USB Device - CDC - Serial Emulator". Make sure you download the whole project by clicking here, as some of the h files are different.

The send and receive commands are putsUSBUSART() and getsUSBUSART() respectively.


The MATLAB m-file used to test the speed of the USB transfer is below:

 %% This program tests the connection speed of a PC to PIC32 USB connection
 %  Created by:
 %  Chris Semple, Derek Siegal, Leland Gossett
 %  LAB #5, ME 333 - Mechatronics
 %  Version 1.0, February 10, 2010
 %% Prepare the program for execution and open a serial port
 clc                                                                                     % Clearing the workspace
 clear                                                                                   % Clearing the variables
 delete(instrfind);                                                                      % Clearing the Serial Port Object
 s = serial('COM14','BAUD',19200, 'OutputBufferSize', 10^7, 'InputBufferSize', 10^7)     % Create serial object (PORT Dependent, buffer size increased to allow more data i/o)
 fopen(s)                                                                                % Open the serial port for r/w
 disp('initialized');                                                                    % Display start message
 length = 10^4;                                                                          % Size of the vector to be sent
 info = floor(rand(length,1)*10);                                                        % Vector of numbers between 0 and 9
 %% Send and receive the info, storing for post processing
 for x = 1:100;                                  % Repeat test 100 times
   fprintf(s, '%d', info);                     % Print data to USB
   fprintf(s, '\n');                           % Print stop bit to USB (This is so matlab knows it has received last bit)
   tic                                         % Start Stopwatch (for timing purposes)
   temp = fgetl(s);                            % Read in line from USB
   if size(temp) == [0,0]                      % If our line was simply a null bit, then:
       temp = fgetl(s);                        % Read another line
     total(x) = toc;                             % Look at final stopwatch reading
     temp = temp';                               % Transpose Matrix
     variable(x,:) = str2num(temp);              % Convert to type Double from char
     bit_rate(x,1) = length/total(x)*8;          % Calculate the bit rate for this test
 %% Post Process - Calculate the number of errors, print the bit rate and total errors
 disp('finished')                                % Display a finished notification
 error = 0;                                      % Initialize error to 0
 for x = 1:100                                   % For each test performed:
     for jj = 1:length                           % For every byte sent in the test:
         if variable(x,jj) ~= info(jj,1)'        % if the byte received does not equal the byte sent:
             error = error + 1;                  % add one to the total errors
 fprintf('\n\nThe average bit rate was %.3f kbits/s\n' , mean(bit_rate)/10^3)
 fprintf('There were a total of %d errors during the transmission\n\n\n' , error)

The output of the MATLAB code should read:

"The average bit rate was 15330.950 kbits/s There were a total of 0 errors during the transmission"

This bit rate displayed by MATLAB could be different, since the USB does not have a set speed. There should always be 0 errors with a slightly variable data rate.