Function Generator and Oscilloscope
Dependencies: C12832_lcd DebounceIn mbed
main.cpp
- Committer:
- trichards1138
- Date:
- 2014-06-03
- Revision:
- 4:7340e7a6eb14
- Parent:
- 3:920cc6573be0
File content as of revision 4:7340e7a6eb14:
//*************************************************************** // Function Generator - main entry and sole source file for an // MBED based function generator. The program will output // waveforms sinewave, squarewave, sawtooth, and flat DC on the // MBED analog out pin (P18). The joystick buttons are used // to control the period and amplitude of the output waveforms. // This is because the pots are a little too unstable to be read // out in a tight update loop for the waveforms. The exception // is the DC output. That uses the pot as it doesn't need a tight // loop. // // Author: Terry Richards // Date: 5/29/2014 // #include "mbed.h" #include "C12832_lcd.h" //Serial output for debug //Serial pc(USBTX, USBRX); C12832_LCD LCD; AnalogIn Ain(p17); AnalogOut Aout(p18); AnalogIn pot1(p19); AnalogIn pot2(p20); DigitalIn up(p15); DigitalIn down(p12); DigitalIn left(p13); DigitalIn right(p16); BusIn joy(p15,p12,p13,p16); DigitalIn OnOff(p14); bool first = true; // check_update - checks the buttons to see if the user wants // to update either the vertical (in volts) or the horizontal // (in uS) for the currently selected waveform. It also updates // the LCD // **** The joystick is used instead of the pots because ***** // **** I found that the pots were to unstable *************** // Inputs - the vert and horiz from the calling waveform routine // Outputs - the updated vert and horiz based on the button presses // #define SINE 1 #define SQUARE 2 #define DC 3 #define SAW 4 void check_update( int type, //what type of waveform double *vert, //vertical in volts int *horiz, //horizontal in us float vertmax, //max vertical in volts int horizmax, //max horizontal in us bool init ) //put initial vert and horiz { //on LCD screen if set if( type ) { //The header is static once the waveform is chosen LCD.locate(0, 3); switch( type ) { //only done if type is set case SINE: LCD.printf("Current WaveForm: Sine "); break; case SQUARE: LCD.printf("Current WaveForm: Square "); break; case DC: LCD.printf("Current WaveForm: DC "); break; case SAW: LCD.printf("Current WaveForm: SawTooth"); } } if( up ) { //if user pushes up button if( *vert < (1.0 - 0.001) ) *vert += 0.01; //update the vertical LCD.locate(0, 23); //vert is a percentage between 0 and 1 LCD.printf("Height: %5.3f V", *vert*3.3); } if( down ) { if( *vert > 0.01 ) *vert -= 0.01; //update the vertical down LCD.locate(0, 23); LCD.printf("Height: %5.3f V", *vert*3.3); } if( right ) { //right updates the horizontal in us if( *horiz < 100 ) //fine grain if below 100 *horiz += 1; else if( *horiz < 1000 ) //little coarser *horiz += 100; else *horiz += 1000; if( *horiz > 100000 ) //most coarse *horiz = 100000; LCD.locate(0, 13); LCD.printf("PW/Period: %d uS ", *horiz); } if( left ) { //left updates horizontal down if( *horiz < 100 ) *horiz -= 1; else if( *horiz < 1000 ) *horiz -= 100; else *horiz -= 1000; if( *horiz <= 0 ) *horiz = 1; LCD.locate(0, 13); LCD.printf("PW/Period: %d uS ", *horiz); } if( init ) { //only done if bool init is true LCD.locate(0, 13); //used for initial LCD update LCD.printf("PW/Period: %d uS ", *horiz); LCD.locate(0, 23); LCD.printf("Height: %5.3f V", *vert*3.3); } } // SineWave - is initiated when the user selects sinewave output // Sends a sine wave to the Aout pin. // The up and down buttons of the joystick control the amplitude // The right and left buttons control the period void sineWave(void) { int horiz=1000; double vert=1.0, outval, i; while( OnOff ) wait_ms(10); check_update( SINE, &vert, &horiz, 1.0, 10000, true ); while(!OnOff) { // thread loop check_update( 0, &vert, &horiz, 1.0, 10000, false ); for (i=0; i<2; i=i+0.05) { outval = 0.5 + 0.5*vert*sin(i*3.14159); Aout.write(outval); // Compute the sine value, + half the range wait_us(horiz); // Controls the sine wave period } } while( OnOff ) first = true; } // squareWave - called if user selects squarewave. Sends the // square wave to the Aout pin. // The up and down buttons of the joystick control the amplitude // The right and left buttons control the period void squareWave(void) { static double height = 1.0; static int width = 20; check_update( SQUARE, &height, &width, 1.0, 10000, true ); while(!OnOff) { // thread loop check_update( 0, &height, &width, 1.0, 100000, false ); Aout.write(height); wait_us(width); Aout.write(0); wait_us(width); } while( OnOff ) first = true; } // flatdc - called if user selects dc sig // pot2 controls the height of dc signal // The check_update is not used here because the // pot does not interrupt dc operation. void flatdc(void) { float current = pot2.read(); LCD.locate(0, 3); LCD.printf("Current WaveForm: DC "); LCD.locate(0, 13); LCD.printf("DC Volts: %f V", current*3.3); LCD.locate(0, 23); LCD.printf(" "); while(!OnOff) { // thread loop Aout.write(pot2.read()); // scale the height of wave if( current != pot2.read() ) { current = pot2.read(); LCD.locate(0, 13); LCD.printf("DC Volts: %f V", current*3.3); } wait_ms(2); } while( OnOff ) first = true; } // SawTooth - called if the user selects sawTooth. Sends the // saw tooth waveform out to the Aout pin. // The up and down buttons of the joystick control the amplitude // The right and left buttons control the period void sawTooth(void) { static double height = 1.0, inc; static int width = 6000, i; inc = height/width; check_update( SAW, &height, &width, 1.0, 10000, true ); while(!OnOff) { // thread loop check_update( 0, &height, &width, 1.0, 100000, false ); inc = height/width; for( i=0; i<width; i++) { Aout.write(i*inc); //wait_us(1); } } while( OnOff ) first = true; } // Banner - Output a welcome and select screen for // the user to select the desired waveform to // output. // Inputs: none // Outputs: none void banner(void) { LCD.locate(0,3); LCD.printf("Select Waveform: "); LCD.locate(0,13); LCD.printf("UP=Sawtooth, DOWN=DC"); LCD.locate(0,23); LCD.printf("LEFT=Sine , RIGHT=Square"); } // main - main entry point to program and where the // user selects the desired waveform. int main() { //booleans to select waveform bool do_sine=false, do_saw=false; bool do_dc=false, do_square=false; //pc.baud(19200); //debug banner(); //put the selection banner on LCD while(1) { if( up ) { //is UP pressed? do_saw=true; //select Sawtooth do_sine=false; //ensure nothing else selected do_dc=false; do_square=false; } if( down ) { //is DOWN pressed? do_saw=false; do_sine=false; do_dc=true; //user wants DC do_square=false; } if( right ) { //is RIGHT pressed? do_saw=false; do_sine=false; do_dc=false; do_square=true; //user wants squarewave } if( left ) { //is LEFT pressed? do_saw=false; do_sine=true; //user wants sinewave do_dc=false; do_square=false; } if( OnOff && first ) { //pressing center button starts while( OnOff ) //ensure we only get in here once first = false; //sync signal if( do_saw ) { //pc.printf("I'm doing saw\r\n"); sawTooth(); } else if( do_dc ) { //pc.printf("I'm doing dc\r\n"); flatdc(); } else if( do_square ) { //pc.printf("I'm doing square\r\n"); squareWave(); } else if( do_sine ) { //pc.printf("I'm doing sine\r\n"); sineWave(); } else { //Default if no button pushed //pc.printf("I'm doing default (sine)\r\n"); sineWave(); } banner(); //we came back, ask user what next } } }