2036 student lab assignment - students must add code where shown

Dependencies:   FFT Terminal_VT100 mbed

Committer:
4180_1
Date:
Thu Nov 01 19:10:56 2012 +0000
Revision:
0:257c8b623a6f
ver 1.0 4180 student lab assignment - more code must be added by students

Who changed what in which revision?

UserRevisionLine numberNew contents of line
4180_1 0:257c8b623a6f 1 // mymbedDAQ - Electronic Test Instrument Concept Demo & Lab assignment
4180_1 0:257c8b623a6f 2 // CODE MUST BE ADDED BY STUDENTS WHERE INDICATED!!!!!!!!!!!!!!!
4180_1 0:257c8b623a6f 3 // Uses VT100 terminal application on PC
4180_1 0:257c8b623a6f 4 // Needs terminal and FFT libs
4180_1 0:257c8b623a6f 5 //
4180_1 0:257c8b623a6f 6 // NOTE: for test signals must connect
4180_1 0:257c8b623a6f 7 // P18 to P16 (sine wave from D/A to A/D)
4180_1 0:257c8b623a6f 8 // P13 to P12 (digital test signal from serial port to LA digital input)
4180_1 0:257c8b623a6f 9 // P21 to P15 (PWM for square wave to A/D)
4180_1 0:257c8b623a6f 10 //
4180_1 0:257c8b623a6f 11 #include "mbed.h"
4180_1 0:257c8b623a6f 12 #include "FFT.h"
4180_1 0:257c8b623a6f 13 #include "Terminal.h"
4180_1 0:257c8b623a6f 14 #include <vector>
4180_1 0:257c8b623a6f 15 using namespace std;
4180_1 0:257c8b623a6f 16
4180_1 0:257c8b623a6f 17 // **********************************************************************************************
4180_1 0:257c8b623a6f 18 #define N 128 //number of analog samples to take - need power of two for FFT
4180_1 0:257c8b623a6f 19 float FFT_Data[N*2]; //complex data space for analog signal's FFT-1D array with real & imag pairs
4180_1 0:257c8b623a6f 20 float Data[N]; //data space for (real) analog signal samples
4180_1 0:257c8b623a6f 21 float Analog_Voltage; //used for DMM voltage reading
4180_1 0:257c8b623a6f 22 float Analog_out_value[N]; // Analog values of precomputed sine wave for D/A (function generator)
4180_1 0:257c8b623a6f 23 unsigned char PowerInt[N/2]; //used to store scaled magnitude of FFT bars (positive only)
4180_1 0:257c8b623a6f 24
4180_1 0:257c8b623a6f 25 // note use of volatile for an interrupt set global variable!
4180_1 0:257c8b623a6f 26 volatile int take_sample; //sample period timer flag - set by interrupt
4180_1 0:257c8b623a6f 27
4180_1 0:257c8b623a6f 28 vector <int> Digital_Signal (100); // use a vector for sample data for Logic Analyzer
4180_1 0:257c8b623a6f 29
4180_1 0:257c8b623a6f 30 char input_char; //character read from PC terminal application window
4180_1 0:257c8b623a6f 31 bool sine=true; //sine or square wave flag for test signal input
4180_1 0:257c8b623a6f 32 bool square=true; //50% or 25% duty cycle on square wave test signal
4180_1 0:257c8b623a6f 33
4180_1 0:257c8b623a6f 34
4180_1 0:257c8b623a6f 35 //Digital Signals for Logic Analyzer
4180_1 0:257c8b623a6f 36
4180_1 0:257c8b623a6f 37 // Used to read in digital signals
4180_1 0:257c8b623a6f 38 DigitalIn LogicAnalyzer_test_signal_in(p12);
4180_1 0:257c8b623a6f 39 // Used for digital test signal output
4180_1 0:257c8b623a6f 40 Serial LogicAnalyzer_test_signal_out(p13,p14);
4180_1 0:257c8b623a6f 41
4180_1 0:257c8b623a6f 42 //Analog I/O Signals for DMM, Oscilloscope, and Spectrum Analyzer
4180_1 0:257c8b623a6f 43
4180_1 0:257c8b623a6f 44 // Analog A/D Input
4180_1 0:257c8b623a6f 45 AnalogIn Analog_test_signal_in(p16);
4180_1 0:257c8b623a6f 46 // Analog D/A output test signal (for sine wave function generation)
4180_1 0:257c8b623a6f 47 AnalogOut Analog_test_signal_out(p18);
4180_1 0:257c8b623a6f 48
4180_1 0:257c8b623a6f 49
4180_1 0:257c8b623a6f 50 // PWM is used for alternate analog square wave signal source
4180_1 0:257c8b623a6f 51
4180_1 0:257c8b623a6f 52 // Analog A/D Input used for square wave
4180_1 0:257c8b623a6f 53 AnalogIn PWM_test_signal(p15);
4180_1 0:257c8b623a6f 54 // PWM output pint that generates a square wave
4180_1 0:257c8b623a6f 55 PwmOut PWM_Output(p21);
4180_1 0:257c8b623a6f 56
4180_1 0:257c8b623a6f 57 //unsed Analog input pins set to digital to reduce A/D noise
4180_1 0:257c8b623a6f 58 DigitalOut d2(p17);
4180_1 0:257c8b623a6f 59 DigitalOut d3(p19);
4180_1 0:257c8b623a6f 60 DigitalOut d4(p20);
4180_1 0:257c8b623a6f 61
4180_1 0:257c8b623a6f 62 //VT100 ANSI Terminal connected to PC
4180_1 0:257c8b623a6f 63 Terminal PC(USBTX, USBRX);
4180_1 0:257c8b623a6f 64
4180_1 0:257c8b623a6f 65
4180_1 0:257c8b623a6f 66 // **********************************************************************************************
4180_1 0:257c8b623a6f 67
4180_1 0:257c8b623a6f 68 void Take_Analog_Signal_Samples(float Analogs[]);
4180_1 0:257c8b623a6f 69 void Graphic_Display_Spectrum(unsigned char *Data);
4180_1 0:257c8b623a6f 70 void Graphic_Display_Time(float *Data);
4180_1 0:257c8b623a6f 71 void Digital_Multimeter();
4180_1 0:257c8b623a6f 72 void Logic_Analyzer();
4180_1 0:257c8b623a6f 73 void Oscilloscope();
4180_1 0:257c8b623a6f 74 void Spectrum_Analyzer();
4180_1 0:257c8b623a6f 75 void Function_Select();
4180_1 0:257c8b623a6f 76 void Duty_Cycle();
4180_1 0:257c8b623a6f 77
4180_1 0:257c8b623a6f 78 // **********************************************************************************************
4180_1 0:257c8b623a6f 79
4180_1 0:257c8b623a6f 80 int main()
4180_1 0:257c8b623a6f 81 {
4180_1 0:257c8b623a6f 82 // Start PWM hardware for a continuous square wave signal ouput with a 50% duty cycle
4180_1 0:257c8b623a6f 83 PWM_Output=0.5;
4180_1 0:257c8b623a6f 84 PWM_Output.period(0.0128);
4180_1 0:257c8b623a6f 85 while(1) {
4180_1 0:257c8b623a6f 86 // clear screen and print user menu selections
4180_1 0:257c8b623a6f 87 PC.cls();
4180_1 0:257c8b623a6f 88 PC.locate(0,5);
4180_1 0:257c8b623a6f 89 PC.printf(" 1 - Digital Multimeter\n\r");
4180_1 0:257c8b623a6f 90 PC.printf(" 2 - Logic Analyzer\n\r");
4180_1 0:257c8b623a6f 91 PC.printf(" 3 - Oscilloscope\n\r");
4180_1 0:257c8b623a6f 92 PC.printf(" 4 - Spectrum Analyzer \n\r");
4180_1 0:257c8b623a6f 93 PC.printf(" 5 - Function Generation - toggles between sine & square wave signal\n\r");
4180_1 0:257c8b623a6f 94 PC.printf(" 6 - Duty Cycle - toggles between 50%% and 25%% duty cycle on square wave");
4180_1 0:257c8b623a6f 95 PC.locate(0,0);
4180_1 0:257c8b623a6f 96 PC.printf(" Select Electronic Test Instrument (type 1...5)");
4180_1 0:257c8b623a6f 97 // reads a character from the PC terminal appication window
4180_1 0:257c8b623a6f 98 input_char=PC.getc();
4180_1 0:257c8b623a6f 99 // echo back selection char for human display on PC
4180_1 0:257c8b623a6f 100 PC.putc(input_char);
4180_1 0:257c8b623a6f 101 // delay for slow human to see character
4180_1 0:257c8b623a6f 102 wait(.5);
4180_1 0:257c8b623a6f 103 //ADD CODE HERE
4180_1 0:257c8b623a6f 104 // select instrument demo using input_char switch statement
4180_1 0:257c8b623a6f 105 // case for each function below
4180_1 0:257c8b623a6f 106 // 1 Digital_Multimeter();
4180_1 0:257c8b623a6f 107 // 2 Logic_Analyzer();
4180_1 0:257c8b623a6f 108 // 3 Oscilloscope();
4180_1 0:257c8b623a6f 109 // 4 Spectrum_Analyzer();
4180_1 0:257c8b623a6f 110 // 5 Function Select();
4180_1 0:257c8b623a6f 111 // 6 Duty Cycle();
4180_1 0:257c8b623a6f 112
4180_1 0:257c8b623a6f 113
4180_1 0:257c8b623a6f 114
4180_1 0:257c8b623a6f 115
4180_1 0:257c8b623a6f 116
4180_1 0:257c8b623a6f 117 //END ADD CODE HERE
4180_1 0:257c8b623a6f 118 }
4180_1 0:257c8b623a6f 119 }
4180_1 0:257c8b623a6f 120
4180_1 0:257c8b623a6f 121 //*********************************************************************************************
4180_1 0:257c8b623a6f 122 // toggles a flag between a sine or square wave test output
4180_1 0:257c8b623a6f 123 // sine flag is used in Take_Analog_Signal_Samples
4180_1 0:257c8b623a6f 124 void Function_Select()
4180_1 0:257c8b623a6f 125 {
4180_1 0:257c8b623a6f 126 sine=!sine;
4180_1 0:257c8b623a6f 127 }
4180_1 0:257c8b623a6f 128
4180_1 0:257c8b623a6f 129 //**********************************************************************************************
4180_1 0:257c8b623a6f 130 // Toggles the hardware PWM output between a 25% and 50% duty cycle square wave
4180_1 0:257c8b623a6f 131 // square flag stores state
4180_1 0:257c8b623a6f 132 void Duty_Cycle()
4180_1 0:257c8b623a6f 133 {
4180_1 0:257c8b623a6f 134 if (square)
4180_1 0:257c8b623a6f 135 PWM_Output=0.25;
4180_1 0:257c8b623a6f 136 else
4180_1 0:257c8b623a6f 137 PWM_Output=0.5;
4180_1 0:257c8b623a6f 138 square=!square;
4180_1 0:257c8b623a6f 139 //PWM hardware needs a bit of setup time to adjust
4180_1 0:257c8b623a6f 140 wait(.25);
4180_1 0:257c8b623a6f 141 }
4180_1 0:257c8b623a6f 142
4180_1 0:257c8b623a6f 143 // **********************************************************************************************
4180_1 0:257c8b623a6f 144
4180_1 0:257c8b623a6f 145 void Digital_Multimeter()
4180_1 0:257c8b623a6f 146 {
4180_1 0:257c8b623a6f 147 // PC.readable() indicates another character is available to read
4180_1 0:257c8b623a6f 148 // but it does not read the character or wait for a character
4180_1 0:257c8b623a6f 149 // It is a handy way to break out of a loop if any key is hit
4180_1 0:257c8b623a6f 150 while(!PC.readable()) {
4180_1 0:257c8b623a6f 151 // Digital Multimeter - reads an analog voltage on pin 16
4180_1 0:257c8b623a6f 152 // D/A output is connected to A/D input (0..3.3V range only!)
4180_1 0:257c8b623a6f 153 PC.cls(); //clear screen
4180_1 0:257c8b623a6f 154 PC.locate(9,0); // move cursor to 9,0
4180_1 0:257c8b623a6f 155 PC.printf("Digital Multimeter"); // print title
4180_1 0:257c8b623a6f 156 PC.locate(22,12);
4180_1 0:257c8b623a6f 157 PC.printf(" volts DC"); // label for voltage reading
4180_1 0:257c8b623a6f 158 // Plot Y Axis tick marks with labels
4180_1 0:257c8b623a6f 159 for(int i=21; i>3; i--) {
4180_1 0:257c8b623a6f 160 PC.locate(7,i);
4180_1 0:257c8b623a6f 161 // put a label every 1 volt on axis
4180_1 0:257c8b623a6f 162 if((i-1)%5==0) {
4180_1 0:257c8b623a6f 163 PC.putc('+');
4180_1 0:257c8b623a6f 164 PC.locate(1,i);
4180_1 0:257c8b623a6f 165 PC.printf("%d.0V",int((21.0-i)/16.0*3.3));
4180_1 0:257c8b623a6f 166 } else PC.putc('-');
4180_1 0:257c8b623a6f 167 }
4180_1 0:257c8b623a6f 168 for(int i=0; i<=64; i++) {
4180_1 0:257c8b623a6f 169 // Output the Analog test signal using D/A output 'Analog_test_signal_out
4180_1 0:257c8b623a6f 170 // makes D/A outputvoltage increase linear from 0 to 3.3
4180_1 0:257c8b623a6f 171 // (but scaled from 0 to 1.0 in C/C++) using loop value i to change it
4180_1 0:257c8b623a6f 172 //ADD CODE HERE - 1 line
4180_1 0:257c8b623a6f 173
4180_1 0:257c8b623a6f 174 //END ADD CODE HERE
4180_1 0:257c8b623a6f 175 // Print voltage at 15,12
4180_1 0:257c8b623a6f 176 PC.locate(15,12);
4180_1 0:257c8b623a6f 177 //ADD CODE HERE
4180_1 0:257c8b623a6f 178 // read in the analog voltage using A/D input "Analog_test_signal_in"
4180_1 0:257c8b623a6f 179 // multiply value by 3.3 to convert to actual voltage level
4180_1 0:257c8b623a6f 180 // save in "Analog_Voltage"
4180_1 0:257c8b623a6f 181
4180_1 0:257c8b623a6f 182 // Print Analog_Voltage*3.3 in "%7.3F" format
4180_1 0:257c8b623a6f 183
4180_1 0:257c8b623a6f 184 // Display Analog Level Bar but only every four display updates (i%4) for faster updates
4180_1 0:257c8b623a6f 185 // on PC use char(219) for a solid bar graphics character or a space ' ' to erase
4180_1 0:257c8b623a6f 186 // use locate to draw a vertical bar
4180_1 0:257c8b623a6f 187
4180_1 0:257c8b623a6f 188
4180_1 0:257c8b623a6f 189
4180_1 0:257c8b623a6f 190
4180_1 0:257c8b623a6f 191
4180_1 0:257c8b623a6f 192 }
4180_1 0:257c8b623a6f 193 //END ADD CODE HERE
4180_1 0:257c8b623a6f 194 }
4180_1 0:257c8b623a6f 195 // delay to allow time to view each display
4180_1 0:257c8b623a6f 196 wait(1);
4180_1 0:257c8b623a6f 197 }
4180_1 0:257c8b623a6f 198
4180_1 0:257c8b623a6f 199 // **********************************************************************************************
4180_1 0:257c8b623a6f 200
4180_1 0:257c8b623a6f 201 void Logic_Analyzer()
4180_1 0:257c8b623a6f 202 {
4180_1 0:257c8b623a6f 203 // Logic Analyzer
4180_1 0:257c8b623a6f 204 // Reads in a serial digital output pin (0 or 3.3V)
4180_1 0:257c8b623a6f 205 // pin 13 TX serial output tied to pin12 digital input
4180_1 0:257c8b623a6f 206 while(!PC.readable()) {
4180_1 0:257c8b623a6f 207 // Loop through several ASCII characters for display test
4180_1 0:257c8b623a6f 208 for(int c='A'; c<='z'&&!PC.readable(); c=c+1) {
4180_1 0:257c8b623a6f 209 PC.cls();
4180_1 0:257c8b623a6f 210 Digital_Signal.clear();
4180_1 0:257c8b623a6f 211 PC.locate(15,0);
4180_1 0:257c8b623a6f 212 PC.printf("Logic Analyzer Display - RS-232 Serial ASCII character %c 0x%X",char(c), int(c));
4180_1 0:257c8b623a6f 213 // Sample digital data for display - need 80 samples (have 80 display cols)
4180_1 0:257c8b623a6f 214 for(int i=0; i<80; i++) {
4180_1 0:257c8b623a6f 215 // Test signal for Logic Analyzer
4180_1 0:257c8b623a6f 216 // Send out a new character char(c) using the serial port
4180_1 0:257c8b623a6f 217 // after a small delay so that it will show up in middle of display
4180_1 0:257c8b623a6f 218 if(i==6) LogicAnalyzer_test_signal_out.putc(char(c));
4180_1 0:257c8b623a6f 219 //ADD CODE HERE
4180_1 0:257c8b623a6f 220 // Use "Digital_Signal" vector to store data from "LogicAnalyzer_test_signal_in" (DigitalIn pin)
4180_1 0:257c8b623a6f 221
4180_1 0:257c8b623a6f 222 // time delay is used to adjust sample time interval
4180_1 0:257c8b623a6f 223 // a hardware timer would be more accurate
4180_1 0:257c8b623a6f 224 // that will be explained later in the oscilloscope example
4180_1 0:257c8b623a6f 225 // some adjustment to time delay here might be needed for your code
4180_1 0:257c8b623a6f 226 // scale so that you can see entire ASCII character on display
4180_1 0:257c8b623a6f 227 wait(.00002);
4180_1 0:257c8b623a6f 228 }
4180_1 0:257c8b623a6f 229 //Display data
4180_1 0:257c8b623a6f 230 //Move cursor to 0,15 or 0,5 based on first digital bit from Digital_Signal[i]
4180_1 0:257c8b623a6f 231 //Scan through data samples from left to right and draw the high or low line
4180_1 0:257c8b623a6f 232 //Locate is only needed when changing between high or low value
4180_1 0:257c8b623a6f 233 //loop through 80 sample values
4180_1 0:257c8b623a6f 234 PC.locate(0,(15 - int(float(Digital_Signal[0])*10.0)));
4180_1 0:257c8b623a6f 235 for(int i=0; i<80; i++) {
4180_1 0:257c8b623a6f 236 // If no change in digital signal, or fist bit just output a horiz bar char(196)?
4180_1 0:257c8b623a6f 237
4180_1 0:257c8b623a6f 238 // if A 1 to 0 transisition occured
4180_1 0:257c8b623a6f 239 // draw a vertical line with correct bar and corner characters (191, 179, 192)
4180_1 0:257c8b623a6f 240 // PC.locate(col,row) is needed for vertical line drawing
4180_1 0:257c8b623a6f 241
4180_1 0:257c8b623a6f 242
4180_1 0:257c8b623a6f 243
4180_1 0:257c8b623a6f 244
4180_1 0:257c8b623a6f 245
4180_1 0:257c8b623a6f 246 //if A 0 to 1 transisiton occured
4180_1 0:257c8b623a6f 247 // draw a vertical line with correct bar and corner characters (217, 179, 218)
4180_1 0:257c8b623a6f 248
4180_1 0:257c8b623a6f 249
4180_1 0:257c8b623a6f 250
4180_1 0:257c8b623a6f 251
4180_1 0:257c8b623a6f 252
4180_1 0:257c8b623a6f 253 }
4180_1 0:257c8b623a6f 254 //plot X axis tick marks and labels
4180_1 0:257c8b623a6f 255 //only initial locate needed
4180_1 0:257c8b623a6f 256 PC.locate(0,20);
4180_1 0:257c8b623a6f 257
4180_1 0:257c8b623a6f 258
4180_1 0:257c8b623a6f 259
4180_1 0:257c8b623a6f 260
4180_1 0:257c8b623a6f 261
4180_1 0:257c8b623a6f 262
4180_1 0:257c8b623a6f 263 //END ADD CODE HERE
4180_1 0:257c8b623a6f 264 // delay to allow time to view each display
4180_1 0:257c8b623a6f 265 wait(1);
4180_1 0:257c8b623a6f 266 }
4180_1 0:257c8b623a6f 267 }
4180_1 0:257c8b623a6f 268 }
4180_1 0:257c8b623a6f 269 // **********************************************************************************************
4180_1 0:257c8b623a6f 270
4180_1 0:257c8b623a6f 271 void Oscilloscope()
4180_1 0:257c8b623a6f 272 {
4180_1 0:257c8b623a6f 273 while(!PC.readable()) {
4180_1 0:257c8b623a6f 274 // Oscilloscope
4180_1 0:257c8b623a6f 275 // D/A sends out a sine wave and the A/D reads it back in
4180_1 0:257c8b623a6f 276 // PWM hardware sends out a square wave to another A/D input
4180_1 0:257c8b623a6f 277 // loop through increasing the frequency of the test signals for each display
4180_1 0:257c8b623a6f 278 for(int i=1; i<11&&!PC.readable(); i++) {
4180_1 0:257c8b623a6f 279 //Setup square wave signal source period - increase each loop iteration
4180_1 0:257c8b623a6f 280 PWM_Output.period(0.0128/i);
4180_1 0:257c8b623a6f 281 wait(0.25);
4180_1 0:257c8b623a6f 282 // Precompute sine wave values for faster D/A output to save execution time
4180_1 0:257c8b623a6f 283 // Need to add DC bias and scale sine wave from 0...1.0 for analog out function
4180_1 0:257c8b623a6f 284 // (i.e. not just -1..1)
4180_1 0:257c8b623a6f 285 // need N samples of one sine cycle first time - then make it i times faster each
4180_1 0:257c8b623a6f 286 // loop iteration - samples go in Analog_out_value[k]
4180_1 0:257c8b623a6f 287 for(int k=0; k<N; k++) {
4180_1 0:257c8b623a6f 288 //ADD CODE HERE - 1 line to compute sine values
4180_1 0:257c8b623a6f 289
4180_1 0:257c8b623a6f 290 //END ADD CODE HERE
4180_1 0:257c8b623a6f 291 }
4180_1 0:257c8b623a6f 292 //Reads analog samples using test signals setup above
4180_1 0:257c8b623a6f 293 Take_Analog_Signal_Samples(Data);
4180_1 0:257c8b623a6f 294 //Displays an analog signal in time
4180_1 0:257c8b623a6f 295 Graphic_Display_Time(Data);
4180_1 0:257c8b623a6f 296 // delay to allow time to view each display
4180_1 0:257c8b623a6f 297 wait(2);
4180_1 0:257c8b623a6f 298 }
4180_1 0:257c8b623a6f 299 }
4180_1 0:257c8b623a6f 300 }
4180_1 0:257c8b623a6f 301
4180_1 0:257c8b623a6f 302 // **********************************************************************************************
4180_1 0:257c8b623a6f 303 void Spectrum_Analyzer()
4180_1 0:257c8b623a6f 304 {
4180_1 0:257c8b623a6f 305 while(!PC.readable()) {
4180_1 0:257c8b623a6f 306 // Spectrum Analyzer
4180_1 0:257c8b623a6f 307 // Compute FFT of sampled signal
4180_1 0:257c8b623a6f 308 // D/A sends out a sine wave and the A/D reads it back in
4180_1 0:257c8b623a6f 309 // loop through increasing the frequency of test signals for each display
4180_1 0:257c8b623a6f 310 for(int i=1; i<11&&!PC.readable(); i++) {
4180_1 0:257c8b623a6f 311 //Setup square wave signal source with correct period
4180_1 0:257c8b623a6f 312 PWM_Output.period(.0128/i);
4180_1 0:257c8b623a6f 313 wait(0.25);
4180_1 0:257c8b623a6f 314 //Precompute sine wave values for D/A output to save execution time
4180_1 0:257c8b623a6f 315 //same as Oscilloscope code earlier
4180_1 0:257c8b623a6f 316 for(int k=0; k<N; k++) {
4180_1 0:257c8b623a6f 317 //ADD CODE HERE - line
4180_1 0:257c8b623a6f 318
4180_1 0:257c8b623a6f 319 //END ADD CODE HERE
4180_1 0:257c8b623a6f 320 }
4180_1 0:257c8b623a6f 321 //Reads analog samples
4180_1 0:257c8b623a6f 322 Take_Analog_Signal_Samples(Data);
4180_1 0:257c8b623a6f 323 // put data in complex format for FFT code (real followed by imag=0 in 2*N 1D array)
4180_1 0:257c8b623a6f 324 // Required by Numerical Recipes in C++ Algorithm for FFT used in in vFFT.cpp
4180_1 0:257c8b623a6f 325 for(int k=0; k<N; k++) {
4180_1 0:257c8b623a6f 326 FFT_Data[k*2]=Data[k];
4180_1 0:257c8b623a6f 327 FFT_Data[k*2+1] = 0.0;
4180_1 0:257c8b623a6f 328 }
4180_1 0:257c8b623a6f 329 Graphic_Display_Time(Data);
4180_1 0:257c8b623a6f 330 // delay to allow time to view each time display
4180_1 0:257c8b623a6f 331 wait(2);
4180_1 0:257c8b623a6f 332 // Spectrum Analyzer
4180_1 0:257c8b623a6f 333 // Compute FFT of sampled signal
4180_1 0:257c8b623a6f 334 vFFT(FFT_Data-1,N);
4180_1 0:257c8b623a6f 335 // Compute magnitude for positive frequency display
4180_1 0:257c8b623a6f 336 // scaled and returned in a char array
4180_1 0:257c8b623a6f 337 vCalPowerInt(FFT_Data,PowerInt,N/2);
4180_1 0:257c8b623a6f 338 // Display Frequency content of sampled signal
4180_1 0:257c8b623a6f 339 Graphic_Display_Spectrum(PowerInt);
4180_1 0:257c8b623a6f 340 // delay to allow time to view each frequency display
4180_1 0:257c8b623a6f 341 wait(2);
4180_1 0:257c8b623a6f 342 }
4180_1 0:257c8b623a6f 343 }
4180_1 0:257c8b623a6f 344 }
4180_1 0:257c8b623a6f 345
4180_1 0:257c8b623a6f 346
4180_1 0:257c8b623a6f 347 // **********************************************************************************************
4180_1 0:257c8b623a6f 348 // Functions to sample Analog input data at an accurate 10Khz rate (every 100 us)
4180_1 0:257c8b623a6f 349 // used by Oscilloscope and Spectrum Analyzer
4180_1 0:257c8b623a6f 350 void Sample_timer_interrupt(void)
4180_1 0:257c8b623a6f 351 {
4180_1 0:257c8b623a6f 352 // Sets flag when time to read in another analog sample
4180_1 0:257c8b623a6f 353 // Timer interrupt comes here when a it hits every sample time interval
4180_1 0:257c8b623a6f 354 take_sample=1;
4180_1 0:257c8b623a6f 355 }
4180_1 0:257c8b623a6f 356 void Take_Analog_Signal_Samples(float Analogs[])
4180_1 0:257c8b623a6f 357 {
4180_1 0:257c8b623a6f 358 // setup a timer to determine accurate sample time
4180_1 0:257c8b623a6f 359 Ticker Sample_Period;
4180_1 0:257c8b623a6f 360 // reset sample time interval flag
4180_1 0:257c8b623a6f 361 take_sample=0;
4180_1 0:257c8b623a6f 362 // output first D/A value for sine wave
4180_1 0:257c8b623a6f 363 Analog_test_signal_out=Analog_out_value[0];
4180_1 0:257c8b623a6f 364 // Start periodic timer interrupts to ensure accurate control of sample time interval
4180_1 0:257c8b623a6f 365 // Sample_timer_interrupt is "called" every 100 us by hardware interrupt signal
4180_1 0:257c8b623a6f 366 Sample_Period.attach_us(&Sample_timer_interrupt,100); // 100 us, 10.000 KHz
4180_1 0:257c8b623a6f 367 // Take N analog samples at sample period
4180_1 0:257c8b623a6f 368 // timing is critical inside loop here - needs to be fast
4180_1 0:257c8b623a6f 369 for(int k=0; k<N; k++) {
4180_1 0:257c8b623a6f 370 // wait and spin here until sample timer interrupt routine sets take sample flag
4180_1 0:257c8b623a6f 371 while(take_sample==0) {};
4180_1 0:257c8b623a6f 372 // next sample period reached (timer interrupt has set take_sample==1)
4180_1 0:257c8b623a6f 373 // reset take sample
4180_1 0:257c8b623a6f 374 take_sample=0;
4180_1 0:257c8b623a6f 375
4180_1 0:257c8b623a6f 376 // select sine or square input source using "sine" bool flag in if - two A/D input channels
4180_1 0:257c8b623a6f 377 //read in next sample into Analogs[k]
4180_1 0:257c8b623a6f 378 //ADD CODE HERE
4180_1 0:257c8b623a6f 379
4180_1 0:257c8b623a6f 380
4180_1 0:257c8b623a6f 381
4180_1 0:257c8b623a6f 382
4180_1 0:257c8b623a6f 383
4180_1 0:257c8b623a6f 384 //END ADD CODE HERE
4180_1 0:257c8b623a6f 385 }
4180_1 0:257c8b623a6f 386 // got the N analog samples
4180_1 0:257c8b623a6f 387 // so turn off sample timer interrupts
4180_1 0:257c8b623a6f 388 Sample_Period.detach();
4180_1 0:257c8b623a6f 389 return;
4180_1 0:257c8b623a6f 390 }
4180_1 0:257c8b623a6f 391
4180_1 0:257c8b623a6f 392 // **********************************************************************************************
4180_1 0:257c8b623a6f 393 void Graphic_Display_Spectrum(unsigned char *Data)
4180_1 0:257c8b623a6f 394 // plots frequency bars using data array - 64 values
4180_1 0:257c8b623a6f 395 {
4180_1 0:257c8b623a6f 396 char max_value=0;
4180_1 0:257c8b623a6f 397 // clear screen
4180_1 0:257c8b623a6f 398 PC.cls();
4180_1 0:257c8b623a6f 399 PC.locate(15,0);
4180_1 0:257c8b623a6f 400 // print title
4180_1 0:257c8b623a6f 401 PC.printf("Spectrum Analyzer - Frequency Domain Display");
4180_1 0:257c8b623a6f 402 //ADD CODE HERE
4180_1 0:257c8b623a6f 403 //plot X axis tick marks with labels
4180_1 0:257c8b623a6f 404
4180_1 0:257c8b623a6f 405
4180_1 0:257c8b623a6f 406
4180_1 0:257c8b623a6f 407
4180_1 0:257c8b623a6f 408
4180_1 0:257c8b623a6f 409 //END ADD CODE HERE
4180_1 0:257c8b623a6f 410 // Find max Data[i] value for autoscaling feature
4180_1 0:257c8b623a6f 411 // max value bar should fill the screen display area
4180_1 0:257c8b623a6f 412 for (int i=0; i<N/2; i++) {
4180_1 0:257c8b623a6f 413 if (Data[i] > max_value) max_value = Data[i];
4180_1 0:257c8b623a6f 414 }
4180_1 0:257c8b623a6f 415 //ADD CODE HERE
4180_1 0:257c8b623a6f 416 // Plot Y Axis tick marks with labels
4180_1 0:257c8b623a6f 417
4180_1 0:257c8b623a6f 418
4180_1 0:257c8b623a6f 419
4180_1 0:257c8b623a6f 420
4180_1 0:257c8b623a6f 421
4180_1 0:257c8b623a6f 422
4180_1 0:257c8b623a6f 423 // use max value for Y axis auto scaling and axis label value calculations
4180_1 0:257c8b623a6f 424 // draw the frequency bars using Data[i] values (0..N/2 i.e., the positive spectrum only)
4180_1 0:257c8b623a6f 425 // loop though 20 lines starting at top left of bar display area (lines 1-20)
4180_1 0:257c8b623a6f 426 for(int i=2; i<=21; i++) {
4180_1 0:257c8b623a6f 427 // then loop through each display bar across 64 cols of display area
4180_1 0:257c8b623a6f 428 // if scaled Data[col] value> current line (height) move cursor and print a bar char(222)
4180_1 0:257c8b623a6f 429 // values in Data[col] are in range from 0 to max_value
4180_1 0:257c8b623a6f 430 // scale so that max_value bar height is number of characters in display area
4180_1 0:257c8b623a6f 431 // loop through 64 columns across display
4180_1 0:257c8b623a6f 432 for(int k=0; k<(N/2); k++) {
4180_1 0:257c8b623a6f 433 // if( Data[k]...
4180_1 0:257c8b623a6f 434 }
4180_1 0:257c8b623a6f 435 //END ADD CODE HERE
4180_1 0:257c8b623a6f 436 }
4180_1 0:257c8b623a6f 437
4180_1 0:257c8b623a6f 438 }
4180_1 0:257c8b623a6f 439
4180_1 0:257c8b623a6f 440 //************************************************************************************************
4180_1 0:257c8b623a6f 441 void Graphic_Display_Time(float *Data)
4180_1 0:257c8b623a6f 442 // displays Data vs time for Oscilloscope style display
4180_1 0:257c8b623a6f 443 {
4180_1 0:257c8b623a6f 444 // clear screen
4180_1 0:257c8b623a6f 445 PC.cls();
4180_1 0:257c8b623a6f 446 PC.locate(20,0);
4180_1 0:257c8b623a6f 447 // print title
4180_1 0:257c8b623a6f 448 PC.printf("Oscilloscope - Time Domain Display");
4180_1 0:257c8b623a6f 449 //ADD CODE HERE
4180_1 0:257c8b623a6f 450 // Plot Y Axis tick marks with labels
4180_1 0:257c8b623a6f 451
4180_1 0:257c8b623a6f 452
4180_1 0:257c8b623a6f 453
4180_1 0:257c8b623a6f 454
4180_1 0:257c8b623a6f 455
4180_1 0:257c8b623a6f 456 // plot X axis tick marks with labels
4180_1 0:257c8b623a6f 457
4180_1 0:257c8b623a6f 458
4180_1 0:257c8b623a6f 459
4180_1 0:257c8b623a6f 460
4180_1 0:257c8b623a6f 461
4180_1 0:257c8b623a6f 462
4180_1 0:257c8b623a6f 463 // loop through each sampled Data[i] value (0..N)
4180_1 0:257c8b623a6f 464 // scale to display area, move to proper col,row
4180_1 0:257c8b623a6f 465 // and plot each point using a '.' (period)
4180_1 0:257c8b623a6f 466 // 128 points in 64 display columns so two samples per column
4180_1 0:257c8b623a6f 467 // (but likely value is in a different row)
4180_1 0:257c8b623a6f 468 // loop through data values
4180_1 0:257c8b623a6f 469 for(int i=0; i<N; i++ ) {
4180_1 0:257c8b623a6f 470
4180_1 0:257c8b623a6f 471 }
4180_1 0:257c8b623a6f 472 //END ADD CODE HERE
4180_1 0:257c8b623a6f 473 }
4180_1 0:257c8b623a6f 474