Digital To Analogue Converter

Fork of ADCandticker_sample by William Marsh

Files at this revision

API Documentation at this revision

Comitter:
novinfard
Date:
Fri Feb 09 15:57:42 2018 +0000
Parent:
1:126dd2f5fc2d
Commit message:
Initial Commit

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
sineTable.h Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Wed Jan 24 21:55:43 2018 +0000
+++ b/main.cpp	Fri Feb 09 15:57:42 2018 +0000
@@ -3,29 +3,82 @@
 //   Revised for mbed 5
 
 #include "mbed.h"
+#include "sineTable.h"
+
 
 
 Ticker tick;                // Ticker for reading analog
 AnalogIn ain(A0) ;          // Analog input
-DigitalOut led1(LED_RED);   // Red LED
+DigitalOut led1(PTA12);
+DigitalOut led2(PTA4);
+DigitalOut led3(PTA5);
+DigitalOut led4(PTC8);
+DigitalOut led5(PTC9);
+Serial pc(USBTX, USBRX); // tx, rx, for debugging
+
+DigitalIn b1(PTD0, PullUp);
+
+volatile int pressEvent = 0 ;  // Variabe set by the polling thread
+
+AnalogOut ao(PTE30) ;  // Analog output
+
+// 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 ;   
+}
 
-Serial pc(USBTX, USBRX); // tx, rx, for debugging
+enum buttonPos { up, down, bounce }; // Button positions
+void polling()
+{
+    buttonPos pos = up ;
+    int bcounter = 0 ;
+
+    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 ;
+
+    }
+}
 
 // Message type
 typedef struct {
-  uint16_t analog; /* Analog input value */
+    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  
+// Low pass filter
 // Every 10th value is sent to mailbox
 volatile int samples = 0 ;
-volatile uint16_t smoothed = 0 ; 
-void readA0() {
-    smoothed = (smoothed >> 1) + (ain.read_u16() >> 1) ;
+volatile uint16_t smoothed = 0 ;
+void readA0()
+{
+    polling();
+    smoothed = (smoothed >> 1) + (ain.read_u16() >> 1) ; // divided by 2 - reduce the signal noise
     samples++ ;
     if (samples == 10) {
         // send to thread
@@ -35,12 +88,13 @@
             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) {    
+void vToString(int v, char* s)
+{
     s[3] = '0' + (v % 10) ;
     v = v / 10 ;
     s[2] = '0' + (v % 10) ;
@@ -51,24 +105,94 @@
 // Main program
 //   Initialise variables
 //   Attach ISR for ticker
-//   Procss messages from mailbox    
-int main() {
-    led1 = 1 ; // turn off 
+//   Procss messages from mailbox
+int main()
+{
+    led1 = 1 ; // turn off
     int volts = 0 ;
-    const int threshold = 100 ;
+    int threshold = 100 ; // 1 vol
     int counter = 0 ;
     char vstring[] = "X.XX\r\n" ;
+    
+    int update_us = 1000 ; // 1ms
 
-    tick.attach_us(callback(&readA0), 10000); // ticks every 10ms
+    tick.attach_us(callback(&readA0), 10000); // ticks every 10ms -> 10000 micro second
+
+
     while (true) {
-        osEvent evt = mailbox.get(); // wait for mail 
+        
+
+        
+        osEvent evt = mailbox.get(); // wait for mail
+
+        if (pressEvent) {
+            pressEvent = 0 ; // clear the event variable
+            threshold = volts;
+
+        }
+
+        // every 100 ms this loop operates
         if (evt.status == osEventMail) {
             message_t* mess = (message_t*)evt.value.p ;
-            volts = (mess->analog * 330) / 0xffff ;
+            volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16
             mailbox.free(mess) ;  // free the message space
-            if (volts > threshold) led1 = 0 ; else led1 = 1 ;
+
+            int f = (1+49*volts/threshold);
+            if(f<1)
+                f =1;
+            else if(f>50)
+                f=50;
+            
+            update_us = 1/(64*f);
+            tick.attach_us(callback(&writeAout), update_us); // setup ticker to write to AnalogOut
+            
+            
+            if(volts < (threshold / 6)) {
+                led1 = 1;
+                led2 = 1;
+                led3 = 1;
+                led4 = 1;
+                led5 = 1;
+            }
+            if((volts > (threshold * 1/ 6))&&(volts < (threshold * 2/ 6))) {
+                led1 = 0;
+                led2 = 1;
+                led3 = 1;
+                led4 = 1;
+                led5 = 1;
+            }
+            if((volts > (threshold * 2/ 6))&&(volts < (threshold * 3/ 6))) {
+                led1 = 0;
+                led2 = 0;
+                led3 = 1;
+                led4 = 1;
+                led5 = 1;
+            }
+            if((volts > (threshold * 3/ 6))&&(volts < (threshold * 4/ 6))) {
+                led1 = 0;
+                led2 = 0;
+                led3 = 0;
+                led4 = 1;
+                led5 = 1;
+            }
+            if((volts > (threshold * 4/ 6))&&(volts < (threshold * 5/ 6))) {
+                led1 = 0;
+                led2 = 0;
+                led3 = 0;
+                led4 = 0;
+                led5 = 1;
+            }
+            if(volts > (threshold * 5/ 6)) {
+                led1 = 0;
+                led2 = 0;
+                led3 = 0;
+                led4 = 0;
+                led5 = 0;
+            }
             vToString(volts, vstring) ;
             counter++ ;
+
+            // every 1 s this loop will operate
             if (counter == 10) {  // limit bandwidth of serial
                 pc.printf(vstring) ;
                 counter = 0 ;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sineTable.h	Fri Feb 09 15:57:42 2018 +0000
@@ -0,0 +1,15 @@
+// Look up table for a sine wave as 16 bits
+// Note that it is possible to construct the full period from 
+//   the first quarter, but the code is more complex
+//
+// These number were calcuated using a spreadsheet 
+const uint16_t sine[] = {
+    32768, 35980, 39161, 42280, 45308, 48215, 50973, 53556, 
+    55938, 58098, 60014, 61667, 63042, 64125, 64906, 65378, 
+    65535, 65378, 64906, 64125, 63042, 61667, 60014, 58098,
+    55938, 53556, 50973, 48215, 45308, 42280, 39161, 35980,
+    32768, 29556, 26375, 23256, 20228, 17321, 14563, 11980,
+     9598,  7438,  5522,  3869,  2494,  1411,   630,   158, 
+        0,   158,   630,  1411,  2494,  3869,  5522,  7438,
+     9598, 11980, 14563, 17321, 20228, 23256, 26375, 29556
+    } ;
\ No newline at end of file