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

Files at this revision

API Documentation at this revision

Comitter:
natgovor
Date:
Fri Feb 09 16:35:47 2018 +0000
Parent:
2:e27fd3b65155
Commit message:
Digital to analog conversion. Reads analog signal (voltage) and depending on it, sets the frequency to produce the analog output for sine wave.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r e27fd3b65155 -r ac3412621bf9 main.cpp
--- 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) ;
     }
 }