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
		}
	}
}