PIC32MX: USB Communication with a PC

From Mech
Revision as of 21:01, 15 February 2010 by DerekSiegal (talk | contribs) (→‎Code)
Jump to navigationJump to search

Original Assignment

Do not erase this section!

Your assignment is to set up the PIC32 to send and receive data with a PC using the USB communications device class (USB CDC).

This type of communication will allow you to talk to a virtual serial port on a PC, just like using the RS232 cable, except you will communicate with the USB cable that powers your PIC32 and achieve faster communication than you could with the RS232 cable.

Use the example projects in the "Microchip Solutions/USB Device - CDC - Basic Demo" and "Microchip Solutions/USB Device - CDC - Serial Emulator" folders as guides.

Send 1000 bytes of data to your PC from your PIC32 and have your PC echo them back to the PIC32. How long does it take? Does it always take the same amount of time? What if you change to a different (faster or slower) PC?

Overview

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 kbs. However, the program we wrote clocks the USB transfer at an average speed of about 2 mbs, which is about 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 PIC by the PC. 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.

Circuit

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.

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 code follows the model set by the example "Microchip Solutions/USB Device - CDC - Serial Emulator".

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
   end
     
     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
 end
 
 %% 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
         end
     end
 end
 
 
 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"