Signal Generator - Square, Sine. Arbitrary with mods

Dependencies:   mbed

SigGen.cpp

Committer:
smpedi
Date:
2010-07-22
Revision:
0:e4b2af8e875a

File content as of revision 0:e4b2af8e875a:

#include "mbed.h"

#define MAXWAVEPTS 20
#define SQUARE      0
#define SINE        1
#define UP          65
#define DOWN        66
#define RIGHT       67
#define LEFT        68

AnalogOut wave(p18);
Ticker  timer;
float   wValue;
float   waveVals[MAXWAVEPTS];
float   *fpW, *fpEnd;
float   fAmp, fModAmp;
short   itype;

void init_wave(int, int);
void write_wavePt();
int DoTermIO(char);
void    ChangeRate(float);
extern float input_control();
extern void ledOut(int);

DigitalOut  oled(p8);
Serial pc(USBTX, USBRX); // tx, rx

int main() {
    float   rate, delay;
    unsigned int    idelay;
    char    c;

    fAmp = 0.606f;
    fModAmp = 0.5f;
    pc.printf("\fFrequency (Hz)? ");
    pc.scanf("%f",&rate);
    if (rate > 2000.0f) rate = 2000.0f;
    pc.printf("\n%f Hz, Got it\nSine (1) or Square? (0)",rate);
    pc.scanf("%c",&c);
    itype = c - 48;
    pc.printf("\nType is %s \n",(itype ? "Sine" : "Square"));

    delay = 1000000 / rate;                   // delay for one cycle
    delay = delay / (float)(MAXWAVEPTS - 1);  // delay per point
    idelay = (int)(delay);                    // delay in int format
    init_wave((int)MAXWAVEPTS, itype);

    pc.printf("\nrate = %f\n",rate);
    pc.printf("delay = %f\n",delay);
    pc.printf("idelay = %u micro-seconds\n",idelay);

    timer.attach_us(&write_wavePt,idelay);
    oled = 0;
    while (1) {
        switch (DoTermIO(pc.getc())) {
            case    'i':
                fModAmp *= 1.01;
                if (fModAmp > 1.0)
                   fModAmp = 1.0;
                init_wave((int)MAXWAVEPTS, itype);
                break;
            case    'd':
                fModAmp *= 0.99;
                if (fModAmp < 0.05)
                   fModAmp = 0.05;
                init_wave((int)MAXWAVEPTS, itype);
               break;
                
            case    UP:
                rate +=  1.0f;
                ChangeRate(rate);
                break;
            case    DOWN:
                rate -=  1.0f;
                ChangeRate(rate);
                break;
            case    RIGHT:
                rate += 25.0f;
                ChangeRate(rate);
                break;
            case    LEFT:
                rate -=  25.0f;
                ChangeRate(rate);
                break;
            case    -1:
                pc.printf("%c",12);
                break;
        }
    }
}

int DoTermIO(char c) {
    char    e;
    
    if (c==17)
        return(-1);
        
    if (c == 27) {      // escape sequence?
        e = pc.getc();
        if (e != 91) {
            return((int)(-1));
        }
        pc.printf("%c",c);
        return((int)(pc.getc()));
    }
    pc.putc(c);
    return((int)c);
}


void ChangeRate(float val) {
    int idelay;
    float   delay;
    
    pc.printf("\f");
    pc.printf(" FFreq = %8.0f",val);

    delay = 1000000 / val;                   // delay for one cycle
    delay = delay / (float)(MAXWAVEPTS - 1);  // delay per point
    idelay = (int)(delay);                    // delay in int format

    pc.printf("\nrate = %f\n",val);
    pc.printf("delay = %f\n",delay);
    pc.printf("idelay = %u micro-seconds\n",idelay);
    timer.detach();
    timer = Ticker();
    timer.attach_us(&write_wavePt,idelay);
}


void write_wavePt

    if (fpW >= fpEnd) {
        fpW = waveVals;
    }
    wave.write(*fpW);
}

/* load wave array with values.  Currently supports square and sine, but any
   arbitrary wave shape can be defined, as long as it is MAXWAVEPTS long
*/

void init_wave(int iNumPts, int itype) {       
    int i, iMid;
    float   fddeg, fdeg, pi;
    float   *fp;
    float   amp;

    amp = fAmp * fModAmp;
    switch (itype) {
        case    SQUARE:          // square
            iMid = iNumPts/2-1;
            fpW = waveVals;
            fp = fpW;
            for (i=0; i<iMid; i++) {
                *fp = 0.0;
                fp++;
            }
            for (i=iMid; i< iNumPts; i++) {
                *fp = amp * 2;
                fp++;
            }
            fpEnd = fp-1;
            break;

        case    SINE:          // sine
            pi = 3.1415926;
            fddeg = ((2.0f * pi) / (float)iNumPts);
            fpW = waveVals;
            fp = fpW;
            fdeg = 0;
            for (i=0; i<iNumPts; i++) {
                *fp =( amp * cos(fdeg)) + amp;
                fp++;
                fdeg += fddeg;
            }
            fpEnd = fp-1;

            break;
    }

}