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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /**
00002 * @file main.cpp
00003 * @brief This file programs the processor for the inductive force sensor
00004 * using the library LDC1101.h and LDC1101.cpp.
00005 * - Led: processing communication with LDC1101
00006 *
00007 * Log protocol:
00008 * -  1 minute  at 20 Hz
00009 * - 29 minutes rest
00010 *
00011 * @author Bob Giesberts
00012 *
00013 * @date 2015-12-17
00014 */
00015 #include "mbed.h"
00016 #include "LDC1101.h"        // inductive force sensor
00017 #include "SDFileSystem.h"   // control the SD card
00018 #include "Bob.h"            // processorboard
00019 #include "DS1825.h"         // thermometer
00020 
00021 #include <iostream>
00022 #include <vector>
00023 #include <string>
00024 using namespace std;
00025 
00026 // SETTINGS
00027 bool DEBUG              = false;
00028 float C                 = 120E-12;      // Capacitor in F
00029 uint16_t INTERVAL_FIRST = 600;          // First sampling time in seconds.  60:00 minutes = 600 sec
00030 uint16_t INTERVAL_OFF   = 870;          // Waiting interval in seconds.     14:30 minutes = 870 sec (14*60+30)
00031 uint16_t INTERVAL_ON    = 30;           // Sampling interval in seconds.     0:30 minutes =  30 sec
00032 
00033 // Correct pinnames
00034 // PinName _LEDpin = PTB0;     // For the first sensor (a bright red led)
00035 // PinName _Tpin = PTB1;       // For the first sensor 
00036 PinName _LEDpin = PTB1;     // For all other sensors (a faint green led)
00037 PinName _Tpin = PTB0;       // For all other sensors
00038 
00039 
00040 // load libraries
00041 Bob bob( _LEDpin, // LED
00042             PTC3, // sd_enable
00043             PTE0, // sd_present
00044             PTC2, // battery
00045             PTE30 // 3V3_DET        TODO: can we use this to detect if we're charging the battery? If so, how should we respond?
00046             );
00047 // Serial pc(USBTX, USBRX);
00048 
00049 // timer variables
00050 uint32_t now = 0, next = 0, prev = 0;
00051 uint8_t t_high = 0;
00052 uint32_t t_lost = 0, lost_prev = 0;
00053 uint8_t lost_high = 0;
00054 uint32_t t_sleep = 0;
00055 uint32_t t;
00056 
00057 // file variables
00058 FILE *fp;
00059 string filename = "/sd/data00.txt";
00060 const char *fn;
00061 
00062 // temperature variables
00063 uint8_t Tdata[9];
00064 int16_t T_bin;
00065 float T;
00066 
00067 // temporal storage for data samples
00068 const uint8_t package_size = 60;    // ±12-13 Hz, so 60 would take about 5 sec.
00069 struct mydata {
00070     uint32_t    t[package_size];    // time (s)
00071     uint32_t    L[package_size];    // LHR_DATA
00072 } collected;
00073 uint8_t counter = 0;
00074 
00075 // function to write all data to the SD card
00076 void storeit( float T )
00077 {   
00078     // write data to SD card
00079     bob.ledon();
00080     fp = fopen( fn, "a" );      // open file (append)
00081     for( int i = 0; i < counter; i++ )
00082        fprintf( fp, "%.2f;%d;%.4f;%.4f\r\n", (float) collected.t[i]/100.0, collected.L[i], bob.battery(), T ); // write to file
00083     fclose( fp );               // close file
00084     bob.ledoff();
00085                  
00086     // pc.printf( "%d points: %.2f;%d;%.4f;%.4f\r\n", counter, (float) collected.t[0]/100.0, collected.L[0], bob.battery(), T );
00087                     
00088     // Reset data
00089     memset(collected.t, 0, counter);
00090     memset(collected.L, 0, counter);
00091     counter = 0;    
00092 }
00093 
00094 int main(void)
00095 {
00096     // Load SD File system
00097     // - the Raspberry Pie SD cards give a warning here that might just be ignored:
00098     //      "Not in idle state after sending CMD8 (not an SD card?)
00099     //       Didn't get a response from the disk
00100     //       Set 512-byte block timed out"
00101     // TODO: buy 'better' SD cards from IAPC / the Stores (Kingston ...)
00102     bob.wakeup();
00103     SDFileSystem *sd = new SDFileSystem(PTD6, // mosi
00104                                         PTD7, // miso
00105                                         PTD5, // sclk
00106                                         PTD4, // cs
00107                                         "sd"
00108                                         );
00109 
00110     // Create a new data file (data00.txt)
00111     mkdir("/sd", 0777);
00112     for(uint8_t i = 0; i < 100; i++)
00113     {
00114         filename[8] = i/10 + '0';
00115         filename[9] = i%10 + '0';
00116         fp = fopen( filename.c_str() , "r" );
00117         if( fp == NULL ) // read failed so file does not exist
00118         {
00119             fp = fopen( filename.c_str(), "w" ); // create it
00120             if( fp != NULL )
00121             {
00122                 fn = filename.c_str();
00123                 fclose( fp );
00124                 break;
00125             } else {
00126                 bob.ledon();  // error: unable to create new file
00127             }
00128         } else { // file already exists
00129             fclose( fp );
00130         }
00131     }
00132     if( fp == NULL )
00133     {
00134         bob.ledon();  // error: file 00 - 99 already exists
00135         // pc.printf( "/sd/data00.txt t/m /sd/data99.txt already exist!\n" );
00136     }
00137 
00138     // Unload SD File system
00139     delete sd;
00140     sd = NULL;
00141    
00142     while(1)
00143     {
00144         // Wakeup: SD + LDC1101 on
00145         bob.wakeup();
00146 
00147         // what time is it now?
00148         prev = now;                                                     // 0 -> 429 496     --> (4 294,96 s)        (71 min)
00149         now = (uint32_t) clock();                                       // 0 -> 429 496     --> (4 294,96 s)        (71 min)
00150         if( now < prev )
00151             t_high++;                                                   // 0 -> 255         --> (255*4 294,96 s)    (12 days)
00152         t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;  // 0 -> 219 901 952 --> (2 199 019,52 s)    (25 days)
00153         
00154         // load libraries to take control over the communication        
00155         LDC1101 *ldc = new LDC1101( PTC6,   // mosi
00156                                     PTC7,   // miso
00157                                     PTC5,   // sck
00158                                     PTC4,   // cs
00159                                     C,      // capacitor
00160                                     16E6    // f_CLKIN
00161                                     );      // load sensor (LDC1101) library (this takes 0.81 s)
00162         DS1825 *thermometer = new DS1825( _Tpin );                          // load thermometer (DS1825) library
00163         SDFileSystem *sd = new SDFileSystem(PTD6, // mosi
00164                                             PTD7, // miso
00165                                             PTD5, // sclk
00166                                             PTD4, // cs
00167                                             "sd"
00168                                             );  // load SD system on
00169             mkdir("/sd", 0777); // select folder
00170 
00171 
00172         // How long should we takes samples?
00173         if( next == 0 )
00174         {
00175             next = t + INTERVAL_FIRST*100;
00176         } else {
00177             next = t + INTERVAL_ON*100;                                 // 0 -> 219 904 952 --> (2 199 049,52 s)    (25 days)
00178         }
00179 
00180         // Take samples for INTERVAL_ON seconds
00181         while( t < next )
00182         {
00183             // wait for new data to be ready
00184             while( !ldc->is_New_LHR_data() ) { }
00185 
00186             // what time is it now?
00187             prev = now;
00188             now = (uint32_t) clock();
00189             if( now < prev ) 
00190                 t_high++;
00191             t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;
00192 
00193             if( !ldc->is_Oscillation_Error() ) // sensor overloaded, this happends when the target is too close to the coil
00194             {
00195                 // Store data in temporal memory
00196                 collected.t[counter] = t;
00197                 collected.L[counter] = ldc->get_LHR_Data();
00198                 counter++;
00199             }
00200    
00201             // Write a full package of data points to the SD card
00202             if( counter >= package_size-1  )
00203                 storeit( thermometer->getTemperature() );
00204         }
00205         
00206         // Write remaining data to the SD card
00207         if( counter > 0 )
00208             storeit( thermometer->getTemperature() );
00209 
00210         // prepare for sleep, power down the SD and the LDC1101
00211         delete sd;          sd  = NULL;             // unload library to be able to power down completely
00212         delete ldc;         ldc = NULL;             // unload library to be able to power down completely
00213         delete thermometer; thermometer = NULL;     // unload library to be able to power down completely
00214         bob.beforesleep();
00215         
00216         // if the battery is almost empty (Vbatt < 3.10 V), the termometer stops 
00217         // working well and L can not be corrected. So just shut down...
00218         if( bob.battery() < 3.10f )
00219         {
00220             bob.ledon();  // error: battery empty
00221             // pc.printf( "Battery empty (%.1f V), shutting down.\n", bob.battery() );
00222             exit(0);
00223         }
00224 
00225         // what time is it now?
00226         prev = now;
00227         now = (uint32_t) clock();
00228         if( now < prev ) 
00229             t_high++;
00230         t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;
00231 
00232         // Calculate sleeping time (correction to INTERVAL_OFF)
00233         // t has passed the limit of next. Those few ms are substracted from INTERVAL_OFF.
00234         t_sleep = INTERVAL_OFF*100 - (t - next);
00235 
00236         // Calculate time that will be lost during sleep
00237         lost_prev = t_lost;
00238         t_lost += t_sleep;
00239         if( t_lost < lost_prev ) 
00240             lost_high++;
00241 
00242         // Sleep now (ms), enter low power mode
00243         bob.sleep( t_sleep * 10 );
00244 
00245     }
00246 
00247 
00248 
00249 
00250 }
00251