Version 3.0: Switching to newer LDC1614 which is placed on the same PCB.
Dependencies: Bob DS1825 LDC1614 LDC1101 SDFileSystem mbed
Fork of Inductive_Sensor by
main.cpp@12:cceece4f3afb, 2016-04-12 (annotated)
- Committer:
- bobgiesberts
- Date:
- Tue Apr 12 14:42:52 2016 +0000
- Revision:
- 12:cceece4f3afb
- Parent:
- 11:599ca9982e45
- Child:
- 13:2caedc56b863
Solved a few problems:; - Timing (float / int problem in deepsleep mode); - Storing data (seperate function now); - Power down Pinouts when class is killed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bobgiesberts | 2:1a203732fc95 | 1 | /** |
bobgiesberts | 2:1a203732fc95 | 2 | * @file main.cpp |
bobgiesberts | 2:1a203732fc95 | 3 | * @brief This file programs the processor for the inductive force sensor |
bobgiesberts | 2:1a203732fc95 | 4 | * using the library LDC1101.h and LDC1101.cpp. |
bobgiesberts | 12:cceece4f3afb | 5 | * - Led: processing communication with LDC1101 |
bobgiesberts | 10:3cab80866536 | 6 | * |
bobgiesberts | 4:ae441c5727b9 | 7 | * Log protocol: |
bobgiesberts | 4:ae441c5727b9 | 8 | * - 1 minute at 20 Hz |
bobgiesberts | 4:ae441c5727b9 | 9 | * - 29 minutes rest |
bobgiesberts | 2:1a203732fc95 | 10 | * |
bobgiesberts | 2:1a203732fc95 | 11 | * @author Bob Giesberts |
bobgiesberts | 2:1a203732fc95 | 12 | * |
bobgiesberts | 2:1a203732fc95 | 13 | * @date 2015-12-17 |
bobgiesberts | 2:1a203732fc95 | 14 | */ |
bobgiesberts | 10:3cab80866536 | 15 | #include "mbed.h" |
bobgiesberts | 11:599ca9982e45 | 16 | #include "LDC1101.h" // inductive force sensor |
bobgiesberts | 11:599ca9982e45 | 17 | #include "SDFileSystem.h" // control the SD card |
bobgiesberts | 11:599ca9982e45 | 18 | #include "Bob.h" // processorboard |
bobgiesberts | 11:599ca9982e45 | 19 | #include "DS1825.h" // thermometer |
bobgiesberts | 10:3cab80866536 | 20 | |
bobgiesberts | 10:3cab80866536 | 21 | #include <iostream> |
bobgiesberts | 10:3cab80866536 | 22 | #include <vector> |
bobgiesberts | 10:3cab80866536 | 23 | #include <string> |
bobgiesberts | 10:3cab80866536 | 24 | using namespace std; |
bobgiesberts | 10:3cab80866536 | 25 | |
bobgiesberts | 5:736a81a59f3c | 26 | // SETTINGS |
bobgiesberts | 12:cceece4f3afb | 27 | bool DEBUG = false; |
bobgiesberts | 12:cceece4f3afb | 28 | float C = 120E-12; // Capacitor in F |
bobgiesberts | 12:cceece4f3afb | 29 | uint16_t INTERVAL_FIRST = 600; // First sampling time in seconds. 60:00 minutes = 600 sec |
bobgiesberts | 12:cceece4f3afb | 30 | uint16_t INTERVAL_OFF = 870; // Waiting interval in seconds. 14:30 minutes = 870 sec (14*60+30) |
bobgiesberts | 12:cceece4f3afb | 31 | uint16_t INTERVAL_ON = 30; // Sampling interval in seconds. 0:30 minutes = 30 sec |
bobgiesberts | 12:cceece4f3afb | 32 | |
bobgiesberts | 12:cceece4f3afb | 33 | // Correct pinnames |
bobgiesberts | 12:cceece4f3afb | 34 | // PinName _LEDpin = PTB0; // For the first sensor (a bright red led) |
bobgiesberts | 12:cceece4f3afb | 35 | // PinName _Tpin = PTB1; // For the first sensor |
bobgiesberts | 12:cceece4f3afb | 36 | PinName _LEDpin = PTB1; // For all other sensors (a faint green led) |
bobgiesberts | 12:cceece4f3afb | 37 | PinName _Tpin = PTB0; // For all other sensors |
bobgiesberts | 12:cceece4f3afb | 38 | |
bobgiesberts | 0:e81b68888268 | 39 | |
bobgiesberts | 5:736a81a59f3c | 40 | // load libraries |
bobgiesberts | 12:cceece4f3afb | 41 | Bob bob( _LEDpin, // LED |
bobgiesberts | 12:cceece4f3afb | 42 | PTC3, // sd_enable |
bobgiesberts | 12:cceece4f3afb | 43 | PTE0, // sd_present |
bobgiesberts | 12:cceece4f3afb | 44 | PTC2, // battery |
bobgiesberts | 12:cceece4f3afb | 45 | PTE30 // 3V3_DET TODO: can we use this to detect if we're charging the battery? If so, how should we respond? |
bobgiesberts | 12:cceece4f3afb | 46 | ); |
bobgiesberts | 12:cceece4f3afb | 47 | // Serial pc(USBTX, USBRX); |
bobgiesberts | 4:ae441c5727b9 | 48 | |
bobgiesberts | 4:ae441c5727b9 | 49 | // timer variables |
bobgiesberts | 6:ff39d60061ca | 50 | uint32_t now = 0, next = 0, prev = 0; |
bobgiesberts | 8:8cc1960467ae | 51 | uint8_t t_high = 0; |
bobgiesberts | 11:599ca9982e45 | 52 | uint32_t t_lost = 0, lost_prev = 0; |
bobgiesberts | 8:8cc1960467ae | 53 | uint8_t lost_high = 0; |
bobgiesberts | 11:599ca9982e45 | 54 | uint32_t t_sleep = 0; |
bobgiesberts | 12:cceece4f3afb | 55 | uint32_t t; |
bobgiesberts | 4:ae441c5727b9 | 56 | |
bobgiesberts | 4:ae441c5727b9 | 57 | // file variables |
bobgiesberts | 4:ae441c5727b9 | 58 | FILE *fp; |
bobgiesberts | 4:ae441c5727b9 | 59 | string filename = "/sd/data00.txt"; |
bobgiesberts | 4:ae441c5727b9 | 60 | const char *fn; |
bobgiesberts | 4:ae441c5727b9 | 61 | |
bobgiesberts | 11:599ca9982e45 | 62 | // temperature variables |
bobgiesberts | 11:599ca9982e45 | 63 | uint8_t Tdata[9]; |
bobgiesberts | 11:599ca9982e45 | 64 | int16_t T_bin; |
bobgiesberts | 11:599ca9982e45 | 65 | float T; |
bobgiesberts | 11:599ca9982e45 | 66 | |
bobgiesberts | 5:736a81a59f3c | 67 | // temporal storage for data samples |
bobgiesberts | 12:cceece4f3afb | 68 | const uint8_t package_size = 60; // ±12-13 Hz, so 60 would take about 5 sec. |
bobgiesberts | 12:cceece4f3afb | 69 | struct mydata { |
bobgiesberts | 12:cceece4f3afb | 70 | uint32_t t[package_size]; // time (s) |
bobgiesberts | 12:cceece4f3afb | 71 | uint32_t L[package_size]; // LHR_DATA |
bobgiesberts | 12:cceece4f3afb | 72 | } collected; |
bobgiesberts | 12:cceece4f3afb | 73 | uint8_t counter = 0; |
bobgiesberts | 12:cceece4f3afb | 74 | |
bobgiesberts | 12:cceece4f3afb | 75 | // function to write all data to the SD card |
bobgiesberts | 12:cceece4f3afb | 76 | void storeit( float T ) |
bobgiesberts | 12:cceece4f3afb | 77 | { |
bobgiesberts | 12:cceece4f3afb | 78 | // write data to SD card |
bobgiesberts | 12:cceece4f3afb | 79 | bob.ledon(); |
bobgiesberts | 12:cceece4f3afb | 80 | fp = fopen( fn, "a" ); // open file (append) |
bobgiesberts | 12:cceece4f3afb | 81 | for( int i = 0; i < counter; i++ ) |
bobgiesberts | 12:cceece4f3afb | 82 | fprintf( fp, "%.2f;%d;%.4f;%.4f\r\n", (float) collected.t[i]/100.0, collected.L[i], bob.battery(), T ); // write to file |
bobgiesberts | 12:cceece4f3afb | 83 | fclose( fp ); // close file |
bobgiesberts | 12:cceece4f3afb | 84 | bob.ledoff(); |
bobgiesberts | 12:cceece4f3afb | 85 | |
bobgiesberts | 12:cceece4f3afb | 86 | // pc.printf( "%d points: %.2f;%d;%.4f;%.4f\r\n", counter, (float) collected.t[0]/100.0, collected.L[0], bob.battery(), T ); |
bobgiesberts | 12:cceece4f3afb | 87 | |
bobgiesberts | 12:cceece4f3afb | 88 | // Reset data |
bobgiesberts | 12:cceece4f3afb | 89 | memset(collected.t, 0, counter); |
bobgiesberts | 12:cceece4f3afb | 90 | memset(collected.L, 0, counter); |
bobgiesberts | 12:cceece4f3afb | 91 | counter = 0; |
bobgiesberts | 12:cceece4f3afb | 92 | } |
bobgiesberts | 5:736a81a59f3c | 93 | |
bobgiesberts | 10:3cab80866536 | 94 | int main(void) |
bobgiesberts | 10:3cab80866536 | 95 | { |
bobgiesberts | 6:ff39d60061ca | 96 | // Load SD File system |
bobgiesberts | 12:cceece4f3afb | 97 | // - the Raspberry Pie SD cards give a warning here that might just be ignored: |
bobgiesberts | 12:cceece4f3afb | 98 | // "Not in idle state after sending CMD8 (not an SD card?) |
bobgiesberts | 12:cceece4f3afb | 99 | // Didn't get a response from the disk |
bobgiesberts | 12:cceece4f3afb | 100 | // Set 512-byte block timed out" |
bobgiesberts | 12:cceece4f3afb | 101 | // TODO: buy 'better' SD cards from IAPC / the Stores (Kingston ...) |
bobgiesberts | 11:599ca9982e45 | 102 | bob.wakeup(); |
bobgiesberts | 12:cceece4f3afb | 103 | SDFileSystem *sd = new SDFileSystem(PTD6, // mosi |
bobgiesberts | 12:cceece4f3afb | 104 | PTD7, // miso |
bobgiesberts | 12:cceece4f3afb | 105 | PTD5, // sclk |
bobgiesberts | 12:cceece4f3afb | 106 | PTD4, // cs |
bobgiesberts | 12:cceece4f3afb | 107 | "sd" |
bobgiesberts | 12:cceece4f3afb | 108 | ); |
bobgiesberts | 10:3cab80866536 | 109 | |
bobgiesberts | 6:ff39d60061ca | 110 | // Create a new data file (data00.txt) |
bobgiesberts | 10:3cab80866536 | 111 | mkdir("/sd", 0777); |
bobgiesberts | 11:599ca9982e45 | 112 | for(uint8_t i = 0; i < 100; i++) |
bobgiesberts | 11:599ca9982e45 | 113 | { |
bobgiesberts | 6:ff39d60061ca | 114 | filename[8] = i/10 + '0'; |
bobgiesberts | 4:ae441c5727b9 | 115 | filename[9] = i%10 + '0'; |
bobgiesberts | 4:ae441c5727b9 | 116 | fp = fopen( filename.c_str() , "r" ); |
bobgiesberts | 11:599ca9982e45 | 117 | if( fp == NULL ) // read failed so file does not exist |
bobgiesberts | 11:599ca9982e45 | 118 | { |
bobgiesberts | 4:ae441c5727b9 | 119 | fp = fopen( filename.c_str(), "w" ); // create it |
bobgiesberts | 11:599ca9982e45 | 120 | if( fp != NULL ) |
bobgiesberts | 11:599ca9982e45 | 121 | { |
bobgiesberts | 4:ae441c5727b9 | 122 | fn = filename.c_str(); |
bobgiesberts | 6:ff39d60061ca | 123 | fclose( fp ); |
bobgiesberts | 4:ae441c5727b9 | 124 | break; |
bobgiesberts | 10:3cab80866536 | 125 | } else { |
bobgiesberts | 12:cceece4f3afb | 126 | bob.ledon(); // error: unable to create new file |
bobgiesberts | 4:ae441c5727b9 | 127 | } |
bobgiesberts | 10:3cab80866536 | 128 | } else { // file already exists |
bobgiesberts | 4:ae441c5727b9 | 129 | fclose( fp ); |
bobgiesberts | 4:ae441c5727b9 | 130 | } |
bobgiesberts | 1:22c272515015 | 131 | } |
bobgiesberts | 11:599ca9982e45 | 132 | if( fp == NULL ) |
bobgiesberts | 11:599ca9982e45 | 133 | { |
bobgiesberts | 12:cceece4f3afb | 134 | bob.ledon(); // error: file 00 - 99 already exists |
bobgiesberts | 12:cceece4f3afb | 135 | // pc.printf( "/sd/data00.txt t/m /sd/data99.txt already exist!\n" ); |
bobgiesberts | 11:599ca9982e45 | 136 | } |
bobgiesberts | 10:3cab80866536 | 137 | |
bobgiesberts | 6:ff39d60061ca | 138 | // Unload SD File system |
bobgiesberts | 10:3cab80866536 | 139 | delete sd; |
bobgiesberts | 10:3cab80866536 | 140 | sd = NULL; |
bobgiesberts | 12:cceece4f3afb | 141 | |
bobgiesberts | 11:599ca9982e45 | 142 | while(1) |
bobgiesberts | 11:599ca9982e45 | 143 | { |
bobgiesberts | 11:599ca9982e45 | 144 | // Wakeup: SD + LDC1101 on |
bobgiesberts | 11:599ca9982e45 | 145 | bob.wakeup(); |
bobgiesberts | 10:3cab80866536 | 146 | |
bobgiesberts | 11:599ca9982e45 | 147 | // what time is it now? |
bobgiesberts | 8:8cc1960467ae | 148 | prev = now; // 0 -> 429 496 --> (4 294,96 s) (71 min) |
bobgiesberts | 8:8cc1960467ae | 149 | now = (uint32_t) clock(); // 0 -> 429 496 --> (4 294,96 s) (71 min) |
bobgiesberts | 11:599ca9982e45 | 150 | if( now < prev ) |
bobgiesberts | 11:599ca9982e45 | 151 | t_high++; // 0 -> 255 --> (255*4 294,96 s) (12 days) |
bobgiesberts | 11:599ca9982e45 | 152 | t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high; // 0 -> 219 901 952 --> (2 199 019,52 s) (25 days) |
bobgiesberts | 11:599ca9982e45 | 153 | |
bobgiesberts | 11:599ca9982e45 | 154 | // load libraries to take control over the communication |
bobgiesberts | 12:cceece4f3afb | 155 | LDC1101 *ldc = new LDC1101( PTC6, // mosi |
bobgiesberts | 12:cceece4f3afb | 156 | PTC7, // miso |
bobgiesberts | 12:cceece4f3afb | 157 | PTC5, // sck |
bobgiesberts | 12:cceece4f3afb | 158 | PTC4, // cs |
bobgiesberts | 12:cceece4f3afb | 159 | C, // capacitor |
bobgiesberts | 12:cceece4f3afb | 160 | 16E6 // f_CLKIN |
bobgiesberts | 12:cceece4f3afb | 161 | ); // load sensor (LDC1101) library (this takes 0.81 s) |
bobgiesberts | 11:599ca9982e45 | 162 | DS1825 *thermometer = new DS1825( _Tpin ); // load thermometer (DS1825) library |
bobgiesberts | 12:cceece4f3afb | 163 | SDFileSystem *sd = new SDFileSystem(PTD6, // mosi |
bobgiesberts | 12:cceece4f3afb | 164 | PTD7, // miso |
bobgiesberts | 12:cceece4f3afb | 165 | PTD5, // sclk |
bobgiesberts | 12:cceece4f3afb | 166 | PTD4, // cs |
bobgiesberts | 12:cceece4f3afb | 167 | "sd" |
bobgiesberts | 12:cceece4f3afb | 168 | ); // load SD system on |
bobgiesberts | 11:599ca9982e45 | 169 | mkdir("/sd", 0777); // select folder |
bobgiesberts | 10:3cab80866536 | 170 | |
bobgiesberts | 12:cceece4f3afb | 171 | |
bobgiesberts | 12:cceece4f3afb | 172 | // How long should we takes samples? |
bobgiesberts | 11:599ca9982e45 | 173 | if( next == 0 ) |
bobgiesberts | 11:599ca9982e45 | 174 | { |
bobgiesberts | 11:599ca9982e45 | 175 | next = t + INTERVAL_FIRST*100; |
bobgiesberts | 10:3cab80866536 | 176 | } else { |
bobgiesberts | 11:599ca9982e45 | 177 | next = t + INTERVAL_ON*100; // 0 -> 219 904 952 --> (2 199 049,52 s) (25 days) |
bobgiesberts | 8:8cc1960467ae | 178 | } |
bobgiesberts | 10:3cab80866536 | 179 | |
bobgiesberts | 6:ff39d60061ca | 180 | // Take samples for INTERVAL_ON seconds |
bobgiesberts | 11:599ca9982e45 | 181 | while( t < next ) |
bobgiesberts | 11:599ca9982e45 | 182 | { |
bobgiesberts | 12:cceece4f3afb | 183 | // wait for new data to be ready |
bobgiesberts | 12:cceece4f3afb | 184 | while( !ldc->is_New_LHR_data() ) { } |
bobgiesberts | 10:3cab80866536 | 185 | |
bobgiesberts | 12:cceece4f3afb | 186 | // what time is it now? |
bobgiesberts | 12:cceece4f3afb | 187 | prev = now; |
bobgiesberts | 12:cceece4f3afb | 188 | now = (uint32_t) clock(); |
bobgiesberts | 12:cceece4f3afb | 189 | if( now < prev ) |
bobgiesberts | 12:cceece4f3afb | 190 | t_high++; |
bobgiesberts | 12:cceece4f3afb | 191 | t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high; |
bobgiesberts | 10:3cab80866536 | 192 | |
bobgiesberts | 12:cceece4f3afb | 193 | if( !ldc->is_Oscillation_Error() ) // sensor overloaded, this happends when the target is too close to the coil |
bobgiesberts | 12:cceece4f3afb | 194 | { |
bobgiesberts | 12:cceece4f3afb | 195 | // Store data in temporal memory |
bobgiesberts | 12:cceece4f3afb | 196 | collected.t[counter] = t; |
bobgiesberts | 12:cceece4f3afb | 197 | collected.L[counter] = ldc->get_LHR_Data(); |
bobgiesberts | 12:cceece4f3afb | 198 | counter++; |
bobgiesberts | 6:ff39d60061ca | 199 | } |
bobgiesberts | 11:599ca9982e45 | 200 | |
bobgiesberts | 12:cceece4f3afb | 201 | // Write a full package of data points to the SD card |
bobgiesberts | 12:cceece4f3afb | 202 | if( counter >= package_size-1 ) |
bobgiesberts | 12:cceece4f3afb | 203 | storeit( thermometer->getTemperature() ); |
bobgiesberts | 10:3cab80866536 | 204 | } |
bobgiesberts | 12:cceece4f3afb | 205 | |
bobgiesberts | 12:cceece4f3afb | 206 | // Write remaining data to the SD card |
bobgiesberts | 12:cceece4f3afb | 207 | if( counter > 0 ) |
bobgiesberts | 12:cceece4f3afb | 208 | storeit( thermometer->getTemperature() ); |
bobgiesberts | 10:3cab80866536 | 209 | |
bobgiesberts | 11:599ca9982e45 | 210 | // prepare for sleep, power down the SD and the LDC1101 |
bobgiesberts | 12:cceece4f3afb | 211 | delete sd; sd = NULL; // unload library to be able to power down completely |
bobgiesberts | 12:cceece4f3afb | 212 | delete ldc; ldc = NULL; // unload library to be able to power down completely |
bobgiesberts | 12:cceece4f3afb | 213 | delete thermometer; thermometer = NULL; // unload library to be able to power down completely |
bobgiesberts | 11:599ca9982e45 | 214 | bob.beforesleep(); |
bobgiesberts | 12:cceece4f3afb | 215 | |
bobgiesberts | 12:cceece4f3afb | 216 | // if the battery is almost empty (Vbatt < 3.10 V), the termometer stops |
bobgiesberts | 12:cceece4f3afb | 217 | // working well and L can not be corrected. So just shut down... |
bobgiesberts | 12:cceece4f3afb | 218 | if( bob.battery() < 3.10f ) |
bobgiesberts | 12:cceece4f3afb | 219 | { |
bobgiesberts | 12:cceece4f3afb | 220 | bob.ledon(); // error: battery empty |
bobgiesberts | 12:cceece4f3afb | 221 | // pc.printf( "Battery empty (%.1f V), shutting down.\n", bob.battery() ); |
bobgiesberts | 12:cceece4f3afb | 222 | exit(0); |
bobgiesberts | 12:cceece4f3afb | 223 | } |
bobgiesberts | 10:3cab80866536 | 224 | |
bobgiesberts | 11:599ca9982e45 | 225 | // what time is it now? |
bobgiesberts | 11:599ca9982e45 | 226 | prev = now; |
bobgiesberts | 11:599ca9982e45 | 227 | now = (uint32_t) clock(); |
bobgiesberts | 11:599ca9982e45 | 228 | if( now < prev ) |
bobgiesberts | 11:599ca9982e45 | 229 | t_high++; |
bobgiesberts | 11:599ca9982e45 | 230 | t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high; |
bobgiesberts | 10:3cab80866536 | 231 | |
bobgiesberts | 8:8cc1960467ae | 232 | // Calculate sleeping time (correction to INTERVAL_OFF) |
bobgiesberts | 12:cceece4f3afb | 233 | // t has passed the limit of next. Those few ms are substracted from INTERVAL_OFF. |
bobgiesberts | 11:599ca9982e45 | 234 | t_sleep = INTERVAL_OFF*100 - (t - next); |
bobgiesberts | 8:8cc1960467ae | 235 | |
bobgiesberts | 12:cceece4f3afb | 236 | // Calculate time that will be lost during sleep |
bobgiesberts | 11:599ca9982e45 | 237 | lost_prev = t_lost; |
bobgiesberts | 11:599ca9982e45 | 238 | t_lost += t_sleep; |
bobgiesberts | 11:599ca9982e45 | 239 | if( t_lost < lost_prev ) |
bobgiesberts | 11:599ca9982e45 | 240 | lost_high++; |
bobgiesberts | 10:3cab80866536 | 241 | |
bobgiesberts | 11:599ca9982e45 | 242 | // Sleep now (ms), enter low power mode |
bobgiesberts | 11:599ca9982e45 | 243 | bob.sleep( t_sleep * 10 ); |
bobgiesberts | 10:3cab80866536 | 244 | |
bobgiesberts | 0:e81b68888268 | 245 | } |
bobgiesberts | 6:ff39d60061ca | 246 | |
bobgiesberts | 11:599ca9982e45 | 247 | |
bobgiesberts | 11:599ca9982e45 | 248 | |
bobgiesberts | 11:599ca9982e45 | 249 | |
bobgiesberts | 12:cceece4f3afb | 250 | } |
bobgiesberts | 12:cceece4f3afb | 251 |