Proposed solution to lab 3

main.cpp

Committer:
sebbarpar
Date:
2020-02-27
Revision:
6:a5841dd9e3b2
Parent:
4:ebd00f94455a

File content as of revision 6:a5841dd9e3b2:


// LAB 3 
//After pressing the button, maximum voltage is set.
//Divided by 5(5 LEDs) and each LED assigned a threshold.
//LED is turned on when threshold is surpassed.

#include "mbed.h"
#include "sineTable.h"

class AnalogOut_unsafe : public AnalogOut {
  public:
    AnalogOut_unsafe (PinName pin) : AnalogOut (pin) {} 
  protected: 
    virtual void lock() {}
    virtual void unlock() {}
};
// --------------------------

Ticker tick ;          // Creates periodic interrupt
AnalogOut_unsafe ao(PTE30) ;  // Analog output

AnalogIn ain(A0) ;          // Analog input
//Connected LEDs
DigitalOut led1(PTE1);     
DigitalOut led2(PTE0);
DigitalOut led3(PTD7);
DigitalOut led4(PTD6);
DigitalOut led5(PTE31);
//Button to set maximum voltage
InterruptIn button(PTD5); //Button 1

EventQueue queue;  // creates an event queue, to call read ADC

Serial pc(USBTX, USBRX); // tx, rx, for debugging

// This thread runs the event queue
Thread eventThread ;

// Message type
typedef struct {
  uint16_t analog; /* Analog input value */
} message_t;

// Mail box
Mail<message_t, 2> mailbox;

// Function called every 10ms to read ADC
// Average using a low pass filter  
// Every 10th value is sent to mailbox
volatile int samples = 0 ;
volatile uint16_t smoothed = 0 ; 
volatile int buttonEvent=0;

//Interrupt to detect button switch
void buttonCallback(){
    buttonEvent=1;  
}

void readA0() {
    smoothed = (smoothed >> 1) + (ain.read_u16() >> 1) ;
    samples++ ;
    if (samples == 10) {
        // send to thread
        message_t *mess = mailbox.alloc() ; // may fail but does not block
        if (mess) {
            mess->analog = smoothed ;
            mailbox.put(mess); // fails but does not block if full
        }
        samples = 0;
    }
}

// Write voltage digits
//   v  Voltage as scale int, e.g. 3.30 is 330
void vToString(int v, char* s) {    
    s[3] = '0' + (v % 10) ;
    v = v / 10 ;
    s[2] = '0' + (v % 10) ;
    v = v / 10 ;
    s[0] = '0' + (v % 10) ;
}




// Function called periodically
// Write new value to AnalogOut 
volatile int index = 0 ; // index into array of sin values
void writeAout() {
    ao.write_u16(sine[index]) ;
    index = (index + 1) % 64 ;   
}

volatile int t=312;
volatile int freq=1;

// Main program
//   Initialise variables
//   Attach ISR for ticker
//   Procss messages from mailbox    
int main() {
    led1=0 ; // turn off 
    led2=0;
    led3=0;
    led4=0;
    led5=0;
    int volts = 0 ;
    int i=0;
    int threshold[5]={400,400,400,400,400};
    int counter = 0 ;
    char vstring[] = "X.XX\r\n" ;
    char max[] = "X.XX\r\n" ;//For debugging
    int maxvalue=1;
    button.fall(&buttonCallback) ; 
    
    // Start the event queue
    eventThread.start(callback(&queue, &EventQueue::dispatch_forever));
    // call the readA0 function every 10ms 
    queue.call_every(10, readA0) ; 
    
    while (true) {
        osEvent evt = mailbox.get(); // wait for mail 
        tick.attach_us(callback(&writeAout), t); // setup ticker to write to AnalogOut
        //pc.printf("%d",t); //For debugging
        if (evt.status == osEventMail) {
            message_t* mess = (message_t*)evt.value.p ;
             if (buttonEvent==1){//When button is pressed establish maximum value and thresholds
                buttonEvent=0;
                maxvalue=(mess->analog * 330) / 0xffff;
                for (i=1;i<=5;i++){
                    threshold[i-1]=maxvalue*i/5;//Set values for thresholds
                }
            }
            volts = (mess->analog * 330) / 0xffff ;
            //Calculate frequency to call the function to write the DAC
            freq=1+(49*volts/maxvalue);
            if (freq>50) freq=50;
            t=(1000000/(freq*64));
            mailbox.free(mess) ;  // free the message space
            //Turn on LEDs depending on the range of voltage
            if (volts < threshold[0]) led1 = 0 ; else led1 = 1 ;
            if (volts < threshold[1]) led2 = 0 ; else led2 = 1 ;
            if (volts < threshold[2]) led3 = 0 ; else led3 = 1 ;
            if (volts < threshold[3]) led4 = 0 ; else led4 = 1 ;
            if (volts < threshold[4]) led5 = 0 ; else led5 = 1 ;
            vToString(volts, vstring) ;
            vToString(maxvalue, max) ;
            counter++ ;
            /*if (counter == 10) {  // limit bandwidth of serial
                //pc.printf(vstring) ;
                pc.printf("%d \n",freq);
                pc.printf("%d \n",t);
                counter = 0 ;
            }*/ //For debugging
        }
    }
}