Sebastian Barrera
/
Lab3_ADC
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 } } }