Data Logger Mangue Baja

Dependencies:   mbed

Committer:
einsteingustavo
Date:
Fri Jul 05 00:02:13 2019 +0000
Revision:
0:aef6b59caed0
Datta Logger Mangue Baja 200Hz

Who changed what in which revision?

UserRevisionLine numberNew contents of line
einsteingustavo 0:aef6b59caed0 1 /*
einsteingustavo 0:aef6b59caed0 2 Data Logger implementation in K64F.
einsteingustavo 0:aef6b59caed0 3 Inputs:
einsteingustavo 0:aef6b59caed0 4 x6 Analog Inputs;
einsteingustavo 0:aef6b59caed0 5 x2 Digital (Frequency) Inputs;
einsteingustavo 0:aef6b59caed0 6 x1 Internal Accelerometer (FXOS8700);
einsteingustavo 0:aef6b59caed0 7 x1 External Accelerometer and Gyroscope (LSM6DS3);
einsteingustavo 0:aef6b59caed0 8 In this set, it is designed for a 200Hz sample rate.
einsteingustavo 0:aef6b59caed0 9 All the data are saved periodically (every 0.25s) to a folder in the SD card.
einsteingustavo 0:aef6b59caed0 10 To read the data, use the file "read_struct.c" in the folder results.
einsteingustavo 0:aef6b59caed0 11
einsteingustavo 0:aef6b59caed0 12 Implemented by Diego "sid" Hamilton, Electronics Coordinator at Mangue Baja Team, UFPE.
einsteingustavo 0:aef6b59caed0 13 */
einsteingustavo 0:aef6b59caed0 14
einsteingustavo 0:aef6b59caed0 15 #include "mbed.h"
einsteingustavo 0:aef6b59caed0 16 #include "LSM6DS3.h"
einsteingustavo 0:aef6b59caed0 17 #include "FXOS8700CQ.h"
einsteingustavo 0:aef6b59caed0 18 #include "SDFileSystem.h"
einsteingustavo 0:aef6b59caed0 19 #include <cstdlib>
einsteingustavo 0:aef6b59caed0 20
einsteingustavo 0:aef6b59caed0 21 #define SERIAL_BAUD 1000000 // Board baud rate
einsteingustavo 0:aef6b59caed0 22 #define BUFFER_SIZE 200 // Acquisition buffer
einsteingustavo 0:aef6b59caed0 23 #define SAVE_WHEN 50 // Number of packets to save (fail safe)
einsteingustavo 0:aef6b59caed0 24 #define SAMPLE_FREQ 200 // Frequency in Hz
einsteingustavo 0:aef6b59caed0 25
einsteingustavo 0:aef6b59caed0 26 /* Debug */
einsteingustavo 0:aef6b59caed0 27 PwmOut signal_wave(D3); // Debug wave to test frequency channels
einsteingustavo 0:aef6b59caed0 28 /* I/O */
einsteingustavo 0:aef6b59caed0 29 Serial pc(USBTX, USBRX, SERIAL_BAUD); // Debug purposes
einsteingustavo 0:aef6b59caed0 30 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS
einsteingustavo 0:aef6b59caed0 31 //DigitalOut warning(D3); // When device is ready, led is permanently OFF
einsteingustavo 0:aef6b59caed0 32 //DigitalOut logging(D4); // When data is beign acquired, led is ON
einsteingustavo 0:aef6b59caed0 33 InterruptIn start(D2, PullUp); // Press button to start/stop acquisition
einsteingustavo 0:aef6b59caed0 34 InterruptIn freq_chan1(D0, PullUp); // Frequency channel 1
einsteingustavo 0:aef6b59caed0 35 InterruptIn freq_chan2(D1, PullUp); // Frequency channel 2
einsteingustavo 0:aef6b59caed0 36 AnalogIn pot0(A0),
einsteingustavo 0:aef6b59caed0 37 pot1(A1),
einsteingustavo 0:aef6b59caed0 38 pot2(A2),
einsteingustavo 0:aef6b59caed0 39 pot3(A3),
einsteingustavo 0:aef6b59caed0 40 pot4(A4),
einsteingustavo 0:aef6b59caed0 41 pot5(A5);
einsteingustavo 0:aef6b59caed0 42 LSM6DS3 LSM6DS3(PTE25,PTE24); // External accelerometer and gyroscope
einsteingustavo 0:aef6b59caed0 43 FXOS8700CQ fxos(PTE25,PTE24); // Internal accelerometer (and magnetometer, not used)
einsteingustavo 0:aef6b59caed0 44
einsteingustavo 0:aef6b59caed0 45 //Ajuste para usar o led da placa
einsteingustavo 0:aef6b59caed0 46 DigitalOut logging(LED1);
einsteingustavo 0:aef6b59caed0 47 DigitalOut warning(LED2);
einsteingustavo 0:aef6b59caed0 48 //DigitalOut led3(LED3);
einsteingustavo 0:aef6b59caed0 49
einsteingustavo 0:aef6b59caed0 50 /* Data structure */
einsteingustavo 0:aef6b59caed0 51 typedef struct
einsteingustavo 0:aef6b59caed0 52 {
einsteingustavo 0:aef6b59caed0 53 int16_t acclsmx;
einsteingustavo 0:aef6b59caed0 54 int16_t acclsmy;
einsteingustavo 0:aef6b59caed0 55 int16_t acclsmz;
einsteingustavo 0:aef6b59caed0 56 int16_t anglsmx;
einsteingustavo 0:aef6b59caed0 57 int16_t anglsmy;
einsteingustavo 0:aef6b59caed0 58 int16_t anglsmz;
einsteingustavo 0:aef6b59caed0 59 int16_t accfxox;
einsteingustavo 0:aef6b59caed0 60 int16_t accfxoy;
einsteingustavo 0:aef6b59caed0 61 int16_t accfxoz;
einsteingustavo 0:aef6b59caed0 62 uint16_t analog0;
einsteingustavo 0:aef6b59caed0 63 uint16_t analog1;
einsteingustavo 0:aef6b59caed0 64 uint16_t analog2;
einsteingustavo 0:aef6b59caed0 65 uint16_t analog3;
einsteingustavo 0:aef6b59caed0 66 uint16_t analog4;
einsteingustavo 0:aef6b59caed0 67 uint16_t analog5;
einsteingustavo 0:aef6b59caed0 68 uint16_t pulses_chan1;
einsteingustavo 0:aef6b59caed0 69 uint16_t pulses_chan2;
einsteingustavo 0:aef6b59caed0 70 uint32_t time_stamp;
einsteingustavo 0:aef6b59caed0 71 } packet_t;
einsteingustavo 0:aef6b59caed0 72
einsteingustavo 0:aef6b59caed0 73 Timer t; // Device timer
einsteingustavo 0:aef6b59caed0 74 Ticker acq; // Acquisition timer interrupt source
einsteingustavo 0:aef6b59caed0 75 CircularBuffer<packet_t, BUFFER_SIZE> buffer; // Acquisition buffer
einsteingustavo 0:aef6b59caed0 76 int buffer_counter = 0; // Packet currently in buffer
einsteingustavo 0:aef6b59caed0 77 bool running = false; // Device status
einsteingustavo 0:aef6b59caed0 78 //bool running = true; // Einstein's Adaptation
einsteingustavo 0:aef6b59caed0 79 uint16_t pulse_counter1 = 0,
einsteingustavo 0:aef6b59caed0 80 pulse_counter2 = 0; // Frequency counter variables
einsteingustavo 0:aef6b59caed0 81 uint16_t acc_addr = 0; /* LSM6DS3 address, if not connected
einsteingustavo 0:aef6b59caed0 82 address is 0 and data is not stored */
einsteingustavo 0:aef6b59caed0 83
einsteingustavo 0:aef6b59caed0 84 void sampleISR(); // Data acquisition ISR
einsteingustavo 0:aef6b59caed0 85 uint32_t count_files_in_sd(const char *fsrc); // Compute number of files in SD
einsteingustavo 0:aef6b59caed0 86 void freq_channel1_ISR(); // Frequency counter ISR, channel 1
einsteingustavo 0:aef6b59caed0 87 void freq_channel2_ISR(); // Frequency counter ISR, channel 2
einsteingustavo 0:aef6b59caed0 88 void toggle_logging(); // Start button ISR
einsteingustavo 0:aef6b59caed0 89
einsteingustavo 0:aef6b59caed0 90 int main()
einsteingustavo 0:aef6b59caed0 91 {
einsteingustavo 0:aef6b59caed0 92 uint32_t t1,t2;
einsteingustavo 0:aef6b59caed0 93 logging = 0; // logging led OFF
einsteingustavo 0:aef6b59caed0 94 int num_parts = 0, // Number of parts already saved
einsteingustavo 0:aef6b59caed0 95 num_files = 0, // Number of files in SD
einsteingustavo 0:aef6b59caed0 96 svd_pck = 0; // Number of saved packets (in current part)
einsteingustavo 0:aef6b59caed0 97 char name_dir[12]; // Name of current folder (new RUN)
einsteingustavo 0:aef6b59caed0 98 char name_file[20]; // Name of current file (partX)
einsteingustavo 0:aef6b59caed0 99 FILE* fp;
einsteingustavo 0:aef6b59caed0 100 packet_t temp;
einsteingustavo 0:aef6b59caed0 101 packet_t trash;
einsteingustavo 0:aef6b59caed0 102 signal_wave.period_ms(50);
einsteingustavo 0:aef6b59caed0 103 signal_wave.write(0.5f);
einsteingustavo 0:aef6b59caed0 104
einsteingustavo 0:aef6b59caed0 105 /* Initialize accelerometers */
einsteingustavo 0:aef6b59caed0 106 acc_addr = LSM6DS3.begin(LSM6DS3.G_SCALE_245DPS, LSM6DS3.A_SCALE_2G, \
einsteingustavo 0:aef6b59caed0 107 LSM6DS3.G_ODR_208, LSM6DS3.A_ODR_208);
einsteingustavo 0:aef6b59caed0 108 fxos.init();
einsteingustavo 0:aef6b59caed0 109
einsteingustavo 0:aef6b59caed0 110 /* Wait for SD ready */
einsteingustavo 0:aef6b59caed0 111 while(sd.disk_status())
einsteingustavo 0:aef6b59caed0 112 {
einsteingustavo 0:aef6b59caed0 113 sd.disk_initialize();
einsteingustavo 0:aef6b59caed0 114 warning = 0;
einsteingustavo 0:aef6b59caed0 115 wait(1.0);
einsteingustavo 0:aef6b59caed0 116 warning = 1;
einsteingustavo 0:aef6b59caed0 117 wait(1.0);
einsteingustavo 0:aef6b59caed0 118 }
einsteingustavo 0:aef6b59caed0 119
einsteingustavo 0:aef6b59caed0 120 num_files = count_files_in_sd("/sd");
einsteingustavo 0:aef6b59caed0 121 sprintf(name_dir, "%s%d", "/sd/RUN", num_files + 1);
einsteingustavo 0:aef6b59caed0 122
einsteingustavo 0:aef6b59caed0 123 start.fall(&toggle_logging); // Attach start button ISR
einsteingustavo 0:aef6b59caed0 124 while(!running) // Wait button press
einsteingustavo 0:aef6b59caed0 125 warning = 1; // For some reason if this line is empty the code doesn't run
einsteingustavo 0:aef6b59caed0 126
einsteingustavo 0:aef6b59caed0 127 /* Create RUN directory */
einsteingustavo 0:aef6b59caed0 128 mkdir(name_dir, 0777);
einsteingustavo 0:aef6b59caed0 129 warning = 0;
einsteingustavo 0:aef6b59caed0 130 sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts++);
einsteingustavo 0:aef6b59caed0 131 fp = fopen(name_file, "w"); // Creates first data file
einsteingustavo 0:aef6b59caed0 132 t.start(); // Start device timer
einsteingustavo 0:aef6b59caed0 133 freq_chan1.fall(&freq_channel1_ISR);
einsteingustavo 0:aef6b59caed0 134 freq_chan2.fall(&freq_channel2_ISR);
einsteingustavo 0:aef6b59caed0 135 acq.attach(&sampleISR, 1.0/SAMPLE_FREQ); // Start data acquisition
einsteingustavo 0:aef6b59caed0 136 logging = 1;
einsteingustavo 0:aef6b59caed0 137 // logging led ON
einsteingustavo 0:aef6b59caed0 138
einsteingustavo 0:aef6b59caed0 139 while(running)
einsteingustavo 0:aef6b59caed0 140 {
einsteingustavo 0:aef6b59caed0 141
einsteingustavo 0:aef6b59caed0 142 if(buffer.full())
einsteingustavo 0:aef6b59caed0 143 {
einsteingustavo 0:aef6b59caed0 144 warning = 1; // Turn warning led ON if buffer gets full (abnormal situation)
einsteingustavo 0:aef6b59caed0 145 //pc.putc('X'); // Debug message
einsteingustavo 0:aef6b59caed0 146 //buffer.pop(trash);
einsteingustavo 0:aef6b59caed0 147 }
einsteingustavo 0:aef6b59caed0 148 else if(!buffer.empty())
einsteingustavo 0:aef6b59caed0 149 {
einsteingustavo 0:aef6b59caed0 150 //pc.putc('G'); // Debug message
einsteingustavo 0:aef6b59caed0 151 /* Remove packet from buffer and writes it to file */
einsteingustavo 0:aef6b59caed0 152 buffer.pop(temp);
einsteingustavo 0:aef6b59caed0 153 buffer_counter--;
einsteingustavo 0:aef6b59caed0 154 //t1 = t.read_ms();
einsteingustavo 0:aef6b59caed0 155 fwrite((void *)&temp, sizeof(packet_t), 1, fp);
einsteingustavo 0:aef6b59caed0 156 //t2 = t.read_ms()-t1;
einsteingustavo 0:aef6b59caed0 157 //pc.printf("%d\r\n",t2);
einsteingustavo 0:aef6b59caed0 158 svd_pck++;
einsteingustavo 0:aef6b59caed0 159 /* Create new data file */
einsteingustavo 0:aef6b59caed0 160 if(svd_pck == SAVE_WHEN)
einsteingustavo 0:aef6b59caed0 161 {
einsteingustavo 0:aef6b59caed0 162 fclose(fp);
einsteingustavo 0:aef6b59caed0 163 sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts++);
einsteingustavo 0:aef6b59caed0 164 fp = fopen(name_file, "w");
einsteingustavo 0:aef6b59caed0 165 //pc.printf("%d\n", buffer_counter); // Debug message
einsteingustavo 0:aef6b59caed0 166 svd_pck = 0;
einsteingustavo 0:aef6b59caed0 167
einsteingustavo 0:aef6b59caed0 168 }
einsteingustavo 0:aef6b59caed0 169 }
einsteingustavo 0:aef6b59caed0 170 /* Software debounce for start button */
einsteingustavo 0:aef6b59caed0 171 if((t.read_ms() > 10) && (t.read_ms() < 20))
einsteingustavo 0:aef6b59caed0 172 start.fall(toggle_logging);
einsteingustavo 0:aef6b59caed0 173 }
einsteingustavo 0:aef6b59caed0 174
einsteingustavo 0:aef6b59caed0 175 /* Reset device if start button is pressed while logging */
einsteingustavo 0:aef6b59caed0 176 logging = 0;
einsteingustavo 0:aef6b59caed0 177 NVIC_SystemReset();
einsteingustavo 0:aef6b59caed0 178 return 0;
einsteingustavo 0:aef6b59caed0 179 }
einsteingustavo 0:aef6b59caed0 180
einsteingustavo 0:aef6b59caed0 181 void sampleISR()
einsteingustavo 0:aef6b59caed0 182 {
einsteingustavo 0:aef6b59caed0 183 static uint16_t last_acq = t.read_ms(); // Time of last acquisition
einsteingustavo 0:aef6b59caed0 184 packet_t acq_pck; // Current data packet
einsteingustavo 0:aef6b59caed0 185 Data fxos_acc;
einsteingustavo 0:aef6b59caed0 186 fxos_acc = fxos.get_values(); // Read FXOS8700 data
einsteingustavo 0:aef6b59caed0 187 /* Store LSM6DS3 data if it's connected */
einsteingustavo 0:aef6b59caed0 188 if (acc_addr != 0)
einsteingustavo 0:aef6b59caed0 189 {
einsteingustavo 0:aef6b59caed0 190 LSM6DS3.readAccel(); // Read Accelerometer data
einsteingustavo 0:aef6b59caed0 191 LSM6DS3.readGyro(); // Read Gyroscope data
einsteingustavo 0:aef6b59caed0 192
einsteingustavo 0:aef6b59caed0 193 acq_pck.acclsmx = LSM6DS3.ax_raw;
einsteingustavo 0:aef6b59caed0 194 acq_pck.acclsmy = LSM6DS3.ay_raw;
einsteingustavo 0:aef6b59caed0 195 acq_pck.acclsmz = LSM6DS3.az_raw;
einsteingustavo 0:aef6b59caed0 196 acq_pck.anglsmx = LSM6DS3.gx_raw;
einsteingustavo 0:aef6b59caed0 197 acq_pck.anglsmy = LSM6DS3.gy_raw;
einsteingustavo 0:aef6b59caed0 198 acq_pck.anglsmz = LSM6DS3.gz_raw;
einsteingustavo 0:aef6b59caed0 199 }
einsteingustavo 0:aef6b59caed0 200 else
einsteingustavo 0:aef6b59caed0 201 {
einsteingustavo 0:aef6b59caed0 202 acq_pck.acclsmx = 0;
einsteingustavo 0:aef6b59caed0 203 acq_pck.acclsmy = 0;
einsteingustavo 0:aef6b59caed0 204 acq_pck.acclsmz = 0;
einsteingustavo 0:aef6b59caed0 205 acq_pck.anglsmx = 0;
einsteingustavo 0:aef6b59caed0 206 acq_pck.anglsmy = 0;
einsteingustavo 0:aef6b59caed0 207 acq_pck.anglsmz = 0;
einsteingustavo 0:aef6b59caed0 208 }
einsteingustavo 0:aef6b59caed0 209 acq_pck.accfxox = fxos_acc.ax;
einsteingustavo 0:aef6b59caed0 210 acq_pck.accfxoy = fxos_acc.ay;
einsteingustavo 0:aef6b59caed0 211 acq_pck.accfxoz = fxos_acc.az;
einsteingustavo 0:aef6b59caed0 212 acq_pck.analog0 = pot0.read_u16(); // Read analog sensor 0
einsteingustavo 0:aef6b59caed0 213 acq_pck.analog1 = pot1.read_u16(); // Read analog sensor 1
einsteingustavo 0:aef6b59caed0 214 acq_pck.analog2 = pot2.read_u16(); // Read analog sensor 2
einsteingustavo 0:aef6b59caed0 215 acq_pck.analog3 = pot3.read_u16(); // Read analog sensor 3
einsteingustavo 0:aef6b59caed0 216 acq_pck.analog4 = pot4.read_u16(); // Read analog sensor 4
einsteingustavo 0:aef6b59caed0 217 acq_pck.analog5 = pot5.read_u16(); // Read analog sensor 5
einsteingustavo 0:aef6b59caed0 218 acq_pck.pulses_chan1 = pulse_counter1; // Store frequence channel 1
einsteingustavo 0:aef6b59caed0 219 acq_pck.pulses_chan2 = pulse_counter2; // Store frequence channel 2
einsteingustavo 0:aef6b59caed0 220 acq_pck.time_stamp = t.read_ms(); // Timestamp of data acquistion
einsteingustavo 0:aef6b59caed0 221
einsteingustavo 0:aef6b59caed0 222 pulse_counter1= 0;
einsteingustavo 0:aef6b59caed0 223 pulse_counter2= 0;
einsteingustavo 0:aef6b59caed0 224 buffer.push(acq_pck);
einsteingustavo 0:aef6b59caed0 225 buffer_counter++;
einsteingustavo 0:aef6b59caed0 226 }
einsteingustavo 0:aef6b59caed0 227
einsteingustavo 0:aef6b59caed0 228 uint32_t count_files_in_sd(const char *fsrc)
einsteingustavo 0:aef6b59caed0 229 {
einsteingustavo 0:aef6b59caed0 230 DIR *d = opendir(fsrc);
einsteingustavo 0:aef6b59caed0 231 struct dirent *p;
einsteingustavo 0:aef6b59caed0 232 uint32_t counter = 0;
einsteingustavo 0:aef6b59caed0 233
einsteingustavo 0:aef6b59caed0 234 while ((p = readdir(d)) != NULL) {
einsteingustavo 0:aef6b59caed0 235 if(strcmp(p->d_name, ".Trash-1000"))
einsteingustavo 0:aef6b59caed0 236 counter++;
einsteingustavo 0:aef6b59caed0 237 }
einsteingustavo 0:aef6b59caed0 238 closedir(d);
einsteingustavo 0:aef6b59caed0 239 return counter;
einsteingustavo 0:aef6b59caed0 240 }
einsteingustavo 0:aef6b59caed0 241
einsteingustavo 0:aef6b59caed0 242 void freq_channel1_ISR()
einsteingustavo 0:aef6b59caed0 243 {
einsteingustavo 0:aef6b59caed0 244 pulse_counter1++;
einsteingustavo 0:aef6b59caed0 245 }
einsteingustavo 0:aef6b59caed0 246
einsteingustavo 0:aef6b59caed0 247 void freq_channel2_ISR()
einsteingustavo 0:aef6b59caed0 248 {
einsteingustavo 0:aef6b59caed0 249 pulse_counter2++;
einsteingustavo 0:aef6b59caed0 250 }
einsteingustavo 0:aef6b59caed0 251
einsteingustavo 0:aef6b59caed0 252 void toggle_logging()
einsteingustavo 0:aef6b59caed0 253 {
einsteingustavo 0:aef6b59caed0 254 running = !running;
einsteingustavo 0:aef6b59caed0 255 start.fall(NULL);
einsteingustavo 0:aef6b59caed0 256 }