mangue baja 1st working logger on stm32

Dependencies:   LSM6DS3 DebouncedInterrupt

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }