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

Files at this revision

API Documentation at this revision

Comitter:
bobgiesberts
Date:
Tue Apr 12 14:42:52 2016 +0000
Parent:
11:599ca9982e45
Commit message:
Solved a few problems:; - Timing (float / int problem in deepsleep mode); - Storing data (seperate function now); - Power down Pinouts when class is killed

Changed in this revision

Bob.lib Show annotated file Show diff for this revision Revisions of this file
DS1825.lib Show annotated file Show diff for this revision Revisions of this file
LDC1101.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 599ca9982e45 -r cceece4f3afb Bob.lib
--- a/Bob.lib	Wed Mar 30 12:01:01 2016 +0000
+++ b/Bob.lib	Tue Apr 12 14:42:52 2016 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/users/bobgiesberts/code/Bob/#9c3c8eb56a2b
+https://developer.mbed.org/users/bobgiesberts/code/Bob/#c2468a69aacb
diff -r 599ca9982e45 -r cceece4f3afb DS1825.lib
--- a/DS1825.lib	Wed Mar 30 12:01:01 2016 +0000
+++ b/DS1825.lib	Tue Apr 12 14:42:52 2016 +0000
@@ -1,1 +1,1 @@
-DS1825#abb33be87221
+https://developer.mbed.org/users/bobgiesberts/code/DS1825/#abb33be87221
diff -r 599ca9982e45 -r cceece4f3afb LDC1101.lib
--- a/LDC1101.lib	Wed Mar 30 12:01:01 2016 +0000
+++ b/LDC1101.lib	Tue Apr 12 14:42:52 2016 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/users/bobgiesberts/code/LDC1101/#1ef9172cd355
+https://developer.mbed.org/users/bobgiesberts/code/LDC1101/#05dd145c7997
diff -r 599ca9982e45 -r cceece4f3afb main.cpp
--- 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 @@
 
     }
 
-}
 
 
 
+}
+