<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AndrewDai</id>
	<title>Mech - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AndrewDai"/>
	<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php/Special:Contributions/AndrewDai"/>
	<updated>2026-05-16T01:59:28Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms2.png&amp;diff=18409</id>
		<title>File:IFFTwaveforms2.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms2.png&amp;diff=18409"/>
		<updated>2010-05-20T18:30:42Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18408</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18408"/>
		<updated>2010-05-20T18:30:35Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* IFFT Example Plot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code for a FFT are provided in the FFT Code section of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
With the PIC32, an inverse FFT can also be computed.  Inverse FFT is a function that converts a frequency domain signal into a time domain signal. Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  The second half of this page shows how you can create an analog signal, takes the FFT of that signal, and then take the inverse FFT of the result to try and obtain the original waveform back. The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy. &lt;br /&gt;
&lt;br /&gt;
The C code and Matlab code for this program can be downloaded [[Media: IFFTcode2.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
This circuit is very similar to the preview FFT circuit, except that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png|border|700px]]&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode2.zip | here]].  The code is very similar to the code found above.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms2.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18407</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18407"/>
		<updated>2010-05-20T18:30:04Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code for a FFT are provided in the FFT Code section of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
With the PIC32, an inverse FFT can also be computed.  Inverse FFT is a function that converts a frequency domain signal into a time domain signal. Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  The second half of this page shows how you can create an analog signal, takes the FFT of that signal, and then take the inverse FFT of the result to try and obtain the original waveform back. The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy. &lt;br /&gt;
&lt;br /&gt;
The C code and Matlab code for this program can be downloaded [[Media: IFFTcode2.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
This circuit is very similar to the preview FFT circuit, except that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png|border|700px]]&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode2.zip | here]].  The code is very similar to the code found above.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTcode2.zip&amp;diff=18406</id>
		<title>File:IFFTcode2.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTcode2.zip&amp;diff=18406"/>
		<updated>2010-05-20T18:29:50Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18405</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18405"/>
		<updated>2010-05-20T18:29:39Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* IFFT Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code for a FFT are provided in the FFT Code section of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
With the PIC32, an inverse FFT can also be computed.  Inverse FFT is a function that converts a frequency domain signal into a time domain signal. Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  The second half of this page shows how you can create an analog signal, takes the FFT of that signal, and then take the inverse FFT of the result to try and obtain the original waveform back. The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy. &lt;br /&gt;
&lt;br /&gt;
The C code and Matlab code for this program can be downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
This circuit is very similar to the preview FFT circuit, except that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png|border|700px]]&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode2.zip | here]].  The code is very similar to the code found above.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18404</id>
		<title>File:IFFTwaveforms.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18404"/>
		<updated>2010-05-20T18:27:43Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: uploaded a new version of &amp;quot;Image:IFFTwaveforms.png&amp;quot;: Reverted to version as of 18:22, 20 May 2010&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18403</id>
		<title>File:IFFTwaveforms.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18403"/>
		<updated>2010-05-20T18:27:04Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: uploaded a new version of &amp;quot;Image:IFFTwaveforms.png&amp;quot;: Reverted to version as of 18:21, 20 May 2010&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18402</id>
		<title>File:IFFTwaveforms.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18402"/>
		<updated>2010-05-20T18:26:31Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: uploaded a new version of &amp;quot;Image:IFFTwaveforms.png&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18401</id>
		<title>File:IFFTwaveforms.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18401"/>
		<updated>2010-05-20T18:22:25Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: uploaded a new version of &amp;quot;Image:IFFTwaveforms.png&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18400</id>
		<title>File:IFFTwaveforms.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18400"/>
		<updated>2010-05-20T18:21:35Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: uploaded a new version of &amp;quot;Image:IFFTwaveforms.png&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18399</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18399"/>
		<updated>2010-05-20T17:54:39Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* IFFT Example Plot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code for a FFT are provided in the FFT Code section of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
With the PIC32, an inverse FFT can also be computed.  Inverse FFT is a function that converts a frequency domain signal into a time domain signal. Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  The second half of this page shows how you can create an analog signal, takes the FFT of that signal, and then take the inverse FFT of the result to try and obtain the original waveform back. The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy. &lt;br /&gt;
&lt;br /&gt;
The C code and Matlab code for this program can be downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
This circuit is very similar to the preview FFT circuit, except that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png|border|700px]]&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].  The code is very similar to the code found above.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18398</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18398"/>
		<updated>2010-05-20T17:54:23Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* IFFT Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code for a FFT are provided in the FFT Code section of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
With the PIC32, an inverse FFT can also be computed.  Inverse FFT is a function that converts a frequency domain signal into a time domain signal. Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  The second half of this page shows how you can create an analog signal, takes the FFT of that signal, and then take the inverse FFT of the result to try and obtain the original waveform back. The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy. &lt;br /&gt;
&lt;br /&gt;
The C code and Matlab code for this program can be downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
This circuit is very similar to the preview FFT circuit, except that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png|border|700px]]&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].  The code is very similar to the code found above.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18397</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18397"/>
		<updated>2010-05-20T17:53:41Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* IFFT Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code for a FFT are provided in the FFT Code section of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
With the PIC32, an inverse FFT can also be computed.  Inverse FFT is a function that converts a frequency domain signal into a time domain signal. Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  The second half of this page shows how you can create an analog signal, takes the FFT of that signal, and then take the inverse FFT of the result to try and obtain the original waveform back. The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy. &lt;br /&gt;
&lt;br /&gt;
The C code and Matlab code for this program can be downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
This circuit is very similar to the preview FFT circuit, except that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png|border|700px]]&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18396</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18396"/>
		<updated>2010-05-20T17:50:06Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code for a FFT are provided in the FFT Code section of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
With the PIC32, an inverse FFT can also be computed.  Inverse FFT is a function that converts a frequency domain signal into a time domain signal. Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  The second half of this page shows how you can create an analog signal, takes the FFT of that signal, and then take the inverse FFT of the result to try and obtain the original waveform back. The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy. &lt;br /&gt;
&lt;br /&gt;
The C code and Matlab code for this program can be downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18395</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18395"/>
		<updated>2010-05-20T17:46:16Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code are provided at the bottom of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== IFFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
== IFFT Code ==&lt;br /&gt;
&lt;br /&gt;
== IFFT Example Plot ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18394</id>
		<title>PIC32MX: FFT of Analog Input</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_FFT_of_Analog_Input&amp;diff=18394"/>
		<updated>2010-05-20T17:45:32Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
A fast Fourier transform (FFT) is a method to calculate a discrete Fourier transform (DFT).  More information about [http://en.wikipedia.org/wiki/Fast_Fourier_transform FFTs]  and [http://en.wikipedia.org/wiki/Discrete_Fourier_transform DFTs] can be found on wikipedia (linked).&lt;br /&gt;
The following circuit and code allow a user to put a signal into a PIC32, perform an FFT on that signal, output the data to Matlab via RS-232, and view a plot showing the raw signal, the FFT as calculated by the PIC, and the FFT as calculated by Matlab.  Viewing the Matlab calculation is for verification only and can be commented out of the Matlab code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commented C code and Matlab code are provided at the bottom of this page and can be downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== FFT Circuit ==&lt;br /&gt;
&lt;br /&gt;
Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs.  The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V).  For data output, the PIC uses RS-232 communication.  Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*Black RS-232 wire to ground&lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time.  Pin A14 goes high during calculation and goes back low when the calculation is completed.  This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== FFT Code ==&lt;br /&gt;
The following is the source code to be programmed onto the PIC.  If unfamiliar, see [[HelloWorld_PIC32 | here]] for a guide to creating a .hex file with MPLAB and [[Directions_to_Load_Files_to_PIC32_with_HID_Bootloader | here]] for directions to load files to the PIC.  It first establishes inputs, outputs and RS-232 communication.  When prompted with a &#039;p&#039; (as written, it is prompted automatically by Matlab), the PIC computes the FFT then sends the magnitude portion of the single-sided FFT and the raw samples to Matlab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* Sam Bobb,  Daniel Cornew,  Ryan Deeter&lt;br /&gt;
	Fast Fourier Transform (FFT) Example&lt;br /&gt;
	ME 333, Lab 5&lt;br /&gt;
	Feb 2010&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/** INCLUDES ***************************************************/&lt;br /&gt;
#include &amp;quot;HardwareProfile.h&amp;quot;&lt;br /&gt;
#include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;dsplib_dsp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fftc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Constants **************************************************/&lt;br /&gt;
&lt;br /&gt;
#define TRUE 		1&lt;br /&gt;
#define FALSE		0&lt;br /&gt;
&lt;br /&gt;
#define LOOP_TIME_PIN		LATAbits.LATA14&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate &lt;br /&gt;
&lt;br /&gt;
// To modify the number of samples:&lt;br /&gt;
#define fftc fft16c256 //from fftc.h, for N = 256 use fft16c256, for N = 1024 use fft16c1024	&lt;br /&gt;
#define N 256	// Also change the log2N variable below!!&lt;br /&gt;
&lt;br /&gt;
// To modify the sampling frequency&lt;br /&gt;
#define SAMPLE_FREQ 10000&lt;br /&gt;
// Also change the timer interupt setup in initInterruptController!&lt;br /&gt;
&lt;br /&gt;
/** Function Declarations **************************************/&lt;br /&gt;
void initInterruptController();&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk);&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232(void);&lt;br /&gt;
&lt;br /&gt;
void computeFFT(void);  //sets up function to compute FFT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Global Variables *******************************************/&lt;br /&gt;
&lt;br /&gt;
int computeFFTflag = FALSE; //used to indicate that an fft computation has been requested over rs232&lt;br /&gt;
&lt;br /&gt;
int sampleIndex = 0; //keeps track of where we&#039;re putting our ADC reading&lt;br /&gt;
&lt;br /&gt;
/** establish variables for FFT calculation*/&lt;br /&gt;
// -----&lt;br /&gt;
// this has to be changed for different values of N&lt;br /&gt;
int log2N = 8; // log2(256) = 8&lt;br /&gt;
//int log2N = 10; // log2(1024) = 10&lt;br /&gt;
// -----&lt;br /&gt;
&lt;br /&gt;
int16c sampleBuffer[N]; //initialize buffer to collect samples&lt;br /&gt;
int16c calcBuffer[N]; // initialize buffer to hold old samples&lt;br /&gt;
int16c scratch[N];&lt;br /&gt;
int16c dout[N]; //holds computed FFT until transmission&lt;br /&gt;
&lt;br /&gt;
long int singleSidedFFT[N];&lt;br /&gt;
long int freqVector[N];&lt;br /&gt;
&lt;br /&gt;
/** Main Function **********************************************/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int	pbClk;&lt;br /&gt;
	int i;&lt;br /&gt;
		&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
	&lt;br /&gt;
	TRISAbits.TRISA14 = 0;&lt;br /&gt;
		&lt;br /&gt;
	// Allow vector interrupts&lt;br /&gt;
	INTEnableSystemMultiVectoredInt();&lt;br /&gt;
	&lt;br /&gt;
	mInitAllLEDs();&lt;br /&gt;
	&lt;br /&gt;
	initInterruptController();&lt;br /&gt;
	&lt;br /&gt;
	initUART2(pbClk);&lt;br /&gt;
&lt;br /&gt;
	// Configure the proper PB frequency and the number of wait states&lt;br /&gt;
	SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
&lt;br /&gt;
	// -------- Set Up ADC --------&lt;br /&gt;
	// configure and enable the ADC&lt;br /&gt;
	CloseADC10();	// ensure the ADC is off before setting the configuration&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// Turn module on | output in integer | trigger mode auto | enable  autosample&lt;br /&gt;
	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// ADC ref external    | disable offset test    | enable scan mode | perform 2 samples | use one buffer | use MUXA mode&lt;br /&gt;
	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// 				  use ADC internal clock | set sample time&lt;br /&gt;
	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
				// set AN4&lt;br /&gt;
	#define PARAM4	ENABLE_AN4_ANA&lt;br /&gt;
&lt;br /&gt;
	// define setup parameters for OpenADC10&lt;br /&gt;
	// do not assign channels to scan&lt;br /&gt;
	#define PARAM5	SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15&lt;br /&gt;
&lt;br /&gt;
	// use ground as neg ref for A | use AN4 (B4) for input A&lt;br /&gt;
	// configure to sample AN4&lt;br /&gt;
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // configure to sample AN4&lt;br /&gt;
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above&lt;br /&gt;
&lt;br /&gt;
	EnableADC10(); // Enable the ADC&lt;br /&gt;
&lt;br /&gt;
	while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers&lt;br /&gt;
	// ------ DONE SETTING UP ADC ------&lt;br /&gt;
	&lt;br /&gt;
	// zero the freqVector and singleSidedFFT&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = 0;&lt;br /&gt;
		singleSidedFFT[i] = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// generate frequency vector&lt;br /&gt;
	// this is the x-axis of your single sided fft&lt;br /&gt;
	for (i=0; i&amp;lt;N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		freqVector[i] = i*(SAMPLE_FREQ/2)/((N/2) - 1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// wait around until you get an fft command from rs232&lt;br /&gt;
	// then call computeFFT to generate an fft of the last block of samples&lt;br /&gt;
	// then send out rs232.&lt;br /&gt;
	// If you want to use FFT without rs232, you can call computeFFT when ever you want in your program.&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		if (computeFFTflag == TRUE)&lt;br /&gt;
		{&lt;br /&gt;
			computeFFT();&lt;br /&gt;
			sendDataRS232();&lt;br /&gt;
		}			&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	CloseOC1();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} //end main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Interrupt Handlers *****************************************/&lt;br /&gt;
// interrput code for the timer 3&lt;br /&gt;
void __ISR( _TIMER_3_VECTOR, ipl7) T3Interrupt( void)&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	//LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	// When we used the loop time pin to measure the length of this ISR,&lt;br /&gt;
	// we measured 400 ns, so you could sample at over 1 MHz.&lt;br /&gt;
&lt;br /&gt;
	sampleBuffer[sampleIndex].re = ReadADC10(0); // read the ADC into the real part of the samplebuffer&lt;br /&gt;
	sampleBuffer[sampleIndex].im = 0; // the imaginary value is 0.&lt;br /&gt;
	&lt;br /&gt;
	// you could shave a little time off this ISR by just zeroing the .im value once, outside the ISR&lt;br /&gt;
&lt;br /&gt;
	// increment the sampleIndex&lt;br /&gt;
	if (sampleIndex == (N-1))&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sampleIndex++;&lt;br /&gt;
	}	 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	//LOOP_TIME_PIN = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// clear interrupt flag and exit&lt;br /&gt;
	mT3ClearIntFlag();&lt;br /&gt;
} // T3 Interrupt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// UART 2 interrupt handler&lt;br /&gt;
// it is set at priority level 2&lt;br /&gt;
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void)&lt;br /&gt;
{&lt;br /&gt;
	char data;&lt;br /&gt;
&lt;br /&gt;
	// Is this an RX interrupt?&lt;br /&gt;
	if(mU2RXGetIntFlag())&lt;br /&gt;
	{&lt;br /&gt;
		// Clear the RX interrupt Flag&lt;br /&gt;
		mU2RXClearIntFlag();&lt;br /&gt;
	&lt;br /&gt;
		data = ReadUART2();&lt;br /&gt;
		// Echo what we just received.&lt;br /&gt;
		putcUART2(data);&lt;br /&gt;
		&lt;br /&gt;
		switch(data)&lt;br /&gt;
		{&lt;br /&gt;
&lt;br /&gt;
			case &#039;p&#039;: // compute and output the FFT&lt;br /&gt;
				computeFFTflag = TRUE;&lt;br /&gt;
				break;	&lt;br /&gt;
		}			&lt;br /&gt;
 &lt;br /&gt;
		// Toggle LED to indicate UART activity&lt;br /&gt;
		mLED_0_Toggle();&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// We don&#039;t care about TX interrupt&lt;br /&gt;
	if ( mU2TXGetIntFlag() )&lt;br /&gt;
	{&lt;br /&gt;
		mU2TXClearIntFlag();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** Other Functions ********************************************/&lt;br /&gt;
&lt;br /&gt;
void initInterruptController(void)&lt;br /&gt;
{&lt;br /&gt;
	// init Timer3 mode and period (PR3) &lt;br /&gt;
	OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x1F40); // produces 100 ms period&lt;br /&gt;
															// sampling frequency = 10 kHz&lt;br /&gt;
	&lt;br /&gt;
	mT3SetIntPriority( 7); 	// set Timer3 Interrupt Priority&lt;br /&gt;
	mT3ClearIntFlag(); 		// clear interrupt flag&lt;br /&gt;
	mT3IntEnable( 1);		// enable timer3 interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initUART2(int pbClk)&lt;br /&gt;
{&lt;br /&gt;
	 // define setup Configuration 1 for OpenUARTx&lt;br /&gt;
		// Module Enable &lt;br /&gt;
		// Work in IDLE mode &lt;br /&gt;
		// Communication through usual pins &lt;br /&gt;
		// Disable wake-up &lt;br /&gt;
		// Loop back disabled &lt;br /&gt;
		// Input to Capture module from ICx pin &lt;br /&gt;
		// no parity 8 bit &lt;br /&gt;
		// 1 stop bit &lt;br /&gt;
		// IRDA encoder and decoder disabled &lt;br /&gt;
		// CTS and RTS pins are disabled &lt;br /&gt;
		// UxRX idle state is &#039;1&#039; &lt;br /&gt;
		// 16x baud clock - normal speed&lt;br /&gt;
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
	 &lt;br /&gt;
	 // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
		// IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
		// Enable UxRX pin&lt;br /&gt;
		// Enable UxTX pin&lt;br /&gt;
		// Interrupt on transfer of every character to TSR &lt;br /&gt;
		// Interrupt on every char received&lt;br /&gt;
		// Disable 9-bit address detect&lt;br /&gt;
		// Rx Buffer Over run status bit clear&lt;br /&gt;
	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	&lt;br /&gt;
 &lt;br /&gt;
	// Open UART2 with config1 and config2&lt;br /&gt;
	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.&lt;br /&gt;
 		&lt;br /&gt;
	// Configure UART2 RX Interrupt with priority 2&lt;br /&gt;
	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void sendDataRS232()&lt;br /&gt;
{&lt;br /&gt;
	int i;&lt;br /&gt;
	char RS232_Out_Buffer[32]; // max characters per line (line feed and carriage return count)&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;\n\rSTART\n\r&amp;quot;); //print START. MATLAB uses this as a start delimiter&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;ROWS=%d\n\r&amp;quot;, N); //print the number of rows, so matlab can make the correct sized buffer&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
	for(i = 0; i &amp;lt; N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		// output: frequency vector, the calculated fft, raw samples&lt;br /&gt;
		sprintf(RS232_Out_Buffer,&amp;quot;%d %d %d\n\r&amp;quot;,freqVector[i], singleSidedFFT[i], calcBuffer[i].re); &lt;br /&gt;
		putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	sprintf(RS232_Out_Buffer,&amp;quot;END\n\r&amp;quot;); //output end so matlab knows we&#039;re done&lt;br /&gt;
	putsUART2(RS232_Out_Buffer);&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void computeFFT()&lt;br /&gt;
{&lt;br /&gt;
	// when using 256 samples, we measured this function to take about 500 microseconds&lt;br /&gt;
	// (not including the time to send rs232 data)&lt;br /&gt;
	int i;&lt;br /&gt;
	&lt;br /&gt;
	mT3IntEnable(0); //turns off interrupt while computing FFT&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = TRUE;&lt;br /&gt;
	&lt;br /&gt;
	for (i=0; i&amp;lt;N; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (i&amp;lt;sampleIndex)&lt;br /&gt;
		{&lt;br /&gt;
			// old chunk&lt;br /&gt;
			calcBuffer[i+(N-sampleIndex)] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		else // i &amp;gt;= sampleIndex&lt;br /&gt;
		{&lt;br /&gt;
			// new chunk&lt;br /&gt;
			calcBuffer[i-sampleIndex] = sampleBuffer[i];&lt;br /&gt;
		}	&lt;br /&gt;
		&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	// load complex input data into din&lt;br /&gt;
	mips_fft16(dout, calcBuffer, fftc, scratch, log2N);&lt;br /&gt;
	&lt;br /&gt;
	// compute single sided fft&lt;br /&gt;
	for(i = 0; i &amp;lt; N/2; i++)&lt;br /&gt;
	{&lt;br /&gt;
		singleSidedFFT[i] = 2 * ((dout[i].re*dout[i].re) + (dout[i].im*dout[i].im));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	LOOP_TIME_PIN = FALSE;&lt;br /&gt;
	&lt;br /&gt;
	computeFFTflag = FALSE;&lt;br /&gt;
&lt;br /&gt;
	// do something with dout&lt;br /&gt;
	mT3IntEnable(1); //turn interrupt back on&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Matlab code computes its own FFT with the raw samples.  It then plots the input signal, the PIC calculated FFT, and the Matlab calculated FFT, for comparison.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
% fftserial interface v 2&lt;br /&gt;
&lt;br /&gt;
%Sam Bobb, Daniel Cornew, Ryan Deeter&lt;br /&gt;
%ME 333 Lab 5: FFT of Analog Input, Winter 2010&lt;br /&gt;
&lt;br /&gt;
%This code receives the single sided magnitude FFT calculated on the PIC&lt;br /&gt;
%and the raw samples through serial communication.  Matlab calculates its&lt;br /&gt;
%own FFT of the raw samples, then plots the input signal, PIC calculated&lt;br /&gt;
%FFT, and Matlab calculated FFT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 10000;                    % Sampling frequency&lt;br /&gt;
T = 1/Fs;                     % Sample time&lt;br /&gt;
L = 256;                     % Length of signal&lt;br /&gt;
t = (0:L-1)*T;                % Time vector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%for runtimes=1:100      %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
columns = 3;&lt;br /&gt;
&lt;br /&gt;
%check if the serial port already exists&lt;br /&gt;
%if it does, close it, it probably means something bad happened last run&lt;br /&gt;
if exist(&#039;COM&#039;,&#039;var&#039;)&lt;br /&gt;
    disp(&#039;closing old port instance&#039;);&lt;br /&gt;
    fclose(COM)&lt;br /&gt;
    delete(COM)&lt;br /&gt;
    clear COM&lt;br /&gt;
    disp(&#039;port closed&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% open the serial port&lt;br /&gt;
COM = serial(&#039;COM6&#039;);&lt;br /&gt;
set(COM,&#039;BaudRate&#039;,19200);&lt;br /&gt;
fopen(COM)     &lt;br /&gt;
&lt;br /&gt;
disp(&#039;port opened&#039;);&lt;br /&gt;
&lt;br /&gt;
% send the command to print data&lt;br /&gt;
fprintf(COM,&#039;p&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%there&#039;s usually some garbage at the beginning (like the echoed p &lt;br /&gt;
%character command and line  breaks); this reads lines in until we find &lt;br /&gt;
%the start line&lt;br /&gt;
text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
while isempty(strfind(text, &#039;START&#039;))&lt;br /&gt;
    text = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% read number of rows&lt;br /&gt;
rowstext = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
pat = &#039;ROWS=&#039;;&lt;br /&gt;
split = regexp(rowstext, pat, &#039;split&#039;);&lt;br /&gt;
rows = str2double(split(2));&lt;br /&gt;
&lt;br /&gt;
DATA = zeros(rows,columns);&lt;br /&gt;
&lt;br /&gt;
%generate the fscanf format argument&lt;br /&gt;
%repeate the formatchar character for the number of columns&lt;br /&gt;
formatchar = &#039;%d&#039;;&lt;br /&gt;
serialpat = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
%establishing fscanf format&lt;br /&gt;
for j = 1:columns&lt;br /&gt;
    serialpat = [serialpat &#039; &#039; formatchar];&lt;br /&gt;
end&lt;br /&gt;
    &lt;br /&gt;
%reads serial data and puts it into DATA&lt;br /&gt;
for j = 1:rows&lt;br /&gt;
    DATA(j, :) = fscanf(COM, serialpat, [columns 1]);&lt;br /&gt;
    %disp(COM.BytesAvailable)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%reads last line&lt;br /&gt;
last = fscanf(COM, &#039;%s&#039;);&lt;br /&gt;
&lt;br /&gt;
%verifies that last line read is the last line&lt;br /&gt;
if strcmp(last,&#039;END&#039;)&lt;br /&gt;
    disp(&#039;Success&#039;)&lt;br /&gt;
else&lt;br /&gt;
    disp(&#039;Problem&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
%disp(COM.BytesAvailable)       %for debugging&lt;br /&gt;
&lt;br /&gt;
%plotting input signal&lt;br /&gt;
subplot(3, 1, 1)&lt;br /&gt;
plot(DATA(:,3))&lt;br /&gt;
title(&#039;Time Domain Signal&#039;)&lt;br /&gt;
&lt;br /&gt;
%plotting PIC calculated FFT&lt;br /&gt;
subplot(3, 1, 2)&lt;br /&gt;
plot(DATA(:,1), DATA(:,2))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated on the PIC&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
axis([0 Fs/2 0 2e5])&lt;br /&gt;
&lt;br /&gt;
%calculating FFT in Matlab&lt;br /&gt;
NFFT = 2^nextpow2(L); % Next power of 2 from length of y&lt;br /&gt;
Y = fft(DATA(:,3),NFFT)/L;&lt;br /&gt;
&lt;br /&gt;
%Y = DATA(:,1) + DATA(:,2)*1i;&lt;br /&gt;
&lt;br /&gt;
f = Fs/2*linspace(0,1,NFFT/2+1);&lt;br /&gt;
&lt;br /&gt;
% Plot Matlab&#039;s single-sided amplitude spectrum.&lt;br /&gt;
subplot(3, 1, 3)&lt;br /&gt;
plot(f,2*abs(Y(1:NFFT/2+1)))&lt;br /&gt;
title(&#039;Single Sided FFT Calculated with MATLAB&#039;)&lt;br /&gt;
xlabel(&#039;Frequency (Hz)&#039;)&lt;br /&gt;
ylabel(&#039;|Y(f)|&#039;)&lt;br /&gt;
&lt;br /&gt;
%pause(2)        %UNCOMMENT FOR CONTINOUS FFT&lt;br /&gt;
&lt;br /&gt;
%end             %UNCOMMENT FOR CONTINUOUS FFT&lt;br /&gt;
&lt;br /&gt;
%closes serial port&lt;br /&gt;
fclose(COM)&lt;br /&gt;
delete(COM)&lt;br /&gt;
clear COM&lt;br /&gt;
disp(&#039;port closed&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FFT Example Plots==&lt;br /&gt;
Here is an example using a 500 Hz sine wave input.&lt;br /&gt;
[[Image: FFT_500_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example uses a 1 kHz sine wave.&lt;br /&gt;
[[Image: FFT_1K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example is still at 1 kHz, but with a square wave.&lt;br /&gt;
[[Image: FFT_1K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example shows a 2 kHz sine wave.&lt;br /&gt;
[[Image: FFT_2K_sin.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
This example, still at 2 kHz, is a square wave.&lt;br /&gt;
[[Image:  FFT_2K_square.jpg|border|700px]]&lt;br /&gt;
&lt;br /&gt;
The final example is a 3 kHz sine wave.&lt;br /&gt;
[[Image: FFT_3K_sin.jpg|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Microchip_PICs&amp;diff=18393</id>
		<title>Microchip PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Microchip_PICs&amp;diff=18393"/>
		<updated>2010-05-20T17:40:30Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Using the PIC32MX Series */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Note:  Most code on this page was written using the CCS compiler.  Microchip&#039;s MPLAB is also occasionally used.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;[http://peshkin.mech.northwestern.edu/pic/code Link to all sample code here.]&amp;lt;/b&amp;gt;&lt;br /&gt;
*[[Sample code for most PIC18F4520 operations]]&lt;br /&gt;
*[http://www.ccsinfo.com/forum/ CCS user forum]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
== Using the PIC18F4520 ==&lt;br /&gt;
*[[4520 Board intro]]&lt;br /&gt;
*[[4520 Board construction]]&lt;br /&gt;
*[[4520 Board use]]&lt;br /&gt;
*[[Microcontroller PIC18F4520]]&lt;br /&gt;
*[[PIC MCUs: Capabilities of PIC18F4520]]&lt;br /&gt;
**[[PIC18F4520: PWM Motor Control]]&lt;br /&gt;
**[[PIC18F4520: Digital Outputs]]&lt;br /&gt;
**[[PIC18F4520: Digital Inputs]]&lt;br /&gt;
**[[PIC18F4520: Serial Digital-to-Analog Conversion]]&lt;br /&gt;
**[[PIC18F4520: Analog Inputs]]&lt;br /&gt;
**[[PIC18F4520: Timers]]&lt;br /&gt;
**[[PIC18F4520: Comparator]]&lt;br /&gt;
&lt;br /&gt;
== Example Code in C for PIC18F4520==&lt;br /&gt;
*[[C Example: Parallel Interfacing with LCDs]]&lt;br /&gt;
*[[C Example: Digital Inputs]]&lt;br /&gt;
*[[C Example: PWM Motor Control]]&lt;br /&gt;
*[[C Example: Comparators]]&lt;br /&gt;
*[[C Example: Digital Outputs]]&lt;br /&gt;
*[[C Example: Analog Inputs]]&lt;br /&gt;
*[[C Example: Digital Outputs (Ports)]]&lt;br /&gt;
*[[C Example: Bi-Directional PWM Motor Control]]&lt;br /&gt;
*[[C Example: Serial LCD]]&lt;br /&gt;
&lt;br /&gt;
== Using the PIC32MX Series ==&lt;br /&gt;
*[[Introduction to the PIC32]]&lt;br /&gt;
*[[Getting Started with PIC32]] (includes NU32 development board)&lt;br /&gt;
** Download PIC32 Tutorial Files [[Media: PIC32_TutorialFiles.zip|here]].&lt;br /&gt;
** [[ME 333 Lab 2]] - Includes Digital IO, Analog Input, Parallel LCD and RS232 Com&lt;br /&gt;
** [[ME 333 Lab 4]] - Includes PWM and Encoder Motor Control&lt;br /&gt;
*[[Microcontroller PIC32MX460F512L]]&lt;br /&gt;
*[[Programming HID Bootloader on PIC32]] &lt;br /&gt;
*[[HelloWorld PIC32|Directions to code HelloWorld]]&lt;br /&gt;
*[[Directions to Load Files to PIC32 with HID Bootloader]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[PIC MCUs: Capabilities of PIC32MX]]&lt;br /&gt;
**[[Programming HID Bootloader on PIC32 |PIC32MX: Bootloader]]&lt;br /&gt;
**Simple Programs&lt;br /&gt;
***[[PIC32MX: Digital Inputs]]&lt;br /&gt;
***[[PIC32MX: Digital Outputs]]&lt;br /&gt;
***[[PIC32MX: Analog Inputs]]&lt;br /&gt;
**Communication&lt;br /&gt;
***[[PIC32MX: Parallel LCD]]&lt;br /&gt;
***[[PIC32MX: RS232]]&lt;br /&gt;
***[[PIC32MX:  USB Communication with a PC]]&lt;br /&gt;
***[[PIC32MX:  SPI External RAM]]&lt;br /&gt;
***[[PIC32MX:  I2C DAC]]&lt;br /&gt;
***[[PIC32MX:  I2C EEPROM]]&lt;br /&gt;
***[[PIC32MX:  SPI EEPROM]]&lt;br /&gt;
***[[PIC32MX:  I2C Communication between PIC32s]]&lt;br /&gt;
***[[PIC32MX:  SPI Communication between PIC32s]]&lt;br /&gt;
**Motor Control&lt;br /&gt;
***[[PIC32MX: PWM Motor Control|PIC32MX: PWM Motor Control]]&lt;br /&gt;
***[[PIC32MX: Encoder Motor Control|PIC32MX: Encoder Motor Control]]&lt;br /&gt;
***[[PIC32MX: Servo Control|PIC32MX: Servo Control]]&lt;br /&gt;
***[[PIC32MX:  Driving a Stepper Motor]]&lt;br /&gt;
**Capabilities&lt;br /&gt;
***[[PIC32MX:  Benchmarking Mathematical Operations]]&lt;br /&gt;
***[[PIC32MX:  FFT of Analog Input]]&lt;br /&gt;
***[[PIC32MX:  Sinusoidal Analog Output]]&lt;br /&gt;
***[[PIC32MX:  XBee Wireless Round-trip Latency]]&lt;br /&gt;
***[[PIC32MX:  Interfacing with Force Sensors from a Scale]]&lt;br /&gt;
***[[PIC32MX:  Storing Data in Flash Memory (Run-Time Self Programming)]]&lt;br /&gt;
&lt;br /&gt;
==Other PIC Resources ==&lt;br /&gt;
&lt;br /&gt;
*[[PIC PWM Motor Driver]]&lt;br /&gt;
*[[Writing Code with the C18 Compiler]]&lt;br /&gt;
*[[Controlling a seven segment display]]&lt;br /&gt;
*[[PIC Microcontrollers with C18 Compiler]]&lt;br /&gt;
*[[PIC Motor Control and Serial Port Example]]&lt;br /&gt;
*[[PIC16F684]]&lt;br /&gt;
*[[PIC Microcontrollers with CCS Compiler]]&lt;br /&gt;
*[[Stepper motor control with the PIC]]&lt;br /&gt;
*[[PIC/C18 Compiler Tips and Troubleshooting]]&lt;br /&gt;
*[[CCS C]]&lt;br /&gt;
*[[Analog Input]]&lt;br /&gt;
*[[PIC MCUs: Hardware and Connections]]&lt;br /&gt;
*[[Storing constant data in program memory]]&lt;br /&gt;
*[[PIC Analog-Digital-Converter Example]]&lt;br /&gt;
*[[PIC Microcontroller]]&lt;br /&gt;
*[[Digital inputs &amp;amp; outputs]]&lt;br /&gt;
*[[Debugging C on a PIC]]&lt;br /&gt;
*[[Analog Output]]&lt;br /&gt;
*[[PIC MCUs: Software]]&lt;br /&gt;
*[[Interfacing to External EEPROM]]&lt;br /&gt;
*[[CCS IDE]]&lt;br /&gt;
*[[Interrupts]]&lt;br /&gt;
*[[PIC16F684 Registers]]&lt;br /&gt;
*[[Waveform Generation with AD9833]]&lt;br /&gt;
*[[Waveform Generation with AD9833, and SPI]]&lt;br /&gt;
*[[PIC computation time benchmarks]]&lt;br /&gt;
*[[PICkit 1]]&lt;br /&gt;
*[[PIC MCUs: 4520 Board]]&lt;br /&gt;
*[[More debugging tips]]&lt;br /&gt;
*[[Example Writeup: Analog Input]]&lt;br /&gt;
*[[LED Drivers]]&lt;br /&gt;
*[[Embedded Programming Tips for CCS C]]&lt;br /&gt;
*[[Wireless PIC bootloading]]&lt;br /&gt;
*[[PIC 18f4553]]&lt;br /&gt;
*[[I2C Motor Controller]]&lt;br /&gt;
*[[Driving a piezo speaker with a PIC]]&lt;br /&gt;
*[[PIC Servo Controller]]&lt;br /&gt;
*[[Watchdog timer]]&lt;br /&gt;
*[[Interfacing PIC with SPI memory]]&lt;br /&gt;
*[[Using the LS7166 Quadrature Counter]]&lt;br /&gt;
&lt;br /&gt;
==Programming the PIC with Microchip&#039;s MPLAB==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Microchip_PICs&amp;diff=18392</id>
		<title>Microchip PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Microchip_PICs&amp;diff=18392"/>
		<updated>2010-05-20T17:39:58Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Using the PIC32MX Series */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Note:  Most code on this page was written using the CCS compiler.  Microchip&#039;s MPLAB is also occasionally used.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;[http://peshkin.mech.northwestern.edu/pic/code Link to all sample code here.]&amp;lt;/b&amp;gt;&lt;br /&gt;
*[[Sample code for most PIC18F4520 operations]]&lt;br /&gt;
*[http://www.ccsinfo.com/forum/ CCS user forum]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
== Using the PIC18F4520 ==&lt;br /&gt;
*[[4520 Board intro]]&lt;br /&gt;
*[[4520 Board construction]]&lt;br /&gt;
*[[4520 Board use]]&lt;br /&gt;
*[[Microcontroller PIC18F4520]]&lt;br /&gt;
*[[PIC MCUs: Capabilities of PIC18F4520]]&lt;br /&gt;
**[[PIC18F4520: PWM Motor Control]]&lt;br /&gt;
**[[PIC18F4520: Digital Outputs]]&lt;br /&gt;
**[[PIC18F4520: Digital Inputs]]&lt;br /&gt;
**[[PIC18F4520: Serial Digital-to-Analog Conversion]]&lt;br /&gt;
**[[PIC18F4520: Analog Inputs]]&lt;br /&gt;
**[[PIC18F4520: Timers]]&lt;br /&gt;
**[[PIC18F4520: Comparator]]&lt;br /&gt;
&lt;br /&gt;
== Example Code in C for PIC18F4520==&lt;br /&gt;
*[[C Example: Parallel Interfacing with LCDs]]&lt;br /&gt;
*[[C Example: Digital Inputs]]&lt;br /&gt;
*[[C Example: PWM Motor Control]]&lt;br /&gt;
*[[C Example: Comparators]]&lt;br /&gt;
*[[C Example: Digital Outputs]]&lt;br /&gt;
*[[C Example: Analog Inputs]]&lt;br /&gt;
*[[C Example: Digital Outputs (Ports)]]&lt;br /&gt;
*[[C Example: Bi-Directional PWM Motor Control]]&lt;br /&gt;
*[[C Example: Serial LCD]]&lt;br /&gt;
&lt;br /&gt;
== Using the PIC32MX Series ==&lt;br /&gt;
*[[Introduction to the PIC32]]&lt;br /&gt;
*[[Getting Started with PIC32]] (includes NU32 development board)&lt;br /&gt;
** Download PIC32 Tutorial Files [[Media: PIC32_TutorialFiles.zip|here]].&lt;br /&gt;
** [[ME 333 Lab 2]] - Includes Digital IO, Analog Input, Parallel LCD and RS232 Com&lt;br /&gt;
** [[ME 333 Lab 4]] - Includes PWM and Encoder Motor Control&lt;br /&gt;
*[[Microcontroller PIC32MX460F512L]]&lt;br /&gt;
*[[Programming HID Bootloader on PIC32]] &lt;br /&gt;
*[[HelloWorld PIC32|Directions to code HelloWorld]]&lt;br /&gt;
*[[Directions to Load Files to PIC32 with HID Bootloader]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[PIC MCUs: Capabilities of PIC32MX]]&lt;br /&gt;
**[[Programming HID Bootloader on PIC32 |PIC32MX: Bootloader]]&lt;br /&gt;
**Simple Programs&lt;br /&gt;
***[[PIC32MX: Digital Inputs]]&lt;br /&gt;
***[[PIC32MX: Digital Outputs]]&lt;br /&gt;
***[[PIC32MX: Analog Inputs]]&lt;br /&gt;
**Communication&lt;br /&gt;
***[[PIC32MX: Parallel LCD]]&lt;br /&gt;
***[[PIC32MX: RS232]]&lt;br /&gt;
***[[PIC32MX:  USB Communication with a PC]]&lt;br /&gt;
***[[PIC32MX:  SPI External RAM]]&lt;br /&gt;
***[[PIC32MX:  I2C DAC]]&lt;br /&gt;
***[[PIC32MX:  I2C EEPROM]]&lt;br /&gt;
***[[PIC32MX:  SPI EEPROM]]&lt;br /&gt;
***[[PIC32MX:  I2C Communication between PIC32s]]&lt;br /&gt;
***[[PIC32MX:  SPI Communication between PIC32s]]&lt;br /&gt;
**Motor Control&lt;br /&gt;
***[[PIC32MX: PWM Motor Control|PIC32MX: PWM Motor Control]]&lt;br /&gt;
***[[PIC32MX: Encoder Motor Control|PIC32MX: Encoder Motor Control]]&lt;br /&gt;
***[[PIC32MX: Servo Control|PIC32MX: Servo Control]]&lt;br /&gt;
***[[PIC32MX:  Driving a Stepper Motor]]&lt;br /&gt;
**Capabilities&lt;br /&gt;
***[[PIC32MX:  Benchmarking Mathematical Operations]]&lt;br /&gt;
***[[PIC32MX:  FFT and IFFT of Analog Input]]&lt;br /&gt;
***[[PIC32MX:  Sinusoidal Analog Output]]&lt;br /&gt;
***[[PIC32MX:  XBee Wireless Round-trip Latency]]&lt;br /&gt;
***[[PIC32MX:  Interfacing with Force Sensors from a Scale]]&lt;br /&gt;
***[[PIC32MX:  Storing Data in Flash Memory (Run-Time Self Programming)]]&lt;br /&gt;
&lt;br /&gt;
==Other PIC Resources ==&lt;br /&gt;
&lt;br /&gt;
*[[PIC PWM Motor Driver]]&lt;br /&gt;
*[[Writing Code with the C18 Compiler]]&lt;br /&gt;
*[[Controlling a seven segment display]]&lt;br /&gt;
*[[PIC Microcontrollers with C18 Compiler]]&lt;br /&gt;
*[[PIC Motor Control and Serial Port Example]]&lt;br /&gt;
*[[PIC16F684]]&lt;br /&gt;
*[[PIC Microcontrollers with CCS Compiler]]&lt;br /&gt;
*[[Stepper motor control with the PIC]]&lt;br /&gt;
*[[PIC/C18 Compiler Tips and Troubleshooting]]&lt;br /&gt;
*[[CCS C]]&lt;br /&gt;
*[[Analog Input]]&lt;br /&gt;
*[[PIC MCUs: Hardware and Connections]]&lt;br /&gt;
*[[Storing constant data in program memory]]&lt;br /&gt;
*[[PIC Analog-Digital-Converter Example]]&lt;br /&gt;
*[[PIC Microcontroller]]&lt;br /&gt;
*[[Digital inputs &amp;amp; outputs]]&lt;br /&gt;
*[[Debugging C on a PIC]]&lt;br /&gt;
*[[Analog Output]]&lt;br /&gt;
*[[PIC MCUs: Software]]&lt;br /&gt;
*[[Interfacing to External EEPROM]]&lt;br /&gt;
*[[CCS IDE]]&lt;br /&gt;
*[[Interrupts]]&lt;br /&gt;
*[[PIC16F684 Registers]]&lt;br /&gt;
*[[Waveform Generation with AD9833]]&lt;br /&gt;
*[[Waveform Generation with AD9833, and SPI]]&lt;br /&gt;
*[[PIC computation time benchmarks]]&lt;br /&gt;
*[[PICkit 1]]&lt;br /&gt;
*[[PIC MCUs: 4520 Board]]&lt;br /&gt;
*[[More debugging tips]]&lt;br /&gt;
*[[Example Writeup: Analog Input]]&lt;br /&gt;
*[[LED Drivers]]&lt;br /&gt;
*[[Embedded Programming Tips for CCS C]]&lt;br /&gt;
*[[Wireless PIC bootloading]]&lt;br /&gt;
*[[PIC 18f4553]]&lt;br /&gt;
*[[I2C Motor Controller]]&lt;br /&gt;
*[[Driving a piezo speaker with a PIC]]&lt;br /&gt;
*[[PIC Servo Controller]]&lt;br /&gt;
*[[Watchdog timer]]&lt;br /&gt;
*[[Interfacing PIC with SPI memory]]&lt;br /&gt;
*[[Using the LS7166 Quadrature Counter]]&lt;br /&gt;
&lt;br /&gt;
==Programming the PIC with Microchip&#039;s MPLAB==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTcode.zip&amp;diff=18277</id>
		<title>File:IFFTcode.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTcode.zip&amp;diff=18277"/>
		<updated>2010-04-18T18:40:14Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: uploaded a new version of &amp;quot;Image:IFFTcode.zip&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This code is for the PIC32, and contains a C source file and a MATLAB .m file.  The code implements a PWM output, a FFT, and an inverse FFT.&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18276</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18276"/>
		<updated>2010-04-18T18:39:11Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently *configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png|border|700px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].  The code is very similar to the code found in the [[PIC32MX: FFT of Analog Input]] page.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18275</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18275"/>
		<updated>2010-04-18T18:38:39Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently *configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].  The code is very similar to the code found in the [[PIC32MX: FFT of Analog Input]] page.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18274</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18274"/>
		<updated>2010-04-18T18:37:59Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
*Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently *configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
*    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
*    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
*    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
*The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the *calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
*The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].  The code is very similar to the code found in the [[PIC32MX: FFT of Analog Input]] page.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18273</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18273"/>
		<updated>2010-04-18T18:35:08Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Example Plot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].  The code is very similar to the code found in the [[PIC32MX: FFT of Analog Input]] page.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18272</id>
		<title>File:IFFTwaveforms.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTwaveforms.png&amp;diff=18272"/>
		<updated>2010-04-18T18:34:40Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18271</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18271"/>
		<updated>2010-04-18T18:33:37Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found [[Media: IFFTcode.zip | here]].  The code is very similar to the code found in the [[PIC32MX: FFT of Analog Input]] page.  There are two main differences:&lt;br /&gt;
&lt;br /&gt;
1. There is now an &amp;quot;analog output.&amp;quot;  This is basically a PWM that is filtered through a low pass filter.  The pulse widths are modified very quickly, with the width of the pulse directly related to the amplitude of the output.  Thus, a very short pulse is the same as the trough of the sine wave and a long pulse is the same as the peak of the wave.&lt;br /&gt;
&lt;br /&gt;
2. This is more of a tip, but after the analog inputs are stored in the sample array, they are scaled up by a factor, in this case, 256.  All this does is increase the range of the values.  I found this to give results that align much better with MATLAB&#039;s results.  The reason for this is that the mips_fft16 algorithm accepts int16 and int32 data the best.  However, int data types can lose information since they round to the nearest integer.  Thus, we can scale all the inputs to make them larger, thus yielding more accuracy (it is as if we added a few more decimal places).&lt;br /&gt;
&lt;br /&gt;
== Example Plot ==&lt;br /&gt;
&lt;br /&gt;
This waveform is a 30Hz sine wave superimposed on a 40Hz sine wave with the same amplitude and phase.  As one can see, the FFT amplitude line up almost exactly.  You can download the [[Media: IFFTwaveforms.fig | MATLAB fig]] file for further examination.  The phase graph has some discrepancy, but this can be easily fixed by changing the FFT phase vector to float, rather than int16.  It is ok to use int16 here because the vector is not being inputted into the mips_fft algorithm.  And finally, the inverse FFT matches up very nicely with the original signal, very little information is lost.&lt;br /&gt;
&lt;br /&gt;
[[Image: IFFTwaveforms.png|border|700px]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18270</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18270"/>
		<updated>2010-04-18T18:18:13Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found at the bottom of the page or downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png]]&lt;br /&gt;
&lt;br /&gt;
== Example Plot ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFftSchematic.png&amp;diff=18269</id>
		<title>File:IFftSchematic.png</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFftSchematic.png&amp;diff=18269"/>
		<updated>2010-04-18T18:16:47Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: Schematic for the IFFT code.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Schematic for the IFFT code.&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18268</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18268"/>
		<updated>2010-04-18T18:16:07Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found at the bottom of the page or downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:IFftSchematic.png]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18267</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18267"/>
		<updated>2010-04-18T18:15:54Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found at the bottom of the page or downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
Much of this circuit is the same as the one found in the [[PIC32MX: FFT of Analog Input]] page.  Here is a recap:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Beyond simple inputs and outputs, there is no special circuitry required for computing FFTs. The signal is inserted into pin B4 on the PIC and must be below VREF on the PIC (currently configured to 3.3 V). For data output, the PIC uses RS-232 communication. Three connections need to be made with the RS-232:&lt;br /&gt;
&lt;br /&gt;
    * RS-232 Tx to pin F4 on the PIC (orange connection in diagram)&lt;br /&gt;
    * RS-232 Rx to pin F5 on the PIC (yellow connection in diagram)&lt;br /&gt;
    * Black RS-232 wire to ground &lt;br /&gt;
&lt;br /&gt;
The remaining connection is not essential for FFT caclulation but allows the user to monitor the calculation time. Pin A14 goes high during calculation and goes back low when the calculation is completed. This feature lets the calculation time be monitored on an oscilloscope.&lt;br /&gt;
&lt;br /&gt;
The following circuit diagram illustrates the signal generator to PIC connection, the RS-232 connections, and the optional oscilloscope connection.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The only thing different about this circuit is that it includes a low pass filter.  This filter integrates the PWM signal that is output from pin D0 and creates a continuous, analog signal.&lt;br /&gt;
&lt;br /&gt;
[[Image:FftSchematic.png]]&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:IFFTcode.zip&amp;diff=18266</id>
		<title>File:IFFTcode.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:IFFTcode.zip&amp;diff=18266"/>
		<updated>2010-04-18T18:11:45Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: This code is for the PIC32, and contains a C source file and a MATLAB .m file.  The code implements a PWM output, a FFT, and an inverse FFT.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This code is for the PIC32, and contains a C source file and a MATLAB .m file.  The code implements a PWM output, a FFT, and an inverse FFT.&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18265</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18265"/>
		<updated>2010-04-17T20:26:50Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found at the bottom of the page or downloaded [[Media: IFFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18264</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18264"/>
		<updated>2010-04-17T20:26:39Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation or time reversal (depending on the algorithm).  FFT information can be found at [[PIC32MX: FFT of Analog Input]].  The following circuit and code implements a program on the PIC32 that creates an analog signal, takes the FFT of that signal, and then takes the inverse FFT of the result to try and obtain the original waveform back.  The data is all sent to MATLAB via RS232 and compared to MATLAB&#039;s computational results for accuracy.&lt;br /&gt;
&lt;br /&gt;
The code for both MATLAB and the PIC32 can be found at the bottom of the page or downloaded [[Media: Lab5FFTcode.zip | here]].&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18258</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18258"/>
		<updated>2010-04-17T20:20:01Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation.  FFT information can be found at [[PIC32MX: FFT of Analog Input]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18257</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18257"/>
		<updated>2010-04-17T20:19:43Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.  Inverse FFTs actually use the same algorithm as FFTs except with some scaling and conjugation.  FFT information can be found [[PIC32MX: FFT of Analog Input]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18256</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18256"/>
		<updated>2010-04-17T20:08:16Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
An inverse FFT is a function that converts a frequency domain signal into a time domain signal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18255</id>
		<title>PIC32MX: Inverse FFT</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_Inverse_FFT&amp;diff=18255"/>
		<updated>2010-04-17T20:07:24Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: Calculate the inverse FFT of a frequency domain signal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An inverse FFT is a function that converts a frequency domain signal into a time domain signal.&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Microchip_PICs&amp;diff=18254</id>
		<title>Microchip PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Microchip_PICs&amp;diff=18254"/>
		<updated>2010-04-17T20:03:21Z</updated>

		<summary type="html">&lt;p&gt;AndrewDai: /* Using the PIC32MX Series */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Note:  Most code on this page was written using the CCS compiler.  Microchip&#039;s MPLAB is also occasionally used.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;[http://peshkin.mech.northwestern.edu/pic/code Link to all sample code here.]&amp;lt;/b&amp;gt;&lt;br /&gt;
*[[Sample code for most PIC18F4520 operations]]&lt;br /&gt;
*[http://www.ccsinfo.com/forum/ CCS user forum]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
== Using the PIC18F4520 ==&lt;br /&gt;
*[[4520 Board intro]]&lt;br /&gt;
*[[4520 Board construction]]&lt;br /&gt;
*[[4520 Board use]]&lt;br /&gt;
*[[Microcontroller PIC18F4520]]&lt;br /&gt;
*[[PIC MCUs: Capabilities of PIC18F4520]]&lt;br /&gt;
**[[PIC18F4520: PWM Motor Control]]&lt;br /&gt;
**[[PIC18F4520: Digital Outputs]]&lt;br /&gt;
**[[PIC18F4520: Digital Inputs]]&lt;br /&gt;
**[[PIC18F4520: Serial Digital-to-Analog Conversion]]&lt;br /&gt;
**[[PIC18F4520: Analog Inputs]]&lt;br /&gt;
**[[PIC18F4520: Timers]]&lt;br /&gt;
**[[PIC18F4520: Comparator]]&lt;br /&gt;
&lt;br /&gt;
== Example Code in C for PIC18F4520==&lt;br /&gt;
*[[C Example: Parallel Interfacing with LCDs]]&lt;br /&gt;
*[[C Example: Digital Inputs]]&lt;br /&gt;
*[[C Example: PWM Motor Control]]&lt;br /&gt;
*[[C Example: Comparators]]&lt;br /&gt;
*[[C Example: Digital Outputs]]&lt;br /&gt;
*[[C Example: Analog Inputs]]&lt;br /&gt;
*[[C Example: Digital Outputs (Ports)]]&lt;br /&gt;
*[[C Example: Bi-Directional PWM Motor Control]]&lt;br /&gt;
*[[C Example: Serial LCD]]&lt;br /&gt;
&lt;br /&gt;
== Using the PIC32MX Series ==&lt;br /&gt;
*[[Introduction to the PIC32]]&lt;br /&gt;
*[[Getting Started with PIC32]] (includes NU32 development board)&lt;br /&gt;
** [[ME 333 Lab 2]] - Includes Digital IO, Analog Input, Parallel LCD and RS232 Com&lt;br /&gt;
** [[ME 333 Lab 4]] - Includes PWM and Encoder Motor Control&lt;br /&gt;
*[[Microcontroller PIC32MX460F512L]]&lt;br /&gt;
*[[Programming HID Bootloader on PIC32]] &lt;br /&gt;
*[[HelloWorld PIC32|Directions to code HelloWorld]]&lt;br /&gt;
*[[Directions to Load Files to PIC32 with HID Bootloader]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[PIC MCUs: Capabilities of PIC32MX]]&lt;br /&gt;
**[[Programming HID Bootloader on PIC32 |PIC32MX: Bootloader]]&lt;br /&gt;
**Simple Programs&lt;br /&gt;
***[[PIC32MX: Digital Inputs]]&lt;br /&gt;
***[[PIC32MX: Digital Outputs]]&lt;br /&gt;
***[[PIC32MX: Analog Inputs]]&lt;br /&gt;
**Communication&lt;br /&gt;
***[[PIC32MX: Parallel LCD]]&lt;br /&gt;
***[[PIC32MX: RS232]]&lt;br /&gt;
***[[PIC32MX:  USB Communication with a PC]]&lt;br /&gt;
***[[PIC32MX:  SPI External RAM]]&lt;br /&gt;
***[[PIC32MX:  I2C DAC]]&lt;br /&gt;
***[[PIC32MX:  I2C EEPROM]]&lt;br /&gt;
***[[PIC32MX:  SPI EEPROM]]&lt;br /&gt;
***[[PIC32MX:  I2C Communication between PIC32s]]&lt;br /&gt;
***[[PIC32MX:  SPI Communication between PIC32s]]&lt;br /&gt;
**Motor Control&lt;br /&gt;
***[[PIC32MX: PWM Motor Control|PIC32MX: PWM Motor Control]]&lt;br /&gt;
***[[PIC32MX: Encoder Motor Control|PIC32MX: Encoder Motor Control]]&lt;br /&gt;
***[[PIC32MX: Servo Control|PIC32MX: Servo Control]]&lt;br /&gt;
***[[PIC32MX:  Driving a Stepper Motor]]&lt;br /&gt;
**Capabilities&lt;br /&gt;
***[[PIC32MX:  Benchmarking Mathematical Operations]]&lt;br /&gt;
***[[PIC32MX:  FFT of Analog Input]]&lt;br /&gt;
***[[PIC32MX:  Inverse FFT]]&lt;br /&gt;
***[[PIC32MX:  XBee Wireless Round-trip Latency]]&lt;br /&gt;
***[[PIC32MX:  Interfacing with Force Sensors from a Scale]]&lt;br /&gt;
&lt;br /&gt;
==Other PIC Resources ==&lt;br /&gt;
&lt;br /&gt;
*[[PIC PWM Motor Driver]]&lt;br /&gt;
*[[Writing Code with the C18 Compiler]]&lt;br /&gt;
*[[Controlling a seven segment display]]&lt;br /&gt;
*[[PIC Microcontrollers with C18 Compiler]]&lt;br /&gt;
*[[PIC Motor Control and Serial Port Example]]&lt;br /&gt;
*[[PIC16F684]]&lt;br /&gt;
*[[PIC Microcontrollers with CCS Compiler]]&lt;br /&gt;
*[[Stepper motor control with the PIC]]&lt;br /&gt;
*[[PIC/C18 Compiler Tips and Troubleshooting]]&lt;br /&gt;
*[[CCS C]]&lt;br /&gt;
*[[Analog Input]]&lt;br /&gt;
*[[PIC MCUs: Hardware and Connections]]&lt;br /&gt;
*[[Storing constant data in program memory]]&lt;br /&gt;
*[[PIC Analog-Digital-Converter Example]]&lt;br /&gt;
*[[PIC Microcontroller]]&lt;br /&gt;
*[[Digital inputs &amp;amp; outputs]]&lt;br /&gt;
*[[Debugging C on a PIC]]&lt;br /&gt;
*[[Analog Output]]&lt;br /&gt;
*[[PIC MCUs: Software]]&lt;br /&gt;
*[[Interfacing to External EEPROM]]&lt;br /&gt;
*[[CCS IDE]]&lt;br /&gt;
*[[Interrupts]]&lt;br /&gt;
*[[PIC16F684 Registers]]&lt;br /&gt;
*[[Waveform Generation with AD9833]]&lt;br /&gt;
*[[Waveform Generation with AD9833, and SPI]]&lt;br /&gt;
*[[PIC computation time benchmarks]]&lt;br /&gt;
*[[PICkit 1]]&lt;br /&gt;
*[[PIC MCUs: 4520 Board]]&lt;br /&gt;
*[[More debugging tips]]&lt;br /&gt;
*[[Example Writeup: Analog Input]]&lt;br /&gt;
*[[LED Drivers]]&lt;br /&gt;
*[[Embedded Programming Tips for CCS C]]&lt;br /&gt;
*[[Wireless PIC bootloading]]&lt;br /&gt;
*[[PIC 18f4553]]&lt;br /&gt;
*[[I2C Motor Controller]]&lt;br /&gt;
*[[Driving a piezo speaker with a PIC]]&lt;br /&gt;
*[[PIC Servo Controller]]&lt;br /&gt;
*[[Watchdog timer]]&lt;br /&gt;
*[[Interfacing PIC with SPI memory]]&lt;br /&gt;
&lt;br /&gt;
==Programming the PIC with Microchip&#039;s MPLAB==&lt;/div&gt;</summary>
		<author><name>AndrewDai</name></author>
	</entry>
</feed>