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
Revision 12:cceece4f3afb, committed 2016-04-12
- 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
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 @@ } -} +} +