Digital to analog conversion. Reads analog signal (voltage) and depending on it, sets the frequency to produce the analog output for sine wave.

Fork of DACandticker_sample by William Marsh

Revision:
3:ac3412621bf9
Parent:
2:e27fd3b65155
--- a/main.cpp	Wed Jan 24 22:56:54 2018 +0000
+++ b/main.cpp	Fri Feb 09 16:35:47 2018 +0000
@@ -11,7 +11,48 @@
 #include "sineTable.h"
 
 Ticker tick ;          // Creates periodic interrupt
+Ticker adcTick ;          // Creates periodic interrupt
 AnalogOut ao(PTE30) ;  // Analog output
+AnalogIn ain(A0) ;          // Analog input
+
+Serial pc(USBTX, USBRX); // tx, rx, for debugging
+
+// 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
+// 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) ;
+    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 
@@ -24,13 +65,41 @@
 // Control the frequency of updates
 //   Alternative between two frequencies      
 int main() {
+    int volts = 0 ;
+    int counter = 0 ;
+    char vstring[] = "X.XX\r\n" ;
     int update_us = 1000 ; // 1ms
+    int maximum_voltage = 330;
+    
+    adcTick.attach_us(callback(&readA0), 10000); // ticks every 10ms
+    int f = 0;
+    int old_update_us = update_us;
+    tick.attach_us(callback(&writeAout), update_us); // setup ticker to write to AnalogOut
+    
     while (true) {
-        tick.attach_us(callback(&writeAout), update_us); // setup ticker to write to AnalogOut
-        Thread::wait(30000) ; // wait 30 sec - 30000ms
-        update_us = 2000 ; // 2ms
-        tick.attach_us(callback(&writeAout), update_us); // setup ticker to write to AnalogOut
-        Thread::wait(30000) ; // wait 30 sec - 30000ms
-        update_us = 1000 ; // 1ms
+        osEvent evt = mailbox.get(); // wait for mail 
+        if (evt.status == osEventMail) {
+            message_t* mess = (message_t*)evt.value.p ;
+            volts = (mess->analog * 330) / 0xffff ;
+            mailbox.free(mess) ;  // free the message space         
+            
+            // change the frequency
+            f = 1 + (49 * volts / maximum_voltage);
+            update_us = 1000000 / (f * 64);       
+            
+            if (update_us != old_update_us) {
+                tick.attach_us(callback(&writeAout), update_us); // setup ticker to write to AnalogOut
+                old_update_us = update_us;
+            }
+            
+            vToString(volts, vstring) ;
+            counter++ ;
+            if (counter == 10) {  // limit bandwidth of serial
+                pc.printf(vstring) ;
+                counter = 0 ;
+            }
+        }
+        
+        Thread::wait(200) ;
     }
 }