Proposed solution to lab 3

Committer:
sebbarpar
Date:
Thu Feb 27 09:47:08 2020 +0000
Revision:
6:a5841dd9e3b2
Parent:
4:ebd00f94455a
Lab 3;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WilliamMarshQMUL 0:ad3cdc525b99 1
sebbarpar 6:a5841dd9e3b2 2 // LAB 3
sebbarpar 6:a5841dd9e3b2 3 //After pressing the button, maximum voltage is set.
sebbarpar 6:a5841dd9e3b2 4 //Divided by 5(5 LEDs) and each LED assigned a threshold.
sebbarpar 6:a5841dd9e3b2 5 //LED is turned on when threshold is surpassed.
WilliamMarshQMUL 0:ad3cdc525b99 6
WilliamMarshQMUL 0:ad3cdc525b99 7 #include "mbed.h"
sebbarpar 6:a5841dd9e3b2 8 #include "sineTable.h"
WilliamMarshQMUL 1:126dd2f5fc2d 9
sebbarpar 6:a5841dd9e3b2 10 class AnalogOut_unsafe : public AnalogOut {
sebbarpar 6:a5841dd9e3b2 11 public:
sebbarpar 6:a5841dd9e3b2 12 AnalogOut_unsafe (PinName pin) : AnalogOut (pin) {}
sebbarpar 6:a5841dd9e3b2 13 protected:
sebbarpar 6:a5841dd9e3b2 14 virtual void lock() {}
sebbarpar 6:a5841dd9e3b2 15 virtual void unlock() {}
sebbarpar 6:a5841dd9e3b2 16 };
sebbarpar 6:a5841dd9e3b2 17 // --------------------------
sebbarpar 6:a5841dd9e3b2 18
sebbarpar 6:a5841dd9e3b2 19 Ticker tick ; // Creates periodic interrupt
sebbarpar 6:a5841dd9e3b2 20 AnalogOut_unsafe ao(PTE30) ; // Analog output
WilliamMarshQMUL 0:ad3cdc525b99 21
WilliamMarshQMUL 0:ad3cdc525b99 22 AnalogIn ain(A0) ; // Analog input
sebbarpar 6:a5841dd9e3b2 23 //Connected LEDs
sebbarpar 6:a5841dd9e3b2 24 DigitalOut led1(PTE1);
sebbarpar 6:a5841dd9e3b2 25 DigitalOut led2(PTE0);
sebbarpar 6:a5841dd9e3b2 26 DigitalOut led3(PTD7);
sebbarpar 6:a5841dd9e3b2 27 DigitalOut led4(PTD6);
sebbarpar 6:a5841dd9e3b2 28 DigitalOut led5(PTE31);
sebbarpar 6:a5841dd9e3b2 29 //Button to set maximum voltage
sebbarpar 6:a5841dd9e3b2 30 InterruptIn button(PTD5); //Button 1
sebbarpar 6:a5841dd9e3b2 31
WilliamMarshQMUL 4:ebd00f94455a 32 EventQueue queue; // creates an event queue, to call read ADC
WilliamMarshQMUL 0:ad3cdc525b99 33
WilliamMarshQMUL 0:ad3cdc525b99 34 Serial pc(USBTX, USBRX); // tx, rx, for debugging
WilliamMarshQMUL 0:ad3cdc525b99 35
WilliamMarshQMUL 4:ebd00f94455a 36 // This thread runs the event queue
WilliamMarshQMUL 4:ebd00f94455a 37 Thread eventThread ;
WilliamMarshQMUL 3:f5d7fddeef39 38
WilliamMarshQMUL 0:ad3cdc525b99 39 // Message type
WilliamMarshQMUL 0:ad3cdc525b99 40 typedef struct {
WilliamMarshQMUL 0:ad3cdc525b99 41 uint16_t analog; /* Analog input value */
WilliamMarshQMUL 0:ad3cdc525b99 42 } message_t;
WilliamMarshQMUL 0:ad3cdc525b99 43
WilliamMarshQMUL 0:ad3cdc525b99 44 // Mail box
WilliamMarshQMUL 0:ad3cdc525b99 45 Mail<message_t, 2> mailbox;
WilliamMarshQMUL 0:ad3cdc525b99 46
WilliamMarshQMUL 0:ad3cdc525b99 47 // Function called every 10ms to read ADC
WilliamMarshQMUL 4:ebd00f94455a 48 // Average using a low pass filter
WilliamMarshQMUL 0:ad3cdc525b99 49 // Every 10th value is sent to mailbox
WilliamMarshQMUL 4:ebd00f94455a 50 volatile int samples = 0 ;
WilliamMarshQMUL 4:ebd00f94455a 51 volatile uint16_t smoothed = 0 ;
sebbarpar 6:a5841dd9e3b2 52 volatile int buttonEvent=0;
sebbarpar 6:a5841dd9e3b2 53
sebbarpar 6:a5841dd9e3b2 54 //Interrupt to detect button switch
sebbarpar 6:a5841dd9e3b2 55 void buttonCallback(){
sebbarpar 6:a5841dd9e3b2 56 buttonEvent=1;
sebbarpar 6:a5841dd9e3b2 57 }
WilliamMarshQMUL 4:ebd00f94455a 58
WilliamMarshQMUL 0:ad3cdc525b99 59 void readA0() {
WilliamMarshQMUL 4:ebd00f94455a 60 smoothed = (smoothed >> 1) + (ain.read_u16() >> 1) ;
WilliamMarshQMUL 4:ebd00f94455a 61 samples++ ;
WilliamMarshQMUL 4:ebd00f94455a 62 if (samples == 10) {
WilliamMarshQMUL 4:ebd00f94455a 63 // send to thread
WilliamMarshQMUL 4:ebd00f94455a 64 message_t *mess = mailbox.alloc() ; // may fail but does not block
WilliamMarshQMUL 4:ebd00f94455a 65 if (mess) {
WilliamMarshQMUL 4:ebd00f94455a 66 mess->analog = smoothed ;
WilliamMarshQMUL 4:ebd00f94455a 67 mailbox.put(mess); // fails but does not block if full
WilliamMarshQMUL 0:ad3cdc525b99 68 }
WilliamMarshQMUL 4:ebd00f94455a 69 samples = 0;
WilliamMarshQMUL 4:ebd00f94455a 70 }
WilliamMarshQMUL 0:ad3cdc525b99 71 }
WilliamMarshQMUL 0:ad3cdc525b99 72
WilliamMarshQMUL 0:ad3cdc525b99 73 // Write voltage digits
WilliamMarshQMUL 0:ad3cdc525b99 74 // v Voltage as scale int, e.g. 3.30 is 330
WilliamMarshQMUL 0:ad3cdc525b99 75 void vToString(int v, char* s) {
WilliamMarshQMUL 0:ad3cdc525b99 76 s[3] = '0' + (v % 10) ;
WilliamMarshQMUL 0:ad3cdc525b99 77 v = v / 10 ;
WilliamMarshQMUL 0:ad3cdc525b99 78 s[2] = '0' + (v % 10) ;
WilliamMarshQMUL 0:ad3cdc525b99 79 v = v / 10 ;
WilliamMarshQMUL 0:ad3cdc525b99 80 s[0] = '0' + (v % 10) ;
WilliamMarshQMUL 0:ad3cdc525b99 81 }
WilliamMarshQMUL 0:ad3cdc525b99 82
sebbarpar 6:a5841dd9e3b2 83
sebbarpar 6:a5841dd9e3b2 84
sebbarpar 6:a5841dd9e3b2 85
sebbarpar 6:a5841dd9e3b2 86 // Function called periodically
sebbarpar 6:a5841dd9e3b2 87 // Write new value to AnalogOut
sebbarpar 6:a5841dd9e3b2 88 volatile int index = 0 ; // index into array of sin values
sebbarpar 6:a5841dd9e3b2 89 void writeAout() {
sebbarpar 6:a5841dd9e3b2 90 ao.write_u16(sine[index]) ;
sebbarpar 6:a5841dd9e3b2 91 index = (index + 1) % 64 ;
sebbarpar 6:a5841dd9e3b2 92 }
sebbarpar 6:a5841dd9e3b2 93
sebbarpar 6:a5841dd9e3b2 94 volatile int t=312;
sebbarpar 6:a5841dd9e3b2 95 volatile int freq=1;
sebbarpar 6:a5841dd9e3b2 96
WilliamMarshQMUL 0:ad3cdc525b99 97 // Main program
WilliamMarshQMUL 0:ad3cdc525b99 98 // Initialise variables
WilliamMarshQMUL 0:ad3cdc525b99 99 // Attach ISR for ticker
WilliamMarshQMUL 0:ad3cdc525b99 100 // Procss messages from mailbox
WilliamMarshQMUL 0:ad3cdc525b99 101 int main() {
sebbarpar 6:a5841dd9e3b2 102 led1=0 ; // turn off
sebbarpar 6:a5841dd9e3b2 103 led2=0;
sebbarpar 6:a5841dd9e3b2 104 led3=0;
sebbarpar 6:a5841dd9e3b2 105 led4=0;
sebbarpar 6:a5841dd9e3b2 106 led5=0;
WilliamMarshQMUL 0:ad3cdc525b99 107 int volts = 0 ;
sebbarpar 6:a5841dd9e3b2 108 int i=0;
sebbarpar 6:a5841dd9e3b2 109 int threshold[5]={400,400,400,400,400};
WilliamMarshQMUL 0:ad3cdc525b99 110 int counter = 0 ;
WilliamMarshQMUL 0:ad3cdc525b99 111 char vstring[] = "X.XX\r\n" ;
sebbarpar 6:a5841dd9e3b2 112 char max[] = "X.XX\r\n" ;//For debugging
sebbarpar 6:a5841dd9e3b2 113 int maxvalue=1;
sebbarpar 6:a5841dd9e3b2 114 button.fall(&buttonCallback) ;
WilliamMarshQMUL 3:f5d7fddeef39 115
WilliamMarshQMUL 4:ebd00f94455a 116 // Start the event queue
WilliamMarshQMUL 4:ebd00f94455a 117 eventThread.start(callback(&queue, &EventQueue::dispatch_forever));
WilliamMarshQMUL 4:ebd00f94455a 118 // call the readA0 function every 10ms
WilliamMarshQMUL 4:ebd00f94455a 119 queue.call_every(10, readA0) ;
sebbarpar 6:a5841dd9e3b2 120
WilliamMarshQMUL 0:ad3cdc525b99 121 while (true) {
WilliamMarshQMUL 0:ad3cdc525b99 122 osEvent evt = mailbox.get(); // wait for mail
sebbarpar 6:a5841dd9e3b2 123 tick.attach_us(callback(&writeAout), t); // setup ticker to write to AnalogOut
sebbarpar 6:a5841dd9e3b2 124 //pc.printf("%d",t); //For debugging
WilliamMarshQMUL 0:ad3cdc525b99 125 if (evt.status == osEventMail) {
WilliamMarshQMUL 0:ad3cdc525b99 126 message_t* mess = (message_t*)evt.value.p ;
sebbarpar 6:a5841dd9e3b2 127 if (buttonEvent==1){//When button is pressed establish maximum value and thresholds
sebbarpar 6:a5841dd9e3b2 128 buttonEvent=0;
sebbarpar 6:a5841dd9e3b2 129 maxvalue=(mess->analog * 330) / 0xffff;
sebbarpar 6:a5841dd9e3b2 130 for (i=1;i<=5;i++){
sebbarpar 6:a5841dd9e3b2 131 threshold[i-1]=maxvalue*i/5;//Set values for thresholds
sebbarpar 6:a5841dd9e3b2 132 }
sebbarpar 6:a5841dd9e3b2 133 }
WilliamMarshQMUL 0:ad3cdc525b99 134 volts = (mess->analog * 330) / 0xffff ;
sebbarpar 6:a5841dd9e3b2 135 //Calculate frequency to call the function to write the DAC
sebbarpar 6:a5841dd9e3b2 136 freq=1+(49*volts/maxvalue);
sebbarpar 6:a5841dd9e3b2 137 if (freq>50) freq=50;
sebbarpar 6:a5841dd9e3b2 138 t=(1000000/(freq*64));
WilliamMarshQMUL 0:ad3cdc525b99 139 mailbox.free(mess) ; // free the message space
sebbarpar 6:a5841dd9e3b2 140 //Turn on LEDs depending on the range of voltage
sebbarpar 6:a5841dd9e3b2 141 if (volts < threshold[0]) led1 = 0 ; else led1 = 1 ;
sebbarpar 6:a5841dd9e3b2 142 if (volts < threshold[1]) led2 = 0 ; else led2 = 1 ;
sebbarpar 6:a5841dd9e3b2 143 if (volts < threshold[2]) led3 = 0 ; else led3 = 1 ;
sebbarpar 6:a5841dd9e3b2 144 if (volts < threshold[3]) led4 = 0 ; else led4 = 1 ;
sebbarpar 6:a5841dd9e3b2 145 if (volts < threshold[4]) led5 = 0 ; else led5 = 1 ;
WilliamMarshQMUL 0:ad3cdc525b99 146 vToString(volts, vstring) ;
sebbarpar 6:a5841dd9e3b2 147 vToString(maxvalue, max) ;
WilliamMarshQMUL 0:ad3cdc525b99 148 counter++ ;
sebbarpar 6:a5841dd9e3b2 149 /*if (counter == 10) { // limit bandwidth of serial
sebbarpar 6:a5841dd9e3b2 150 //pc.printf(vstring) ;
sebbarpar 6:a5841dd9e3b2 151 pc.printf("%d \n",freq);
sebbarpar 6:a5841dd9e3b2 152 pc.printf("%d \n",t);
WilliamMarshQMUL 0:ad3cdc525b99 153 counter = 0 ;
sebbarpar 6:a5841dd9e3b2 154 }*/ //For debugging
WilliamMarshQMUL 0:ad3cdc525b99 155 }
WilliamMarshQMUL 0:ad3cdc525b99 156 }
WilliamMarshQMUL 0:ad3cdc525b99 157 }