Difference between revisions of "PIC32MX: USB Communication with a PC"

From Mech
Jump to navigationJump to search
 
(33 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Original Assignment ==
== 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.
'''Do not erase this section!'''


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.
Your assignment is to set up the PIC32 to send and receive data with a PC using the USB communications device class (USB CDC).


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.
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.


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


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.
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 ==
== Code ==


===C Code===
Summarize briefly what the page is about.
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 '''[[Media:main_USB.c|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 '''[[Media:USB - CDC Device - PIC32.zip|here]]''', as some of the h files are different.


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


===MATLAB Code===
Include a schematic and give any part numbers. A photo of your circuit is OK, but not as a replacement for a schematic.
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
== Code ==
% 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"


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.
Where possible, make it a single piece of well-commented cut-and-pastable code, or at least make each function that way, so others can easily copy it. Most comments should be in the code itself; outside the code (on the wiki) should only be explanatory comments that are too cumbersome to include in the code.

Latest revision as of 16:06, 7 March 2010

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 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.

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

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.

MATLAB Code

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"

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.