Communication with LDC1101. Working version, ready for extensive calibration tests for resolution, linearity, etc.

Dependencies:   Bob DS1825 LDC1101 SDFileSystem mbed

Fork of Inductive_Sensor by Bob Giesberts

Revision:
12:cceece4f3afb
Parent:
11:599ca9982e45
--- a/main.cpp	Wed Mar 30 12:01:01 2016 +0000
+++ b/main.cpp	Tue Apr 12 14:42:52 2016 +0000
@@ -2,8 +2,7 @@
 * @file main.cpp
 * @brief This file programs the processor for the inductive force sensor
 * using the library LDC1101.h and LDC1101.cpp.
-* - Red Led: processing communication with LDC1101
-* - Green Led: processing SD card
+* - Led: processing communication with LDC1101
 *
 * Log protocol:
 * -  1 minute  at 20 Hz
@@ -25,15 +24,27 @@
 using namespace std;
 
 // SETTINGS
-bool DEBUG = false;
-float C = 120E-12;      // pF
-uint16_t INTERVAL_FIRST = 600; // 5 sec
-uint16_t INTERVAL_OFF   = 870; // 1770 = 29*60+30 sec
-uint16_t INTERVAL_ON    = 30; //   30 =       30 sec
+bool DEBUG              = false;
+float C                 = 120E-12;      // Capacitor in F
+uint16_t INTERVAL_FIRST = 600;          // First sampling time in seconds.  60:00 minutes = 600 sec
+uint16_t INTERVAL_OFF   = 870;          // Waiting interval in seconds.     14:30 minutes = 870 sec (14*60+30)
+uint16_t INTERVAL_ON    = 30;           // Sampling interval in seconds.     0:30 minutes =  30 sec
+
+// Correct pinnames
+// PinName _LEDpin = PTB0;     // For the first sensor (a bright red led)
+// PinName _Tpin = PTB1;       // For the first sensor 
+PinName _LEDpin = PTB1;     // For all other sensors (a faint green led)
+PinName _Tpin = PTB0;       // For all other sensors
+
 
 // load libraries
-Bob bob(PTB0, PTB1, PTC3, PTE0, PTC2, PTE30); // red led, green led, sd_enable, sd_present, batt, 3V3_DET
-Serial pc(USBTX, USBRX);
+Bob bob( _LEDpin, // LED
+            PTC3, // sd_enable
+            PTE0, // sd_present
+            PTC2, // battery
+            PTE30 // 3V3_DET        TODO: can we use this to detect if we're charging the battery? If so, how should we respond?
+            );
+// Serial pc(USBTX, USBRX);
 
 // timer variables
 uint32_t now = 0, next = 0, prev = 0;
@@ -41,6 +52,7 @@
 uint32_t t_lost = 0, lost_prev = 0;
 uint8_t lost_high = 0;
 uint32_t t_sleep = 0;
+uint32_t t;
 
 // file variables
 FILE *fp;
@@ -48,43 +60,52 @@
 const char *fn;
 
 // temperature variables
-PinName _Tpin = PTB1;      // Thermometer is connected to the original pin for the RED / GREEN LED
 uint8_t Tdata[9];
 int16_t T_bin;
 float T;
 
 // temporal storage for data samples
-const uint8_t package_size = 16;     // Write is per 512 bits: 16 * 32 = 512
-uint32_t tarray[package_size];
-uint32_t t;
-uint32_t Larray[package_size];
-float batt;
+const uint8_t package_size = 60;    // ±12-13 Hz, so 60 would take about 5 sec.
+struct mydata {
+    uint32_t    t[package_size];    // time (s)
+    uint32_t    L[package_size];    // LHR_DATA
+} collected;
+uint8_t counter = 0;
+
+// function to write all data to the SD card
+void storeit( float T )
+{   
+    // write data to SD card
+    bob.ledon();
+    fp = fopen( fn, "a" );      // open file (append)
+    for( int i = 0; i < counter; i++ )
+       fprintf( fp, "%.2f;%d;%.4f;%.4f\r\n", (float) collected.t[i]/100.0, collected.L[i], bob.battery(), T ); // write to file
+    fclose( fp );               // close file
+    bob.ledoff();
+                 
+    // pc.printf( "%d points: %.2f;%d;%.4f;%.4f\r\n", counter, (float) collected.t[0]/100.0, collected.L[0], bob.battery(), T );
+                    
+    // Reset data
+    memset(collected.t, 0, counter);
+    memset(collected.L, 0, counter);
+    counter = 0;    
+}
 
 int main(void)
 {
-    if( DEBUG )
-    {
-        LDC1101 *ldc = new LDC1101(PTC6, PTC7, PTC5, PTC4, C, 16E6);
-        DS1825 *thermometer = new DS1825( _Tpin );
-        wait(1);
-        while(1)
-        {
-            while( !ldc->is_New_LHR_data() ) { } // wait until data is ready
-            
-            // T = thermometer->getTemperature();                      
-            pc.printf( "%d", ldc->get_LHR_Data() );
-            //pc.printf( "%.3f MHz", ldc->get_fsensor()/1000000 );
-            pc.printf( "\r\n" );
-            wait( 1 ); // 20 Hz
-        }
-    }
-
-    // Provide some feedback, is it working?
-    //bob.flash(2);
-
     // Load SD File system
+    // - the Raspberry Pie SD cards give a warning here that might just be ignored:
+    //      "Not in idle state after sending CMD8 (not an SD card?)
+    //       Didn't get a response from the disk
+    //       Set 512-byte block timed out"
+    // TODO: buy 'better' SD cards from IAPC / the Stores (Kingston ...)
     bob.wakeup();
-    SDFileSystem *sd = new SDFileSystem(PTD6, PTD7, PTD5, PTD4, "sd");
+    SDFileSystem *sd = new SDFileSystem(PTD6, // mosi
+                                        PTD7, // miso
+                                        PTD5, // sclk
+                                        PTD4, // cs
+                                        "sd"
+                                        );
 
     // Create a new data file (data00.txt)
     mkdir("/sd", 0777);
@@ -102,7 +123,7 @@
                 fclose( fp );
                 break;
             } else {
-                bob.red();
+                bob.ledon();  // error: unable to create new file
             }
         } else { // file already exists
             fclose( fp );
@@ -110,15 +131,14 @@
     }
     if( fp == NULL )
     {
-        pc.printf( "/sd/data00.txt t/m /sd/data99.txt already exist!\n" );
+        bob.ledon();  // error: file 00 - 99 already exists
+        // pc.printf( "/sd/data00.txt t/m /sd/data99.txt already exist!\n" );
     }
 
     // Unload SD File system
     delete sd;
     sd = NULL;
-
-
-
+   
     while(1)
     {
         // Wakeup: SD + LDC1101 on
@@ -132,12 +152,24 @@
         t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;  // 0 -> 219 901 952 --> (2 199 019,52 s)    (25 days)
         
         // load libraries to take control over the communication        
-        LDC1101 *ldc = new LDC1101(PTC6, PTC7, PTC5, PTC4, C, 16E6);        // load sensor (LDC1101) library (this takes 0.81 s)
+        LDC1101 *ldc = new LDC1101( PTC6,   // mosi
+                                    PTC7,   // miso
+                                    PTC5,   // sck
+                                    PTC4,   // cs
+                                    C,      // capacitor
+                                    16E6    // f_CLKIN
+                                    );      // load sensor (LDC1101) library (this takes 0.81 s)
         DS1825 *thermometer = new DS1825( _Tpin );                          // load thermometer (DS1825) library
-        SDFileSystem *sd = new SDFileSystem(PTD6, PTD7, PTD5, PTD4, "sd");  // load SD system on
+        SDFileSystem *sd = new SDFileSystem(PTD6, // mosi
+                                            PTD7, // miso
+                                            PTD5, // sclk
+                                            PTD4, // cs
+                                            "sd"
+                                            );  // load SD system on
             mkdir("/sd", 0777); // select folder
 
-        // first time take a comfortably long period
+
+        // How long should we takes samples?
         if( next == 0 )
         {
             next = t + INTERVAL_FIRST*100;
@@ -148,71 +180,47 @@
         // Take samples for INTERVAL_ON seconds
         while( t < next )
         {
-                           
-            // Collect a package of data points
-            int i = 0; 
-            while( i < package_size )
-            {
-                // wait for new data to be ready
-                while( !ldc->is_New_LHR_data() ) { }
+            // wait for new data to be ready
+            while( !ldc->is_New_LHR_data() ) { }
 
-                // what time is it now?
-                prev = now;
-                now = (uint32_t) clock();
-                if( now < prev ) 
-                    t_high++;
-                t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;
+            // what time is it now?
+            prev = now;
+            now = (uint32_t) clock();
+            if( now < prev ) 
+                t_high++;
+            t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;
 
-                if( !ldc->is_Oscillation_Error() ) // sensor not overloaded, this happends when the target is too close to the coil
-                {
-                    // Store data in temporal memory
-                    tarray[i] = t;
-                    Larray[i] = ldc->get_LHR_Data();
-                    i++;
-                }
+            if( !ldc->is_Oscillation_Error() ) // sensor overloaded, this happends when the target is too close to the coil
+            {
+                // Store data in temporal memory
+                collected.t[counter] = t;
+                collected.L[counter] = ldc->get_LHR_Data();
+                counter++;
             }
    
-            // get battery level
-            batt = bob.battery();
-           
-            // get temperature
-            T = thermometer->getTemperature();           
-
-            // Store the package of data points
-            // TODO: create a queue with all the data (t, L, Vbatt, T)          --> (Queue<data> queue)
-            // TODO: process this data in packages of 16 in a seperate Thread   --> (RTOS?)
-            bob.red();
-            fp = fopen( fn, "a" );      // open file (append)
-            for( int i = 0; i < package_size; i++ )
-               fprintf( fp, "%.2f;%d;%.4f;%.4f\r\n", (float) tarray[i]/100.0, Larray[i], batt, T ); // write to file
-            fclose( fp );               // close file
-            bob.redoff();
-            
-            
-            
-            // Print to PC for debugging
-            pc.printf( "%.2f;%d;%.4f;%.4f\r\n", (float) tarray[0]/100.0, Larray[0], batt, T ); // write to console
-            
-            // Reset data
-            memset(tarray, 0, package_size);
-            memset(Larray, 0, package_size);
-
-            // if the battery is almost empty (Vbatt < 3.10 V), the termometer stops 
-            // working well and L can not be corrected. So just shut down
-            if( batt < 3.10f )
-            {
-                bob.red();
-                exit(0);
-            }
-            
+            // Write a full package of data points to the SD card
+            if( counter >= package_size-1  )
+                storeit( thermometer->getTemperature() );
         }
+        
+        // Write remaining data to the SD card
+        if( counter > 0 )
+            storeit( thermometer->getTemperature() );
 
         // prepare for sleep, power down the SD and the LDC1101
-        delete sd;          sd  = NULL;
-        delete ldc;         ldc = NULL;
-        delete thermometer; thermometer = NULL;
-        bob.greenoff();                             // in current system the thermometer is connected to the old green led. Turning it off might power it down? Well 1,1V remains. So this doesn't work as expected
+        delete sd;          sd  = NULL;             // unload library to be able to power down completely
+        delete ldc;         ldc = NULL;             // unload library to be able to power down completely
+        delete thermometer; thermometer = NULL;     // unload library to be able to power down completely
         bob.beforesleep();
+        
+        // if the battery is almost empty (Vbatt < 3.10 V), the termometer stops 
+        // working well and L can not be corrected. So just shut down...
+        if( bob.battery() < 3.10f )
+        {
+            bob.ledon();  // error: battery empty
+            // pc.printf( "Battery empty (%.1f V), shutting down.\n", bob.battery() );
+            exit(0);
+        }
 
         // what time is it now?
         prev = now;
@@ -222,10 +230,10 @@
         t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;
 
         // Calculate sleeping time (correction to INTERVAL_OFF)
-        // S has passed the limit of next. Those few ms should be substracted from INTERVAL_OFF.
+        // t has passed the limit of next. Those few ms are substracted from INTERVAL_OFF.
         t_sleep = INTERVAL_OFF*100 - (t - next);
 
-        // Add lost time to the counter
+        // Calculate time that will be lost during sleep
         lost_prev = t_lost;
         t_lost += t_sleep;
         if( t_lost < lost_prev ) 
@@ -236,7 +244,8 @@
 
     }
 
-}
 
 
 
+}
+