Lab 3 the ADC part with the leds

main.cpp

Committer:
anair12345
Date:
2019-02-07
Revision:
5:beff003ed7e0
Parent:
4:ebd00f94455a

File content as of revision 5:beff003ed7e0:

// LAB 3 SAMPLE PROGRAM 1
//   Revised for mbed 5 
//   Revised to replace Ticker with event queue and thread

#include "mbed.h"

AnalogIn ain(A0) ;          // Analog input

DigitalOut led0(PTA13);
DigitalOut led1(PTD5);
DigitalOut led2(PTD0);
DigitalOut led3(PTD2);
DigitalOut led4(PTD3);

DigitalIn b1(PTA1, PullUp);

//DigitalOut led1(REDLED);   // Red LED
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 */
  int button;
} 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 ; 

//Thread pollT ; 
volatile int pressEvent = 0 ;

enum buttonPos { up, down, bounce }; // Button positions

buttonPos pos = up ;
int bcounter = 0 ;

void readA0() {   
    smoothed = (smoothed >> 1) + (ain.read_u16() >> 1) ;
    samples++ ;
    
    switch (pos) {
            case up :
                if (!b1.read()) {    // now down 
                    pressEvent = 1 ;  // transition occurred
                    pos = down ;
                }
                break ;
            case down : 
                if (b1 == 1) { // no longer down
                    bcounter = 3 ; // wait four cycles
                    pos = bounce ;
                }
                break ;
            case bounce :
                if (b1 == 0) { // down again - button has bounced
                    pos = down ;   // no event
                } else if (bcounter == 0) {
                    pos = up ;     // delay passed - reset to up
                } else {
                    bcounter-- ;   // continue waiting
                }
                break ;
        }
        wait(0.03);
    
    if (samples == 10) {
        // send to thread
        message_t *mess = mailbox.alloc() ; // may fail but does not block
        if (mess) {
            mess->analog = smoothed ;
            mess->button = pressEvent ;
            mailbox.put(mess); // fails but does not block if full
            pressEvent = 0;// clear press
        }
        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() {
    led0 = 0 ; // turn off 
    led1 = 0 ;
    led2 = 0 ;
    led3 = 0 ;
    led4 = 0 ;
    
    int volts = 0 ;
    int threshold[] = {55,110,165,220,275,330} ;
    int counter = 0 ;
    char vstring[] = "X.XX\r\n" ;
    
    //pollT.start(callback(polling));
    
    // 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 
        if (evt.status == osEventMail) {
            message_t* mess = (message_t*)evt.value.p ;
            volts = (mess->analog * 330) / 0xffff ;
            int mypressEvent = mess->button;
            mailbox.free(mess) ;  // free the message space
            if(mypressEvent) {
                for(int i = 0; i<5;i++){
                    threshold[i] = (i*volts)/6;
                }// use volts to reset thresholds
            } 
            if (volts > threshold[0] ) led0 = 1 ; else led0 = 0 ;
            if (volts > threshold[1]) led1 = 1 ; else led1 = 0 ;
            if (volts > threshold[2]) led2 = 1 ; else led2 = 0 ;
            if (volts > threshold[3]) led3 = 1 ; else led3 = 0 ;
            if (volts > threshold[4]) led4 = 1 ; else led4 = 0 ;
            vToString(volts, vstring) ;
            counter++ ;
            if (counter == 10) {  // limit bandwidth of serial
                pc.printf(vstring) ;
                counter = 0 ;
            }
        }
    }
}