Proposed solution to lab 3

main.cpp

Committer:
WilliamMarshQMUL
Date:
2019-01-31
Revision:
3:f5d7fddeef39
Parent:
1:126dd2f5fc2d
Child:
4:ebd00f94455a

File content as of revision 3:f5d7fddeef39:


// LAB 3 SAMPLE PROGRAM 1
//   Revised for mbed 5 

#include "mbed.h"


Ticker tick;                // Ticker for reading analog
AnalogIn ain(A0) ;          // Analog input
DigitalOut led1(LED_RED);   // Red LED
DigitalOut led2(LED_BLUE);   // BLUE LED

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

// Variable for a second thread
Thread ADCthread;

// 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
// Low pass filter  
// Every 10th value is sent to mailbox
void readA0() {
    int samples = 0 ;
    uint16_t smoothed = 0 ; 
    while (true) {
        wait(0.01) ; // every 10 ms
        led2 = 1 ;
        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) ;
}

// Main program
//   Initialise variables
//   Attach ISR for ticker
//   Procss messages from mailbox    
int main() {
    led1 = 1 ; // turn off 
    int volts = 0 ;
    const int threshold = 100 ;
    int counter = 0 ;
    char vstring[] = "X.XX\r\n" ;
    
    // start the ADC reading thread
    ADCthread.start(callback(readA0));

    while (true) {
        osEvent evt = mailbox.get(); // wait for mail 
        if (evt.status == osEventMail) {
            message_t* mess = (message_t*)evt.value.p ;
            volts = (mess->analog * 330) / 0xffff ;
            mailbox.free(mess) ;  // free the message space
            if (volts > threshold) led1 = 0 ; else led1 = 1 ;
            vToString(volts, vstring) ;
            counter++ ;
            if (counter == 10) {  // limit bandwidth of serial
                pc.printf(vstring) ;
                counter = 0 ;
            }
        }

    }
}