Digital To Analogue Converter

Fork of ADCandticker_sample by William Marsh

Committer:
novinfard
Date:
Fri Feb 09 15:57:42 2018 +0000
Revision:
2:9e3a110b66ee
Parent:
1:126dd2f5fc2d
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WilliamMarshQMUL 0:ad3cdc525b99 1
WilliamMarshQMUL 0:ad3cdc525b99 2 // LAB 3 SAMPLE PROGRAM 1
WilliamMarshQMUL 1:126dd2f5fc2d 3 // Revised for mbed 5
WilliamMarshQMUL 0:ad3cdc525b99 4
WilliamMarshQMUL 0:ad3cdc525b99 5 #include "mbed.h"
novinfard 2:9e3a110b66ee 6 #include "sineTable.h"
novinfard 2:9e3a110b66ee 7
WilliamMarshQMUL 1:126dd2f5fc2d 8
WilliamMarshQMUL 0:ad3cdc525b99 9
WilliamMarshQMUL 0:ad3cdc525b99 10 Ticker tick; // Ticker for reading analog
WilliamMarshQMUL 0:ad3cdc525b99 11 AnalogIn ain(A0) ; // Analog input
novinfard 2:9e3a110b66ee 12 DigitalOut led1(PTA12);
novinfard 2:9e3a110b66ee 13 DigitalOut led2(PTA4);
novinfard 2:9e3a110b66ee 14 DigitalOut led3(PTA5);
novinfard 2:9e3a110b66ee 15 DigitalOut led4(PTC8);
novinfard 2:9e3a110b66ee 16 DigitalOut led5(PTC9);
novinfard 2:9e3a110b66ee 17 Serial pc(USBTX, USBRX); // tx, rx, for debugging
novinfard 2:9e3a110b66ee 18
novinfard 2:9e3a110b66ee 19 DigitalIn b1(PTD0, PullUp);
novinfard 2:9e3a110b66ee 20
novinfard 2:9e3a110b66ee 21 volatile int pressEvent = 0 ; // Variabe set by the polling thread
novinfard 2:9e3a110b66ee 22
novinfard 2:9e3a110b66ee 23 AnalogOut ao(PTE30) ; // Analog output
novinfard 2:9e3a110b66ee 24
novinfard 2:9e3a110b66ee 25 // Function called periodically
novinfard 2:9e3a110b66ee 26 // Write new value to AnalogOut
novinfard 2:9e3a110b66ee 27 volatile int index = 0 ; // index into array of sin values
novinfard 2:9e3a110b66ee 28 void writeAout() {
novinfard 2:9e3a110b66ee 29 ao.write_u16(sine[index]) ;
novinfard 2:9e3a110b66ee 30 index = (index + 1) % 64 ;
novinfard 2:9e3a110b66ee 31 }
WilliamMarshQMUL 0:ad3cdc525b99 32
novinfard 2:9e3a110b66ee 33 enum buttonPos { up, down, bounce }; // Button positions
novinfard 2:9e3a110b66ee 34 void polling()
novinfard 2:9e3a110b66ee 35 {
novinfard 2:9e3a110b66ee 36 buttonPos pos = up ;
novinfard 2:9e3a110b66ee 37 int bcounter = 0 ;
novinfard 2:9e3a110b66ee 38
novinfard 2:9e3a110b66ee 39 switch (pos) {
novinfard 2:9e3a110b66ee 40 case up :
novinfard 2:9e3a110b66ee 41 if (!b1.read()) { // now down
novinfard 2:9e3a110b66ee 42 pressEvent = 1 ; // transition occurred
novinfard 2:9e3a110b66ee 43 pos = down ;
novinfard 2:9e3a110b66ee 44 }
novinfard 2:9e3a110b66ee 45 break ;
novinfard 2:9e3a110b66ee 46 case down :
novinfard 2:9e3a110b66ee 47 if (b1 == 1) { // no longer down
novinfard 2:9e3a110b66ee 48 bcounter = 3 ; // wait four cycles
novinfard 2:9e3a110b66ee 49 pos = bounce ;
novinfard 2:9e3a110b66ee 50 }
novinfard 2:9e3a110b66ee 51 break ;
novinfard 2:9e3a110b66ee 52 case bounce :
novinfard 2:9e3a110b66ee 53 if (b1 == 0) { // down again - button has bounced
novinfard 2:9e3a110b66ee 54 pos = down ; // no event
novinfard 2:9e3a110b66ee 55 } else if (bcounter == 0) {
novinfard 2:9e3a110b66ee 56 pos = up ; // delay passed - reset to up
novinfard 2:9e3a110b66ee 57 } else {
novinfard 2:9e3a110b66ee 58 bcounter-- ; // continue waiting
novinfard 2:9e3a110b66ee 59 }
novinfard 2:9e3a110b66ee 60 break ;
novinfard 2:9e3a110b66ee 61
novinfard 2:9e3a110b66ee 62 }
novinfard 2:9e3a110b66ee 63 }
WilliamMarshQMUL 0:ad3cdc525b99 64
WilliamMarshQMUL 0:ad3cdc525b99 65 // Message type
WilliamMarshQMUL 0:ad3cdc525b99 66 typedef struct {
novinfard 2:9e3a110b66ee 67 uint16_t analog; /* Analog input value */
WilliamMarshQMUL 0:ad3cdc525b99 68 } message_t;
WilliamMarshQMUL 0:ad3cdc525b99 69
WilliamMarshQMUL 0:ad3cdc525b99 70 // Mail box
WilliamMarshQMUL 0:ad3cdc525b99 71 Mail<message_t, 2> mailbox;
WilliamMarshQMUL 0:ad3cdc525b99 72
WilliamMarshQMUL 0:ad3cdc525b99 73 // Function called every 10ms to read ADC
novinfard 2:9e3a110b66ee 74 // Low pass filter
WilliamMarshQMUL 0:ad3cdc525b99 75 // Every 10th value is sent to mailbox
WilliamMarshQMUL 0:ad3cdc525b99 76 volatile int samples = 0 ;
novinfard 2:9e3a110b66ee 77 volatile uint16_t smoothed = 0 ;
novinfard 2:9e3a110b66ee 78 void readA0()
novinfard 2:9e3a110b66ee 79 {
novinfard 2:9e3a110b66ee 80 polling();
novinfard 2:9e3a110b66ee 81 smoothed = (smoothed >> 1) + (ain.read_u16() >> 1) ; // divided by 2 - reduce the signal noise
WilliamMarshQMUL 0:ad3cdc525b99 82 samples++ ;
WilliamMarshQMUL 0:ad3cdc525b99 83 if (samples == 10) {
WilliamMarshQMUL 0:ad3cdc525b99 84 // send to thread
WilliamMarshQMUL 0:ad3cdc525b99 85 message_t *mess = mailbox.alloc() ; // may fail but does not block
WilliamMarshQMUL 0:ad3cdc525b99 86 if (mess) {
WilliamMarshQMUL 0:ad3cdc525b99 87 mess->analog = smoothed ;
WilliamMarshQMUL 0:ad3cdc525b99 88 mailbox.put(mess); // fails but does not block if full
WilliamMarshQMUL 0:ad3cdc525b99 89 }
WilliamMarshQMUL 0:ad3cdc525b99 90 samples = 0;
novinfard 2:9e3a110b66ee 91 }
WilliamMarshQMUL 0:ad3cdc525b99 92 }
WilliamMarshQMUL 0:ad3cdc525b99 93
WilliamMarshQMUL 0:ad3cdc525b99 94 // Write voltage digits
WilliamMarshQMUL 0:ad3cdc525b99 95 // v Voltage as scale int, e.g. 3.30 is 330
novinfard 2:9e3a110b66ee 96 void vToString(int v, char* s)
novinfard 2:9e3a110b66ee 97 {
WilliamMarshQMUL 0:ad3cdc525b99 98 s[3] = '0' + (v % 10) ;
WilliamMarshQMUL 0:ad3cdc525b99 99 v = v / 10 ;
WilliamMarshQMUL 0:ad3cdc525b99 100 s[2] = '0' + (v % 10) ;
WilliamMarshQMUL 0:ad3cdc525b99 101 v = v / 10 ;
WilliamMarshQMUL 0:ad3cdc525b99 102 s[0] = '0' + (v % 10) ;
WilliamMarshQMUL 0:ad3cdc525b99 103 }
WilliamMarshQMUL 0:ad3cdc525b99 104
WilliamMarshQMUL 0:ad3cdc525b99 105 // Main program
WilliamMarshQMUL 0:ad3cdc525b99 106 // Initialise variables
WilliamMarshQMUL 0:ad3cdc525b99 107 // Attach ISR for ticker
novinfard 2:9e3a110b66ee 108 // Procss messages from mailbox
novinfard 2:9e3a110b66ee 109 int main()
novinfard 2:9e3a110b66ee 110 {
novinfard 2:9e3a110b66ee 111 led1 = 1 ; // turn off
WilliamMarshQMUL 0:ad3cdc525b99 112 int volts = 0 ;
novinfard 2:9e3a110b66ee 113 int threshold = 100 ; // 1 vol
WilliamMarshQMUL 0:ad3cdc525b99 114 int counter = 0 ;
WilliamMarshQMUL 0:ad3cdc525b99 115 char vstring[] = "X.XX\r\n" ;
novinfard 2:9e3a110b66ee 116
novinfard 2:9e3a110b66ee 117 int update_us = 1000 ; // 1ms
WilliamMarshQMUL 0:ad3cdc525b99 118
novinfard 2:9e3a110b66ee 119 tick.attach_us(callback(&readA0), 10000); // ticks every 10ms -> 10000 micro second
novinfard 2:9e3a110b66ee 120
novinfard 2:9e3a110b66ee 121
WilliamMarshQMUL 0:ad3cdc525b99 122 while (true) {
novinfard 2:9e3a110b66ee 123
novinfard 2:9e3a110b66ee 124
novinfard 2:9e3a110b66ee 125
novinfard 2:9e3a110b66ee 126 osEvent evt = mailbox.get(); // wait for mail
novinfard 2:9e3a110b66ee 127
novinfard 2:9e3a110b66ee 128 if (pressEvent) {
novinfard 2:9e3a110b66ee 129 pressEvent = 0 ; // clear the event variable
novinfard 2:9e3a110b66ee 130 threshold = volts;
novinfard 2:9e3a110b66ee 131
novinfard 2:9e3a110b66ee 132 }
novinfard 2:9e3a110b66ee 133
novinfard 2:9e3a110b66ee 134 // every 100 ms this loop operates
WilliamMarshQMUL 0:ad3cdc525b99 135 if (evt.status == osEventMail) {
WilliamMarshQMUL 0:ad3cdc525b99 136 message_t* mess = (message_t*)evt.value.p ;
novinfard 2:9e3a110b66ee 137 volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16
WilliamMarshQMUL 0:ad3cdc525b99 138 mailbox.free(mess) ; // free the message space
novinfard 2:9e3a110b66ee 139
novinfard 2:9e3a110b66ee 140 int f = (1+49*volts/threshold);
novinfard 2:9e3a110b66ee 141 if(f<1)
novinfard 2:9e3a110b66ee 142 f =1;
novinfard 2:9e3a110b66ee 143 else if(f>50)
novinfard 2:9e3a110b66ee 144 f=50;
novinfard 2:9e3a110b66ee 145
novinfard 2:9e3a110b66ee 146 update_us = 1/(64*f);
novinfard 2:9e3a110b66ee 147 tick.attach_us(callback(&writeAout), update_us); // setup ticker to write to AnalogOut
novinfard 2:9e3a110b66ee 148
novinfard 2:9e3a110b66ee 149
novinfard 2:9e3a110b66ee 150 if(volts < (threshold / 6)) {
novinfard 2:9e3a110b66ee 151 led1 = 1;
novinfard 2:9e3a110b66ee 152 led2 = 1;
novinfard 2:9e3a110b66ee 153 led3 = 1;
novinfard 2:9e3a110b66ee 154 led4 = 1;
novinfard 2:9e3a110b66ee 155 led5 = 1;
novinfard 2:9e3a110b66ee 156 }
novinfard 2:9e3a110b66ee 157 if((volts > (threshold * 1/ 6))&&(volts < (threshold * 2/ 6))) {
novinfard 2:9e3a110b66ee 158 led1 = 0;
novinfard 2:9e3a110b66ee 159 led2 = 1;
novinfard 2:9e3a110b66ee 160 led3 = 1;
novinfard 2:9e3a110b66ee 161 led4 = 1;
novinfard 2:9e3a110b66ee 162 led5 = 1;
novinfard 2:9e3a110b66ee 163 }
novinfard 2:9e3a110b66ee 164 if((volts > (threshold * 2/ 6))&&(volts < (threshold * 3/ 6))) {
novinfard 2:9e3a110b66ee 165 led1 = 0;
novinfard 2:9e3a110b66ee 166 led2 = 0;
novinfard 2:9e3a110b66ee 167 led3 = 1;
novinfard 2:9e3a110b66ee 168 led4 = 1;
novinfard 2:9e3a110b66ee 169 led5 = 1;
novinfard 2:9e3a110b66ee 170 }
novinfard 2:9e3a110b66ee 171 if((volts > (threshold * 3/ 6))&&(volts < (threshold * 4/ 6))) {
novinfard 2:9e3a110b66ee 172 led1 = 0;
novinfard 2:9e3a110b66ee 173 led2 = 0;
novinfard 2:9e3a110b66ee 174 led3 = 0;
novinfard 2:9e3a110b66ee 175 led4 = 1;
novinfard 2:9e3a110b66ee 176 led5 = 1;
novinfard 2:9e3a110b66ee 177 }
novinfard 2:9e3a110b66ee 178 if((volts > (threshold * 4/ 6))&&(volts < (threshold * 5/ 6))) {
novinfard 2:9e3a110b66ee 179 led1 = 0;
novinfard 2:9e3a110b66ee 180 led2 = 0;
novinfard 2:9e3a110b66ee 181 led3 = 0;
novinfard 2:9e3a110b66ee 182 led4 = 0;
novinfard 2:9e3a110b66ee 183 led5 = 1;
novinfard 2:9e3a110b66ee 184 }
novinfard 2:9e3a110b66ee 185 if(volts > (threshold * 5/ 6)) {
novinfard 2:9e3a110b66ee 186 led1 = 0;
novinfard 2:9e3a110b66ee 187 led2 = 0;
novinfard 2:9e3a110b66ee 188 led3 = 0;
novinfard 2:9e3a110b66ee 189 led4 = 0;
novinfard 2:9e3a110b66ee 190 led5 = 0;
novinfard 2:9e3a110b66ee 191 }
WilliamMarshQMUL 0:ad3cdc525b99 192 vToString(volts, vstring) ;
WilliamMarshQMUL 0:ad3cdc525b99 193 counter++ ;
novinfard 2:9e3a110b66ee 194
novinfard 2:9e3a110b66ee 195 // every 1 s this loop will operate
WilliamMarshQMUL 0:ad3cdc525b99 196 if (counter == 10) { // limit bandwidth of serial
WilliamMarshQMUL 0:ad3cdc525b99 197 pc.printf(vstring) ;
WilliamMarshQMUL 0:ad3cdc525b99 198 counter = 0 ;
WilliamMarshQMUL 0:ad3cdc525b99 199 }
WilliamMarshQMUL 0:ad3cdc525b99 200 }
WilliamMarshQMUL 0:ad3cdc525b99 201
WilliamMarshQMUL 0:ad3cdc525b99 202 }
WilliamMarshQMUL 0:ad3cdc525b99 203 }