Function Generator and Oscilloscope

Dependencies:   C12832_lcd DebounceIn mbed

Committer:
trichards1138
Date:
Fri May 30 04:07:27 2014 +0000
Revision:
3:920cc6573be0
Parent:
2:218abf68fe93
Child:
4:7340e7a6eb14
Final turn in code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
trichards1138 3:920cc6573be0 1 //***************************************************************
trichards1138 3:920cc6573be0 2 // Function Generator - main entry and sole source file for an
trichards1138 3:920cc6573be0 3 // MBED based function generator. The program will output
trichards1138 3:920cc6573be0 4 // waveforms sinewave, squarewave, sawtooth, and flat DC on the
trichards1138 3:920cc6573be0 5 // MBED analog out pin (P18). The joystick buttons are used
trichards1138 3:920cc6573be0 6 // to control the period and amplitude of the output waveforms.
trichards1138 3:920cc6573be0 7 // This is because the pots are a little too unstable to be read
trichards1138 3:920cc6573be0 8 // out in a tight update loop for the waveforms. The exception
trichards1138 3:920cc6573be0 9 // is the DC output. That uses the pot as it doesn't need a tight
trichards1138 3:920cc6573be0 10 // loop.
trichards1138 3:920cc6573be0 11 //
trichards1138 3:920cc6573be0 12 // Author: Terry Richards
trichards1138 3:920cc6573be0 13 // Date: 5/29/2014
trichards1138 3:920cc6573be0 14 //
trichards1138 0:dfc39b05ea05 15 #include "mbed.h"
trichards1138 0:dfc39b05ea05 16 #include "C12832_lcd.h"
trichards1138 0:dfc39b05ea05 17
trichards1138 0:dfc39b05ea05 18 Serial pc(USBTX, USBRX);
trichards1138 0:dfc39b05ea05 19 C12832_LCD LCD;
trichards1138 0:dfc39b05ea05 20 AnalogIn Ain(p17);
trichards1138 0:dfc39b05ea05 21 AnalogOut Aout(p18);
trichards1138 0:dfc39b05ea05 22 AnalogIn pot1(p19);
trichards1138 0:dfc39b05ea05 23 AnalogIn pot2(p20);
trichards1138 3:920cc6573be0 24
trichards1138 0:dfc39b05ea05 25 DigitalIn up(p15);
trichards1138 0:dfc39b05ea05 26 DigitalIn down(p12);
trichards1138 0:dfc39b05ea05 27 DigitalIn left(p13);
trichards1138 0:dfc39b05ea05 28 DigitalIn right(p16);
trichards1138 0:dfc39b05ea05 29 BusIn joy(p15,p12,p13,p16);
trichards1138 0:dfc39b05ea05 30 DigitalIn OnOff(p14);
trichards1138 0:dfc39b05ea05 31
trichards1138 3:920cc6573be0 32 bool first = true;
trichards1138 0:dfc39b05ea05 33
trichards1138 3:920cc6573be0 34 // check_update - checks the buttons to see if the user wants
trichards1138 3:920cc6573be0 35 // to update either the vertical (in volts) or the horizontal
trichards1138 3:920cc6573be0 36 // (in uS) for the currently selected waveform. It also updates
trichards1138 3:920cc6573be0 37 // the LCD
trichards1138 3:920cc6573be0 38 // **** The joystick is used instead of the pots because *****
trichards1138 3:920cc6573be0 39 // **** I found that the pots were to unstable ***************
trichards1138 3:920cc6573be0 40 // Inputs - the vert and horiz from the calling waveform routine
trichards1138 3:920cc6573be0 41 // Outputs - the updated vert and horiz based on the button presses
trichards1138 3:920cc6573be0 42 //
trichards1138 3:920cc6573be0 43 #define SINE 1
trichards1138 3:920cc6573be0 44 #define SQUARE 2
trichards1138 3:920cc6573be0 45 #define DC 3
trichards1138 3:920cc6573be0 46 #define SAW 4
trichards1138 3:920cc6573be0 47 void check_update( int type, //what type of waveform
trichards1138 3:920cc6573be0 48 double *vert, //vertical in volts
trichards1138 3:920cc6573be0 49 int *horiz, //horizontal in us
trichards1138 3:920cc6573be0 50 float vertmax, //max vertical in volts
trichards1138 3:920cc6573be0 51 int horizmax, //max horizontal in us
trichards1138 3:920cc6573be0 52 bool init ) //put initial vert and horiz
trichards1138 3:920cc6573be0 53 { //on LCD screen if set
trichards1138 3:920cc6573be0 54 if( type ) { //The header is static once the waveform is chosen
trichards1138 3:920cc6573be0 55 LCD.locate(0, 3);
trichards1138 3:920cc6573be0 56 switch( type ) { //only done if type is set
trichards1138 3:920cc6573be0 57 case SINE:
trichards1138 3:920cc6573be0 58 LCD.printf("Current WaveForm: Sine ");
trichards1138 3:920cc6573be0 59 break;
trichards1138 3:920cc6573be0 60 case SQUARE:
trichards1138 3:920cc6573be0 61 LCD.printf("Current WaveForm: Square ");
trichards1138 3:920cc6573be0 62 break;
trichards1138 3:920cc6573be0 63 case DC:
trichards1138 3:920cc6573be0 64 LCD.printf("Current WaveForm: DC ");
trichards1138 3:920cc6573be0 65 break;
trichards1138 3:920cc6573be0 66 case SAW:
trichards1138 3:920cc6573be0 67 LCD.printf("Current WaveForm: SawTooth");
trichards1138 3:920cc6573be0 68 }
trichards1138 3:920cc6573be0 69 }
trichards1138 3:920cc6573be0 70 if( up ) { //if user pushes up button
trichards1138 3:920cc6573be0 71 if( *vert < (1.0 - 0.001) )
trichards1138 3:920cc6573be0 72 *vert += 0.01; //update the vertical
trichards1138 3:920cc6573be0 73 LCD.locate(0, 23); //vert is a percentage between 0 and 1
trichards1138 3:920cc6573be0 74 LCD.printf("Height: %5.3f V", *vert*3.3);
trichards1138 3:920cc6573be0 75 }
trichards1138 3:920cc6573be0 76 if( down ) {
trichards1138 3:920cc6573be0 77 if( *vert > 0.01 )
trichards1138 3:920cc6573be0 78 *vert -= 0.01; //update the vertical down
trichards1138 3:920cc6573be0 79 LCD.locate(0, 23);
trichards1138 3:920cc6573be0 80 LCD.printf("Height: %5.3f V", *vert*3.3);
trichards1138 3:920cc6573be0 81 }
trichards1138 3:920cc6573be0 82 if( right ) { //right updates the horizontal in us
trichards1138 3:920cc6573be0 83 if( *horiz < 100 ) //fine grain if below 100
trichards1138 3:920cc6573be0 84 *horiz += 1;
trichards1138 3:920cc6573be0 85 else if( *horiz < 1000 ) //little coarser
trichards1138 3:920cc6573be0 86 *horiz += 100;
trichards1138 3:920cc6573be0 87 else
trichards1138 3:920cc6573be0 88 *horiz += 1000;
trichards1138 3:920cc6573be0 89 if( *horiz > 100000 ) //most coarse
trichards1138 3:920cc6573be0 90 *horiz = 100000;
trichards1138 3:920cc6573be0 91 LCD.locate(0, 13);
trichards1138 3:920cc6573be0 92 LCD.printf("PW/Period: %d uS ", *horiz);
trichards1138 3:920cc6573be0 93 }
trichards1138 3:920cc6573be0 94 if( left ) { //left updates horizontal down
trichards1138 3:920cc6573be0 95 if( *horiz < 100 )
trichards1138 3:920cc6573be0 96 *horiz -= 1;
trichards1138 3:920cc6573be0 97 else if( *horiz < 1000 )
trichards1138 3:920cc6573be0 98 *horiz -= 100;
trichards1138 3:920cc6573be0 99 else
trichards1138 3:920cc6573be0 100 *horiz -= 1000;
trichards1138 3:920cc6573be0 101 if( *horiz <= 0 )
trichards1138 3:920cc6573be0 102 *horiz = 1;
trichards1138 3:920cc6573be0 103 LCD.locate(0, 13);
trichards1138 3:920cc6573be0 104 LCD.printf("PW/Period: %d uS ", *horiz);
trichards1138 3:920cc6573be0 105 }
trichards1138 3:920cc6573be0 106 if( init ) { //only done if bool init is true
trichards1138 3:920cc6573be0 107 LCD.locate(0, 13); //used for initial LCD update
trichards1138 3:920cc6573be0 108 LCD.printf("PW/Period: %d uS ", *horiz);
trichards1138 3:920cc6573be0 109 LCD.locate(0, 23);
trichards1138 3:920cc6573be0 110 LCD.printf("Height: %5.3f V", *vert*3.3);
trichards1138 1:e31325194990 111 }
trichards1138 0:dfc39b05ea05 112 }
trichards1138 0:dfc39b05ea05 113
trichards1138 3:920cc6573be0 114 // SineWave - is initiated when the user selects sinewave output
trichards1138 3:920cc6573be0 115 // Sends a sine wave to the Aout pin.
trichards1138 3:920cc6573be0 116 // The up and down buttons of the joystick control the amplitude
trichards1138 3:920cc6573be0 117 // The right and left buttons control the period
trichards1138 3:920cc6573be0 118 void sineWave(void)
trichards1138 3:920cc6573be0 119 {
trichards1138 3:920cc6573be0 120 int horiz=1000;
trichards1138 3:920cc6573be0 121 double vert=1.0, outval, i;
trichards1138 3:920cc6573be0 122 while( OnOff )
trichards1138 3:920cc6573be0 123 wait_ms(10);
trichards1138 3:920cc6573be0 124 check_update( SINE, &vert, &horiz, 1.0, 10000, true );
trichards1138 3:920cc6573be0 125 while(!OnOff) { // thread loop
trichards1138 3:920cc6573be0 126 check_update( 0, &vert, &horiz, 1.0, 10000, false );
trichards1138 3:920cc6573be0 127 for (i=0; i<2; i=i+0.05) {
trichards1138 3:920cc6573be0 128 outval = 0.5 + 0.5*vert*sin(i*3.14159);
trichards1138 3:920cc6573be0 129 Aout.write(outval); // Compute the sine value, + half the range
trichards1138 3:920cc6573be0 130 wait_us(horiz); // Controls the sine wave period
trichards1138 3:920cc6573be0 131 }
trichards1138 3:920cc6573be0 132 }
trichards1138 3:920cc6573be0 133 while( OnOff )
trichards1138 3:920cc6573be0 134 first = true;
trichards1138 3:920cc6573be0 135 }
trichards1138 3:920cc6573be0 136
trichards1138 3:920cc6573be0 137 // squareWave - called if user selects squarewave. Sends the
trichards1138 3:920cc6573be0 138 // square wave to the Aout pin.
trichards1138 3:920cc6573be0 139 // The up and down buttons of the joystick control the amplitude
trichards1138 3:920cc6573be0 140 // The right and left buttons control the period
trichards1138 1:e31325194990 141 void squareWave(void)
trichards1138 0:dfc39b05ea05 142 {
trichards1138 3:920cc6573be0 143 static double height = 1.0;
trichards1138 3:920cc6573be0 144 static int width = 20;
trichards1138 3:920cc6573be0 145 check_update( SQUARE, &height, &width, 1.0, 10000, true );
trichards1138 1:e31325194990 146 while(!OnOff) { // thread loop
trichards1138 3:920cc6573be0 147 check_update( 0, &height, &width, 1.0, 100000, false );
trichards1138 1:e31325194990 148 Aout.write(height);
trichards1138 3:920cc6573be0 149 wait_us(width);
trichards1138 1:e31325194990 150 Aout.write(0);
trichards1138 3:920cc6573be0 151 wait_us(width);
trichards1138 0:dfc39b05ea05 152 }
trichards1138 3:920cc6573be0 153 while( OnOff )
trichards1138 3:920cc6573be0 154 first = true;
trichards1138 0:dfc39b05ea05 155 }
trichards1138 0:dfc39b05ea05 156
trichards1138 3:920cc6573be0 157 // flatdc - called if user selects dc sig
trichards1138 0:dfc39b05ea05 158 // pot2 controls the height of dc signal
trichards1138 3:920cc6573be0 159 // The check_update is not used here because the
trichards1138 3:920cc6573be0 160 // pot does not interrupt dc operation.
trichards1138 1:e31325194990 161 void flatdc(void)
trichards1138 0:dfc39b05ea05 162 {
trichards1138 3:920cc6573be0 163 float current = pot2.read();
trichards1138 3:920cc6573be0 164 LCD.locate(0, 3);
trichards1138 3:920cc6573be0 165 LCD.printf("Current WaveForm: DC ");
trichards1138 3:920cc6573be0 166 LCD.locate(0, 13);
trichards1138 3:920cc6573be0 167 LCD.printf("DC Volts: %f V", current*3.3);
trichards1138 3:920cc6573be0 168 LCD.locate(0, 23);
trichards1138 3:920cc6573be0 169 LCD.printf(" ");
trichards1138 1:e31325194990 170 while(!OnOff) { // thread loop
trichards1138 1:e31325194990 171 Aout.write(pot2.read()); // scale the height of wave
trichards1138 3:920cc6573be0 172 if( current != pot2.read() ) {
trichards1138 3:920cc6573be0 173 current = pot2.read();
trichards1138 3:920cc6573be0 174 LCD.locate(0, 13);
trichards1138 3:920cc6573be0 175 LCD.printf("DC Volts: %f V", current*3.3);
trichards1138 3:920cc6573be0 176 }
trichards1138 3:920cc6573be0 177 wait_ms(2);
trichards1138 0:dfc39b05ea05 178 }
trichards1138 3:920cc6573be0 179 while( OnOff )
trichards1138 3:920cc6573be0 180 first = true;
trichards1138 0:dfc39b05ea05 181 }
trichards1138 1:e31325194990 182
trichards1138 3:920cc6573be0 183 // SawTooth - called if the user selects sawTooth. Sends the
trichards1138 3:920cc6573be0 184 // saw tooth waveform out to the Aout pin.
trichards1138 3:920cc6573be0 185 // The up and down buttons of the joystick control the amplitude
trichards1138 3:920cc6573be0 186 // The right and left buttons control the period
trichards1138 1:e31325194990 187 void sawTooth(void)
trichards1138 0:dfc39b05ea05 188 {
trichards1138 3:920cc6573be0 189 static double height = 1.0, inc;
trichards1138 3:920cc6573be0 190 static int width = 200, i;
trichards1138 3:920cc6573be0 191 check_update( SAW, &height, &width, 1.0, 10000, true );
trichards1138 3:920cc6573be0 192 while(!OnOff) { // thread loop
trichards1138 3:920cc6573be0 193 check_update( 0, &height, &width, 1.0, 100000, false );
trichards1138 3:920cc6573be0 194 inc = height/width;
trichards1138 3:920cc6573be0 195 for( i=0; i<width; i++) {
trichards1138 3:920cc6573be0 196 Aout.write(i*inc);
trichards1138 3:920cc6573be0 197 //wait_us(1);
trichards1138 3:920cc6573be0 198 }
trichards1138 3:920cc6573be0 199 }
trichards1138 3:920cc6573be0 200 while( OnOff )
trichards1138 3:920cc6573be0 201 first = true;
trichards1138 0:dfc39b05ea05 202 }
trichards1138 3:920cc6573be0 203 // Banner - Output a welcome and select screen for
trichards1138 3:920cc6573be0 204 // the user to select the desired waveform to
trichards1138 3:920cc6573be0 205 // output.
trichards1138 3:920cc6573be0 206 // Inputs: none
trichards1138 3:920cc6573be0 207 // Outputs: none
trichards1138 3:920cc6573be0 208 void banner(void)
trichards1138 3:920cc6573be0 209 {
trichards1138 3:920cc6573be0 210 LCD.locate(0,3);
trichards1138 3:920cc6573be0 211 LCD.printf("Select Waveform: ");
trichards1138 3:920cc6573be0 212 LCD.locate(0,13);
trichards1138 3:920cc6573be0 213 LCD.printf("UP=Sawtooth, DOWN=DC");
trichards1138 3:920cc6573be0 214 LCD.locate(0,23);
trichards1138 3:920cc6573be0 215 LCD.printf("LEFT=Sine , RIGHT=Square");
trichards1138 3:920cc6573be0 216 }
trichards1138 3:920cc6573be0 217
trichards1138 3:920cc6573be0 218 // main - main entry point to program and where the
trichards1138 3:920cc6573be0 219 // user selects the desired waveform.
trichards1138 0:dfc39b05ea05 220 int main()
trichards1138 0:dfc39b05ea05 221 {
trichards1138 3:920cc6573be0 222 //booleans to select waveform
trichards1138 1:e31325194990 223 bool do_sine=false, do_saw=false;
trichards1138 3:920cc6573be0 224 bool do_dc=false, do_square=false;
trichards1138 3:920cc6573be0 225 pc.baud(19200); //debug
trichards1138 3:920cc6573be0 226 banner(); //put the selection banner on LCD
trichards1138 0:dfc39b05ea05 227 while(1) {
trichards1138 3:920cc6573be0 228 if( up ) { //is UP pressed?
trichards1138 3:920cc6573be0 229 do_saw=true; //select Sawtooth
trichards1138 3:920cc6573be0 230 do_sine=false; //ensure nothing else selected
trichards1138 1:e31325194990 231 do_dc=false;
trichards1138 1:e31325194990 232 do_square=false;
trichards1138 1:e31325194990 233 }
trichards1138 3:920cc6573be0 234 if( down ) { //is DOWN pressed?
trichards1138 1:e31325194990 235 do_saw=false;
trichards1138 1:e31325194990 236 do_sine=false;
trichards1138 3:920cc6573be0 237 do_dc=true; //user wants DC
trichards1138 1:e31325194990 238 do_square=false;
trichards1138 1:e31325194990 239 }
trichards1138 3:920cc6573be0 240 if( right ) { //is RIGHT pressed?
trichards1138 1:e31325194990 241 do_saw=false;
trichards1138 1:e31325194990 242 do_sine=false;
trichards1138 1:e31325194990 243 do_dc=false;
trichards1138 3:920cc6573be0 244 do_square=true; //user wants squarewave
trichards1138 1:e31325194990 245 }
trichards1138 3:920cc6573be0 246 if( left ) { //is LEFT pressed?
trichards1138 1:e31325194990 247 do_saw=false;
trichards1138 3:920cc6573be0 248 do_sine=true; //user wants sinewave
trichards1138 1:e31325194990 249 do_dc=false;
trichards1138 1:e31325194990 250 do_square=false;
trichards1138 1:e31325194990 251 }
trichards1138 1:e31325194990 252
trichards1138 3:920cc6573be0 253 if( OnOff && first ) { //pressing center button starts
trichards1138 3:920cc6573be0 254 while( OnOff ) //ensure we only get in here once
trichards1138 3:920cc6573be0 255 first = false; //sync signal
trichards1138 3:920cc6573be0 256 if( do_saw ) {
trichards1138 3:920cc6573be0 257 pc.printf("I'm doing saw\r\n");
trichards1138 1:e31325194990 258 sawTooth();
trichards1138 3:920cc6573be0 259 }
trichards1138 3:920cc6573be0 260 else if( do_dc ) {
trichards1138 3:920cc6573be0 261 pc.printf("I'm doing dc\r\n");
trichards1138 1:e31325194990 262 flatdc();
trichards1138 3:920cc6573be0 263 }
trichards1138 3:920cc6573be0 264 else if( do_square ) {
trichards1138 3:920cc6573be0 265 pc.printf("I'm doing square\r\n");
trichards1138 1:e31325194990 266 squareWave();
trichards1138 3:920cc6573be0 267 }
trichards1138 3:920cc6573be0 268 else if( do_sine ) {
trichards1138 3:920cc6573be0 269 pc.printf("I'm doing sine\r\n");
trichards1138 1:e31325194990 270 sineWave();
trichards1138 3:920cc6573be0 271 }
trichards1138 3:920cc6573be0 272 else {
trichards1138 3:920cc6573be0 273 pc.printf("I'm doing default (sine)\r\n");
trichards1138 1:e31325194990 274 sineWave();
trichards1138 3:920cc6573be0 275 }
trichards1138 3:920cc6573be0 276 banner(); //we came back, ask user what next
trichards1138 1:e31325194990 277 }
trichards1138 1:e31325194990 278 }
trichards1138 0:dfc39b05ea05 279 }
trichards1138 0:dfc39b05ea05 280