mangue baja 1st working logger on stm32
Dependencies: LSM6DS3 DebouncedInterrupt
main.cpp
00001 /* 00002 Data Logger implementation in STM32F103C8T6. 00003 Inputs: 00004 1x External Accelerometer and Gyroscope (LSM6DS3) 00005 x3 Analog Inputs; 00006 x2 Digital (Frequency) Inputs; 00007 In this set, it is designed for a 200Hz sample rate. 00008 All the data are saved periodically (every 0.25s) to a folder in the SD card. 00009 To read the data, use the file "read_struct2.0.c" in the folder results. 00010 00011 Implemented by Einstein "Hashtag" Gustavo(Electronics Coordinator 2019) at Mangue Baja Team, UFPE. 00012 */ 00013 00014 #include "mbed.h" 00015 #include <stdio.h> 00016 #include <errno.h> 00017 #include "SDBlockDevice.h" 00018 #include "FATFileSystem.h" 00019 #include "LSM6DS3.h" 00020 #include "DebouncedInterrupt.h" 00021 00022 #define BUFFER_SIZE 200 // Acquisition buffer 00023 #define SAVE_WHEN 50 // Number of packets to save (fail safe) 00024 #define SAMPLE_FREQ 200 // Frequency in Hz 00025 00026 /* Debug */ 00027 PwmOut signal_wave(PB_3); // Debug wave to test frequency channels 00028 00029 /* I/O */ 00030 Serial pc(PA_2, PA_3); // Debug purposes 00031 LSM6DS3 LSM6DS3(PB_9, PB_8); // Gyroscope/Accelerometer declaration (SDA,SCL) 00032 SDBlockDevice sd(PB_15, PB_14, PB_13, PB_12); // mosi, miso, sck, cs 00033 FATFileSystem fileSystem("sd"); 00034 DigitalOut warning(PA_15); // When device is ready, led is permanently OFF 00035 DigitalOut logging(PA_12); // When data is beign acquired, led is ON 00036 //InterruptIn start(PB_4,PullUp); // Press button to start/stop acquisition 00037 DebouncedInterrupt start(PB_4); 00038 InterruptIn freq_chan1(PB_5,PullUp); // Frequency channel 1 00039 InterruptIn freq_chan2(PB_6,PullUp); // Frequency channel 2 00040 AnalogIn pot0(PB_1), 00041 pot1(PB_0), 00042 pot2(PA_7); 00043 00044 /* Data structure */ 00045 typedef struct 00046 { 00047 int16_t acclsmx; 00048 int16_t acclsmy; 00049 int16_t acclsmz; 00050 int16_t anglsmx; 00051 int16_t anglsmy; 00052 int16_t anglsmz; 00053 uint16_t analog0; 00054 uint16_t analog1; 00055 uint16_t analog2; 00056 uint16_t pulses_chan1; 00057 uint16_t pulses_chan2; 00058 uint32_t time_stamp; 00059 } packet_t; 00060 00061 00062 Timer t; // Device timer 00063 Ticker acq; // Acquisition timer interrupt source 00064 CircularBuffer<packet_t, BUFFER_SIZE> buffer; // Acquisition buffer 00065 int buffer_counter = 0; // Packet currently in buffer 00066 int err; // SD library utility 00067 bool running = false; // Device status 00068 bool StorageTrigger = false; 00069 uint16_t pulse_counter1 = 0, 00070 pulse_counter2 = 0, // Frequency counter variables 00071 acc_addr = 0; // LSM6DS3 address, if not connected address is 0 and data is not stored 00072 00073 void sampleISR(); // Data acquisition ISR 00074 uint32_t count_files_in_sd(const char *fsrc); // Compute number of files in SD 00075 void freq_channel1_ISR(); // Frequency counter ISR, channel 1 00076 void freq_channel2_ISR(); // Frequency counter ISR, channel 2 00077 void toggle_logging(); // Start button ISR 00078 00079 int main() 00080 { 00081 pc.printf("\r\nDebug 1\r\n"); 00082 logging = 0; // logging led OFF 00083 int num_parts = 0, // Number of parts already saved 00084 num_files = 0, // Number of files in SD 00085 svd_pck = 0; // Number of saved packets (in current part) 00086 char name_dir[12]; // Name of current folder (new RUN) 00087 char name_file[20]; // Name of current file (partX) 00088 FILE* fp; 00089 packet_t temp; 00090 signal_wave.period_us(50); 00091 signal_wave.write(0.5f); 00092 00093 00094 /* Initialize accelerometer */ 00095 acc_addr = LSM6DS3.begin(LSM6DS3.G_SCALE_245DPS, LSM6DS3.A_SCALE_2G, \ 00096 LSM6DS3.G_ODR_208, LSM6DS3.A_ODR_208); 00097 00098 /* Wait for SD mount */ 00099 do 00100 { 00101 /* Try to mount the filesystem */ 00102 pc.printf("Mounting the filesystem... "); 00103 fflush(stdout); 00104 00105 err = fileSystem.mount(&sd); 00106 pc.printf("%s\n", (err ? "Fail :(" : "OK")); 00107 if (err) 00108 { 00109 /* Reformat if we can't mount the filesystem 00110 this should only happen on the first boot */ 00111 pc.printf("No filesystem found, formatting... "); 00112 fflush(stdout); 00113 err = fileSystem.reformat(&sd); 00114 pc.printf("%s\n", (err ? "Fail :(" : "OK")); 00115 if (err) 00116 { 00117 error("error: %s (%d)\n", strerror(-err), err); 00118 } 00119 } 00120 }while(err); 00121 00122 pc.printf("\r\nDebug 2\r\n"); 00123 00124 pc.printf("\r\nDebug 3\r\n"); 00125 00126 num_files = count_files_in_sd("/sd"); 00127 sprintf(name_dir, "%s%d", "/sd/RUN", num_files + 1); 00128 00129 pc.printf("\r\nDebug 4\r\n"); 00130 pc.printf("\r\nNum_files = %d\r\n", num_files); 00131 00132 //start.fall(&toggle_logging); // Attach start button ISR 00133 start.attach(&toggle_logging, IRQ_FALL, 500, true); 00134 00135 while(!running) // Wait button press 00136 { 00137 warning = 1; 00138 pc.printf("\r\nrunning=%d\r\n", running); // For some reason if this line is empty the code doesn't run 00139 } 00140 00141 /* Create RUN directory */ 00142 mkdir(name_dir, 0777); 00143 warning = 0; // Warning led OFF 00144 //sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts++); 00145 sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts+1); 00146 fp = fopen(name_file, "a"); // Creates first data file 00147 t.start(); // Start device timer 00148 freq_chan1.fall(&freq_channel1_ISR); 00149 freq_chan2.fall(&freq_channel2_ISR); 00150 acq.attach(&sampleISR, 1.0/SAMPLE_FREQ); // Start data acquisition 00151 logging = 1; // logging led ON 00152 00153 while(running) 00154 { 00155 if(StorageTrigger) 00156 { 00157 packet_t acq_pck; // Current data packet 00158 static uint16_t last_acq = t.read_ms(); // Time of last acquisition 00159 00160 /* Store LSM6DS3 data if it's connected */ 00161 if (acc_addr != 0) 00162 { 00163 LSM6DS3.readAccel(); // Read Accelerometer data 00164 LSM6DS3.readGyro(); // Read Gyroscope data 00165 00166 acq_pck.acclsmx = LSM6DS3.ax_raw; 00167 acq_pck.acclsmy = LSM6DS3.ay_raw; 00168 acq_pck.acclsmz = LSM6DS3.az_raw; 00169 acq_pck.anglsmx = LSM6DS3.gx_raw; 00170 acq_pck.anglsmy = LSM6DS3.gy_raw; 00171 acq_pck.anglsmz = LSM6DS3.gz_raw; 00172 } 00173 else 00174 { 00175 acq_pck.acclsmx = 0; 00176 acq_pck.acclsmy = 0; 00177 acq_pck.acclsmz = 0; 00178 acq_pck.anglsmx = 0; 00179 acq_pck.anglsmy = 0; 00180 acq_pck.anglsmz = 0; 00181 } 00182 00183 acq_pck.analog0 = pot0.read_u16(); // Read analog sensor 0 00184 acq_pck.analog1 = pot1.read_u16(); // Read analog sensor 1 00185 acq_pck.analog2 = pot2.read_u16(); // Read analog sensor 2 00186 acq_pck.pulses_chan1 = pulse_counter1; // Store frequence channel 1 00187 acq_pck.pulses_chan2 = pulse_counter2; // Store frequence channel 2 00188 acq_pck.time_stamp = t.read_ms(); // Timestamp of data acquistion 00189 00190 pulse_counter1= 0; 00191 pulse_counter2= 0; 00192 buffer.push(acq_pck); 00193 buffer_counter++; 00194 00195 StorageTrigger = false; 00196 } 00197 00198 if(buffer.full()) 00199 { 00200 fclose(fp); 00201 warning = 1; // Turn warning led ON if buffer gets full (abnormal situation) 00202 pc.putc('X'); // Debug message 00203 } 00204 else if(!buffer.empty()) 00205 { 00206 pc.putc('G'); // Debug message 00207 00208 /* Remove packet from buffer and writes it to file */ 00209 buffer.pop(temp); 00210 buffer_counter--; 00211 fwrite((void *)&temp, sizeof(packet_t), 1, fp); 00212 svd_pck++; 00213 00214 /* Create new data file 00215 (Deactivated because the code doesn't works fine doing that so many times) */ 00216 if(svd_pck == SAVE_WHEN) 00217 { 00218 //fclose(fp); 00219 //sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts++); 00220 //t2 = t.read_ms(); 00221 //fp = fopen(name_file, "w"); 00222 //printf("t2=%d\r\n",(t.read_ms()-t2)); 00223 //pc.printf("%d\r\n", buffer_counter); // Debug message 00224 svd_pck = 0; 00225 } 00226 } 00227 00228 /* Software debounce for start button 00229 if((t.read_ms() > 10) && (t.read_ms() < 1000)) 00230 { 00231 00232 start.fall(toggle_logging); 00233 }*/ 00234 } 00235 00236 /* Reset device if start button is pressed while logging */ 00237 fclose(fp); 00238 logging = 0; 00239 NVIC_SystemReset(); 00240 return 0; 00241 } 00242 00243 void sampleISR() 00244 { 00245 StorageTrigger = true; 00246 } 00247 00248 uint32_t count_files_in_sd(const char *fsrc) 00249 { 00250 DIR *d = opendir(fsrc); 00251 struct dirent *p; 00252 uint32_t counter = 0; 00253 00254 while ((p = readdir(d)) != NULL) 00255 { 00256 if(strcmp(p->d_name, ".Trash-1000")) 00257 counter++; 00258 } 00259 closedir(d); 00260 return counter; 00261 } 00262 00263 void freq_channel1_ISR() 00264 { 00265 pulse_counter1++; 00266 } 00267 00268 void freq_channel2_ISR() 00269 { 00270 pulse_counter2++; 00271 } 00272 00273 void toggle_logging() 00274 { 00275 running = !running; 00276 //start.fall(NULL); 00277 }
Generated on Wed Sep 21 2022 21:24:07 by
1.7.2