embed simulator

Dependencies:   mbed C12832

main.cpp

Committer:
kwstasfane1
Date:
2021-04-20
Revision:
3:e3e73c36a565
Parent:
0:167e85b50250
Child:
4:ce121f9e6db5

File content as of revision 3:e3e73c36a565:

/* 
   Created by Konstantinos Fane 
   copy this code to Mbed online simulator 
   to run the designed application
*/

#include "mbed.h"
#include <string>
#include "C12832.h" 

// LCD display
C12832 lcd(p5, p7, p6, p8, p11);

//dummy measurement values
float m_freq_hz; // = 120730.546423; //*10^6 Hz
float m_t_interval_ms; //= 988.056475;

//result to be displayed
float m_result;

//variables used for frequency, period and time interval measruements
float count1 = 0.0;
float ton = 0.0;
float toff = 0.0;
float period = 0.0;

const char* range_scale [3][3] = {
    {"MHz","KHz","Hz"},
    {"ms","ms","s"},
    {"ms","ms","s"}
    };

/*  flag to hold which measurement mode to display
 *  0 = Frequency Measurement
 *  1 = Period Measurement
 *  2 = Time interval Measurement
 *  to match the index of message display arrays */
int dsp_mode = 0; 
const char* mode_msg [] = {"Frequency", "Period", "Time Interval"};

/*  flag to hold which measurement range to display
 *  0 = High Range
 *  1 = Medium Range
 *  2 = Low Range */
int dsp_range = 0;
const char* range_msg [] = {"High Resolution", "Medium Resolution", "Low Resolution"};

int dsp_time_interval = 0; //0=R-R, 1=F-F, 2=R-F, 3=F-R

//result string
const char* res[] = {""};

//Interrupt to be used in actual implementation to read the input square wave signal
//InterruptIn squareIN(p#) //# = the pin number where the actual signal would be conected to

InterruptIn squareIN(p17);

//User interface measurement mode and range selection buttons
InterruptIn mode(p12);
InterruptIn range(p15);
InterruptIn time_interval(p13);

/*For simulation purposes only, multiplier for the count1, to achieve higher simulated frequencies
InterruptIn incr_freq(p15);
InterruptIn decr_freq(p16);
float multi = 1.0;
void incr();
void decr();*/

//user defined functions to implement the user interface
void user_interface_disp();
void mode_select();
void range_select();
void time_interval_type_select();
void result_calculator();

//interrupt service routines
void counter1_isr();
void freq_calc_isr();
void start_t1_isr();
void start_t2_isr();

//Timeout task2;
Ticker tick1; //generate a tick
Ticker ui_disp; //generate the 1s interrupt, to measure frequency (direct frequency measurement)
Ticker result_calc;
Timer t1;
Timer t2;

int main()
{
    
    //ticker, where it is done periodically, timeout only does it once
    //Direct frequency measurement, measures the number of rising edges every time they occur
    //squareIN.attach_us(&counter1_isr,100);
    squareIN.rise(&start_t1_isr);
    squareIN.fall(&start_t2_isr);
    //For simulation purposes only
    //tick1.attach_us(&counter1_isr, 1); //generate a tick every 100 us = 0.0001s 1us = 100000 s (period)
    
    ui_disp.attach(&user_interface_disp, 1); //update the screen every 1 second
    result_calc.attach_us(&result_calculator,100); //calculate a new measurement result every 100us
    
    //interrupt routine for mode and range selection user input
    mode.rise(&mode_select);
    range.rise(&range_select);
    time_interval.rise(&time_interval_type_select);
    
    /*interrupt routine for multiplier increase/decrease user input
    incr_freq.rise(&incr);
    decr_freq.rise(&decr);*/
    
    //start the timer t1
    t1.start();
    
    while(1)
    {
        //user_interface_disp(); //didnt refresh properly when tested on the mbed board
        //wait(0.1);
    }
 

}

//dID NOT PROVIDE A GOOD MEASUREMENT OF TON
void start_t1_isr()
{
    period = t1.read_us();
    t1.reset();
    t2.start();
    //t2.stop();
    //toff=t2.read();
}

void start_t2_isr()
{
    //t2.start();
    ton = t2.read_us();
    t2.reset();
    //period = ton+toff;
}

//ISR to count the occurences of incoming signal rising edges
void counter1_isr()
{
    //increment counter by 1
    count1 = count1 + 1;
}

//ISR to calculate the period of incoming signal, every 1 second
void freq_calc_isr()
{
    //m_freq_hz = 1/period;
    //m_freq_hz = multi * count1;
    //count1 = 0;
}

/*simulation only
void incr()
{
    multi = multi + 1500.5;
}

void decr()
{
    multi = multi - 100.5;
    if (multi<10.5)
    {
        multi = 0.5;
    }
}*/

void user_interface_disp()
{

    //At startup just print a few things on the lcd and then enter a loop until the user does something
    lcd.cls(); //clear screen
    lcd.locate(1,1);
    lcd.printf("Mode: %s", mode_msg[dsp_mode]);
    
    //display the type of time interval measurement if the mode is selected
    if(dsp_mode ==2)
    {
        lcd.locate(90,1);
        if(dsp_time_interval == 0)
        {
            lcd.printf("(R->R)");
        }
        else if(dsp_time_interval == 1)
        {
            lcd.printf("(F->F)");
        }
        else if(dsp_time_interval == 2)
        {
            lcd.printf("(R->F)");
        }
        else if(dsp_time_interval == 3)
        {
            lcd.printf("(F->R)");
        }
        
    }
    /*else
    {
        //simulation only - to display the current multiplier
        lcd.locate(78,1);
        lcd.printf("(x%1.1f)",multi);
    }*/
    
    lcd.locate(1,10);
    lcd.printf("Range: %s", range_msg[dsp_range]);
    lcd.locate(1,20);
    //call the result calculator function
    //result_calculator();
    //print the result
    lcd.printf(*res,m_result,range_scale[dsp_mode][dsp_range]);
    
}

void time_interval_type_select()
{
    if (dsp_time_interval <3)
    {
        dsp_time_interval++;
    }
    else
    {
        dsp_time_interval = 0;
    }
}

//Interrupt service routine to handle the measurement mode selection
void mode_select()
{
    if (dsp_mode < 2)
    {
        dsp_mode++;
    }
    else
    {
        dsp_mode = 0;
    }
}

//Interrupt service routine to handle the measurement range selection
void range_select()
{
    if (dsp_range < 2)
    {
        dsp_range++;
    }
    else
    {
        dsp_range = 0;
    }
}

void result_calculator()
{
    
    //calculate period from frequency
    //float m_period_s = 1/m_freq_hz;
    float m_period_ms = period/1000;
    float m_freq_hz = 1/(m_period_ms/1000);
    m_t_interval_ms = ton/1000;
    
    if(dsp_mode == 0) //frequency measurement 
    {   
        if(dsp_range == 0) //High resolution (MHz)
        {
            m_result = m_freq_hz/1000000;
            if(m_result <= 10.001)
            {
                //assigns the decimal point precision for each range
                *res="%3.3f %s";
            }
            else
            {
                *res="Out-of-range... '>10 MHz !'";
            }
            
        }
        else if(dsp_range == 1) //medium resolution (KHz)
        {
            m_result = m_freq_hz/1000;
            if(m_result <= 100.001)
            {
                //assigns the decimal point precision for each range
                *res="%3.3f %s";
            }
            else
            {
                *res="Out-of-range... '>100 KHz !'";
            }
        }
        else //low resolution (Hz)
        {
            m_result = m_freq_hz;
            if(m_result <= 100.001)
            {
                //assigns the decimal point precision for each range
                *res="%3.3f %s";
            }
            else
            {
                *res="Out-of-range... '>100 Hz !'";
            }
            
        }
        
        /* '*res' assignment was moved inside the ifs, to that in case the current 
        nuber to be displayed is higher that acceptable upper limit, to delete 
        the displayed measurement, and show warning message*/
        
    }
    else if (dsp_mode == 1) //period measurement
    {
        if(dsp_range == 0) //High resolution (2.000 +- 0.0001 ms)
        {
            m_result = m_period_ms;
            if(m_result <= 2.0001)
            {
                //assigns the decimal point precision for each range
                *res="%1.4f %s";
            }
            else
            {
                *res="Out-of-range... '>2.000 ms !'";
            }
        }
        else if(dsp_range == 1) //medium resolution (20.00 +- 0.01 ms)
        {
            m_result = m_period_ms;
            if(m_result <= 20.01)
            {
                //assigns the decimal point precision for each range
                *res="%2.2f %s";
            }
            else
            {
                *res="Out-of-range... '>20.00 ms !'";
            }
        }
        else //low resolution (2.000 +- 0.001 s)
        {
            m_result = m_period_ms/1000;
            if(m_result <= 2.001)
            {
                //assigns the decimal point precision for each range
                *res="%1.3f %s";
            }
            else
            {
                *res="Out-of-range... '>2.000 sec'";
            }
        }
    }
    else // "(dsp_mode == 2)" time interval measurement 
    {
        if(dsp_range == 0) //High resolution (2.0000 +- 0.0001 ms)
        {
            m_result = m_t_interval_ms;
            if(m_result <= 2.0001)
            {
                //assigns the decimal point precision for each range
                *res="%1.4f %s";
            }
            else
            {
                *res="Out-of-range... '>2.000 ms !'";
            }
        }
        else if(dsp_range == 1) //medium resolution (20.00 +- 0.01 ms)
        {
            m_result = m_t_interval_ms;
            if(m_result <= 20.01)
            {
                //assigns the decimal point precision for each range
                *res="%2.2f %s";
            }
            else
            {
                *res="Out-of-range... '>20.00 ms !'";
            }
        }
        else //low resolution (2.000+-0.0001ms)
        {
            m_result = m_t_interval_ms/10e3;
            if(m_result <= 2.001)
            {
                //assigns the decimal point precision for each range
                *res="%1.3f %s";
            }
            else
            {
                *res="Out-of-range... '>2.000 sec'";
            }
        }
    }    
}

/* 
 * Implemention of the vMy_Task1(), if 4 inputs are provided, 
 * vMy_Task2 is executed.
 *
void vMy_Task1_isr()
{
    input_count = input_count + 1;
    printf("Key pressed!: %d\n", input_count);
    if(input_count == 4)
    {
        printf("4 inputs provided...\n");
        input_count = 0;
        printf("Will move onto task2\n");
        
        //call task 2 after 2 seconds to close the led, not the same as the 
        //ticker, where it is done periodically, timeout only does it once
        task2.attach(&vMy_Task2, 2.0);
        //call this to turn on the led, after it has been dictated to shut down after 2 secs
        vMy_Task2();
    }
}

void vMy_Task2()
{
     led1=!led1;
     printf("Task 2 Running… LED1 = %d\n", led1.read());
}

void vMy_Task3()
{
     led2=1;
     led3=0;
     led4=0;
     printf("Task 3 Running… LED2 = %d, LED3 = %d, LED4 = %d\n", led2.read(), led3.read(), led4.read());
     wait(0.01);

}
*/