Function Generator and Oscilloscope

Dependencies:   C12832_lcd DebounceIn mbed

Committer:
trichards1138
Date:
Tue Jun 03 04:33:58 2014 +0000
Revision:
4:7340e7a6eb14
Parent:
3:920cc6573be0
final final

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