PIC32MX: USB Communication with a PC
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"