
mangue baja 1st working logger on stm32
Dependencies: LSM6DS3 DebouncedInterrupt
Revision 3:15d63b793f7b, committed 2020-01-10
- Comitter:
- einsteingustavo
- Date:
- Fri Jan 10 11:26:11 2020 +0000
- Parent:
- 2:d08c053d5a35
- Child:
- 4:b19fb484b1af
- Commit message:
- mangue baja 1st working logger on stm32
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LSM6DS3.lib Fri Jan 10 11:26:11 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/5hel2l2y/code/LSM6DS3/#69c5c66c3f2f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example.txt Fri Jan 10 11:26:11 2020 +0000 @@ -0,0 +1,221 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include <stdio.h> +#include <errno.h> + +// Block devices +//#include "SPIFBlockDevice.h" +//#include "DataFlashBlockDevice.h" +#include "SDBlockDevice.h" +//#include "HeapBlockDevice.h" + +// File systems + +//#include "LittleFileSystem.h" +#include "FATFileSystem.h" + +// Physical block device, can be any device that supports the BlockDevice API +SDBlockDevice blockDevice(PB_15, PB_14, PB_13, PB_12); // mosi, miso, sck, cs + +// File system declaration +FATFileSystem fileSystem("fs"); + +Serial pc(PA_2,PA_3); + +// Entry point for the example +int main() +{ + pc.printf("--- Mbed OS filesystem example ---\n"); + + // Try to mount the filesystem + pc.printf("Mounting the filesystem... "); + fflush(stdout); + + int err = fileSystem.mount(&blockDevice); + pc.printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) { + // Reformat if we can't mount the filesystem + // this should only happen on the first boot + pc.printf("No filesystem found, formatting... "); + fflush(stdout); + err = fileSystem.reformat(&blockDevice); + pc.printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) { + error("error: %s (%d)\n", strerror(-err), err); + } + } + + // Open the numbers file + pc.printf("Opening \"/fs/numbers.txt\"... "); + fflush(stdout); + + FILE* f = fopen("/fs/numbers.txt", "r+"); + pc.printf("%s\n", (!f ? "Fail :(" : "OK")); + if (!f) { + // Create the numbers file if it doesn't exist + pc.printf("No file found, creating a new file... "); + fflush(stdout); + f = fopen("/fs/numbers.txt", "w+"); + pc.printf("%s\n", (!f ? "Fail :(" : "OK")); + if (!f) { + error("error: %s (%d)\n", strerror(errno), -errno); + } + + for (int i = 0; i < 10; i++) { + pc.printf("\rWriting numbers (%d/%d)... ", i, 10); + fflush(stdout); + err = fprintf(f, " %d\n", i); + if (err < 0) { + pc.printf("Fail :(\n"); + error("error: %s (%d)\n", strerror(errno), -errno); + } + } + + pc.printf("\rWriting numbers (%d/%d)... OK\n", 10, 10); + + pc.printf("Seeking file... "); + fflush(stdout); + err = fseek(f, 0, SEEK_SET); + pc.printf("%s\n", (err < 0 ? "Fail :(" : "OK")); + if (err < 0) { + error("error: %s (%d)\n", strerror(errno), -errno); + } + } + + // Go through and increment the numbers + for (int i = 0; i < 10; i++) { + pc.printf("\rIncrementing numbers (%d/%d)... ", i, 10); + fflush(stdout); + + // Get current stream position + long pos = ftell(f); + + // Parse out the number and increment + int32_t number; + fscanf(f, "%ld", &number); + number += 1; + + // Seek to beginning of number + fseek(f, pos, SEEK_SET); + + // Store number + fprintf(f, " %ld\n", number); + + // Flush between write and read on same file + fflush(f); + } + + pc.printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10); + + // Close the file which also flushes any cached writes + pc.printf("Closing \"/fs/numbers.txt\"... "); + fflush(stdout); + err = fclose(f); + pc.printf("%s\n", (err < 0 ? "Fail :(" : "OK")); + if (err < 0) { + error("error: %s (%d)\n", strerror(errno), -errno); + } + + // Display the root directory + pc.printf("Opening the root directory... "); + fflush(stdout); + + DIR* d = opendir("/fs/"); + pc.printf("%s\n", (!d ? "Fail :(" : "OK")); + if (!d) { + error("error: %s (%d)\n", strerror(errno), -errno); + } + + pc.printf("root directory:\n"); + while (true) { + struct dirent* e = readdir(d); + if (!e) { + break; + } + + pc.printf(" %s\n", e->d_name); + } + + pc.printf("Closing the root directory... "); + fflush(stdout); + err = closedir(d); + pc.printf("%s\n", (err < 0 ? "Fail :(" : "OK")); + if (err < 0) { + error("error: %s (%d)\n", strerror(errno), -errno); + } + + // Display the numbers file + pc.printf("Opening \"/fs/numbers.txt\"... "); + fflush(stdout); + f = fopen("/fs/numbers.txt", "r"); + pc.printf("%s\n", (!f ? "Fail :(" : "OK")); + if (!f) { + error("error: %s (%d)\n", strerror(errno), -errno); + } + + pc.printf("numbers:\n"); + while (!feof(f)) { + int c = fgetc(f); + pc.printf("%c", c); + } + + pc.printf("\rClosing \"/fs/numbers.txt\"... "); + fflush(stdout); + err = fclose(f); + pc.printf("%s\n", (err < 0 ? "Fail :(" : "OK")); + if (err < 0) { + error("error: %s (%d)\n", strerror(errno), -errno); + } + + // Tidy up + pc.printf("Unmounting... "); + fflush(stdout); + err = fileSystem.unmount(); + pc.printf("%s\n", (err < 0 ? "Fail :(" : "OK")); + if (err < 0) { + error("error: %s (%d)\n", strerror(-err), err); + } + + pc.printf("Initializing the block device... "); + fflush(stdout); + + err = blockDevice.init(); + pc.printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) { + error("error: %s (%d)\n", strerror(-err), err); + } + + pc.printf("Erasing the block device... "); + fflush(stdout); + err = blockDevice.erase(0, blockDevice.size()); + pc.printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) { + error("error: %s (%d)\n", strerror(-err), err); + } + + pc.printf("Deinitializing the block device... "); + fflush(stdout); + err = blockDevice.deinit(); + pc.printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) { + error("error: %s (%d)\n", strerror(-err), err); + } + + pc.printf("\r\n"); + + pc.printf("Mbed OS filesystem example done!\n"); +}
--- a/main.cpp Wed Jul 17 06:07:09 2019 +0000 +++ b/main.cpp Fri Jan 10 11:26:11 2020 +0000 @@ -1,219 +1,271 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +/* + Data Logger implementation in STM32F103C8T6. + Inputs: + 1x External Accelerometer and Gyroscope (LSM6DS3) + x3 Analog Inputs; + x2 Digital (Frequency) Inputs; + In this set, it is designed for a 200Hz sample rate. + All the data are saved periodically (every 0.25s) to a folder in the SD card. + To read the data, use the file "read_struct2.0.c" in the folder results. + + Implemented by Einstein "Hashtag" Gustavo(Electronics Coordinator 2019) at Mangue Baja Team, UFPE. +*/ + #include "mbed.h" #include <stdio.h> #include <errno.h> - -// Block devices -//#include "SPIFBlockDevice.h" -//#include "DataFlashBlockDevice.h" #include "SDBlockDevice.h" -//#include "HeapBlockDevice.h" - -// File systems +#include "FATFileSystem.h" +#include "LSM6DS3.h" -//#include "LittleFileSystem.h" -#include "FATFileSystem.h" +#define BUFFER_SIZE 200 // Acquisition buffer +#define SAVE_WHEN 50 // Number of packets to save (fail safe) +#define SAMPLE_FREQ 200 // Frequency in Hz -// Physical block device, can be any device that supports the BlockDevice API -SDBlockDevice blockDevice(p5, p6, p7, p8); // mosi, miso, sck, cs - -// File system declaration -FATFileSystem fileSystem("fs"); +/* Debug */ +PwmOut signal_wave(PB_3); // Debug wave to test frequency channels -// Entry point for the example -int main() -{ - printf("--- Mbed OS filesystem example ---\n"); - - // Try to mount the filesystem - printf("Mounting the filesystem... "); - fflush(stdout); +/* I/O */ +Serial pc(PA_2, PA_3); // Debug purposes +LSM6DS3 LSM6DS3(PB_9, PB_8); // Gyroscope/Accelerometer declaration (SDA,SCL) +SDBlockDevice sd(PB_15, PB_14, PB_13, PB_12); // mosi, miso, sck, cs +FATFileSystem fileSystem("sd"); +DigitalOut warning(PA_15); // When device is ready, led is permanently OFF +DigitalOut logging(PA_12); // When data is beign acquired, led is ON +InterruptIn start(PB_4,PullUp); // Press button to start/stop acquisition +InterruptIn freq_chan1(PB_5,PullUp); // Frequency channel 1 +InterruptIn freq_chan2(PB_6,PullUp); // Frequency channel 2 +AnalogIn pot0(PA_5), + pot1(PB_0), + pot2(PA_7); - int err = fileSystem.mount(&blockDevice); - printf("%s\n", (err ? "Fail :(" : "OK")); - if (err) { - // Reformat if we can't mount the filesystem - // this should only happen on the first boot - printf("No filesystem found, formatting... "); - fflush(stdout); - err = fileSystem.reformat(&blockDevice); - printf("%s\n", (err ? "Fail :(" : "OK")); - if (err) { - error("error: %s (%d)\n", strerror(-err), err); - } - } +/* Data structure */ +typedef struct +{ + int16_t acclsmx; + int16_t acclsmy; + int16_t acclsmz; + int16_t anglsmx; + int16_t anglsmy; + int16_t anglsmz; + uint16_t analog0; + uint16_t analog1; + uint16_t analog2; + uint16_t pulses_chan1; + uint16_t pulses_chan2; + uint32_t time_stamp; +} packet_t; - // Open the numbers file - printf("Opening \"/fs/numbers.txt\"... "); - fflush(stdout); - FILE* f = fopen("/fs/numbers.txt", "r+"); - printf("%s\n", (!f ? "Fail :(" : "OK")); - if (!f) { - // Create the numbers file if it doesn't exist - printf("No file found, creating a new file... "); - fflush(stdout); - f = fopen("/fs/numbers.txt", "w+"); - printf("%s\n", (!f ? "Fail :(" : "OK")); - if (!f) { - error("error: %s (%d)\n", strerror(errno), -errno); - } +Timer t; // Device timer +Ticker acq; // Acquisition timer interrupt source +CircularBuffer<packet_t, BUFFER_SIZE> buffer; // Acquisition buffer +int buffer_counter = 0; // Packet currently in buffer +int err; // SD library utility +bool running = false; // Device status +bool StorageTrigger = false; +uint16_t pulse_counter1 = 0, + pulse_counter2 = 0, // Frequency counter variables + acc_addr = 0; // LSM6DS3 address, if not connected address is 0 and data is not stored + +void sampleISR(); // Data acquisition ISR +uint32_t count_files_in_sd(const char *fsrc); // Compute number of files in SD +void freq_channel1_ISR(); // Frequency counter ISR, channel 1 +void freq_channel2_ISR(); // Frequency counter ISR, channel 2 +void toggle_logging(); // Start button ISR - for (int i = 0; i < 10; i++) { - printf("\rWriting numbers (%d/%d)... ", i, 10); - fflush(stdout); - err = fprintf(f, " %d\n", i); - if (err < 0) { - printf("Fail :(\n"); - error("error: %s (%d)\n", strerror(errno), -errno); - } - } - - printf("\rWriting numbers (%d/%d)... OK\n", 10, 10); - - printf("Seeking file... "); - fflush(stdout); - err = fseek(f, 0, SEEK_SET); - printf("%s\n", (err < 0 ? "Fail :(" : "OK")); - if (err < 0) { - error("error: %s (%d)\n", strerror(errno), -errno); - } - } - - // Go through and increment the numbers - for (int i = 0; i < 10; i++) { - printf("\rIncrementing numbers (%d/%d)... ", i, 10); +int main() +{ + pc.printf("\r\nDebug 1\r\n"); + logging = 0; // logging led OFF + int num_parts = 0, // Number of parts already saved + num_files = 0, // Number of files in SD + svd_pck = 0; // Number of saved packets (in current part) + char name_dir[12]; // Name of current folder (new RUN) + char name_file[20]; // Name of current file (partX) + FILE* fp; + packet_t temp; + signal_wave.period_us(50); + signal_wave.write(0.5f); + + + /* Initialize accelerometer */ + acc_addr = LSM6DS3.begin(LSM6DS3.G_SCALE_245DPS, LSM6DS3.A_SCALE_2G, \ + LSM6DS3.G_ODR_208, LSM6DS3.A_ODR_208); + + /* Wait for SD mount */ + do + { + /* Try to mount the filesystem */ + pc.printf("Mounting the filesystem... "); fflush(stdout); - // Get current stream position - long pos = ftell(f); - - // Parse out the number and increment - int32_t number; - fscanf(f, "%ld", &number); - number += 1; - - // Seek to beginning of number - fseek(f, pos, SEEK_SET); - - // Store number - fprintf(f, " %ld\n", number); - - // Flush between write and read on same file - fflush(f); + err = fileSystem.mount(&sd); + pc.printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) + { + /* Reformat if we can't mount the filesystem + this should only happen on the first boot */ + pc.printf("No filesystem found, formatting... "); + fflush(stdout); + err = fileSystem.reformat(&sd); + pc.printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) + { + error("error: %s (%d)\n", strerror(-err), err); + } + } + }while(err); + + pc.printf("\r\nDebug 2\r\n"); + + pc.printf("\r\nDebug 3\r\n"); + + num_files = count_files_in_sd("/sd"); + sprintf(name_dir, "%s%d", "/sd/RUN", num_files + 1); + + pc.printf("\r\nDebug 4\r\n"); + pc.printf("\r\nNum_files = %d\r\n", num_files); + + start.fall(&toggle_logging); // Attach start button ISR + + while(!running) // Wait button press + { + warning = 1; + pc.printf("\r\nrunning=%d\r\n", running); // For some reason if this line is empty the code doesn't run } - - printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10); + + /* Create RUN directory */ + mkdir(name_dir, 0777); + warning = 0; // Warning led OFF + //sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts++); + sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts+1); + fp = fopen(name_file, "a"); // Creates first data file + t.start(); // Start device timer + freq_chan1.fall(&freq_channel1_ISR); + freq_chan2.fall(&freq_channel2_ISR); + acq.attach(&sampleISR, 1.0/SAMPLE_FREQ); // Start data acquisition + logging = 1; // logging led ON + + while(running) + { + if(StorageTrigger) + { + packet_t acq_pck; // Current data packet + static uint16_t last_acq = t.read_ms(); // Time of last acquisition - // Close the file which also flushes any cached writes - printf("Closing \"/fs/numbers.txt\"... "); - fflush(stdout); - err = fclose(f); - printf("%s\n", (err < 0 ? "Fail :(" : "OK")); - if (err < 0) { - error("error: %s (%d)\n", strerror(errno), -errno); - } - - // Display the root directory - printf("Opening the root directory... "); - fflush(stdout); - - DIR* d = opendir("/fs/"); - printf("%s\n", (!d ? "Fail :(" : "OK")); - if (!d) { - error("error: %s (%d)\n", strerror(errno), -errno); - } - - printf("root directory:\n"); - while (true) { - struct dirent* e = readdir(d); - if (!e) { - break; + /* Store LSM6DS3 data if it's connected */ + if (acc_addr != 0) + { + LSM6DS3.readAccel(); // Read Accelerometer data + LSM6DS3.readGyro(); // Read Gyroscope data + + acq_pck.acclsmx = LSM6DS3.ax_raw; + acq_pck.acclsmy = LSM6DS3.ay_raw; + acq_pck.acclsmz = LSM6DS3.az_raw; + acq_pck.anglsmx = LSM6DS3.gx_raw; + acq_pck.anglsmy = LSM6DS3.gy_raw; + acq_pck.anglsmz = LSM6DS3.gz_raw; + } + else + { + acq_pck.acclsmx = 0; + acq_pck.acclsmy = 0; + acq_pck.acclsmz = 0; + acq_pck.anglsmx = 0; + acq_pck.anglsmy = 0; + acq_pck.anglsmz = 0; + } + + acq_pck.analog0 = pot0.read_u16(); // Read analog sensor 0 + acq_pck.analog1 = pot1.read_u16(); // Read analog sensor 1 + acq_pck.analog2 = pot2.read_u16(); // Read analog sensor 2 + acq_pck.pulses_chan1 = pulse_counter1; // Store frequence channel 1 + acq_pck.pulses_chan2 = pulse_counter2; // Store frequence channel 2 + acq_pck.time_stamp = t.read_ms(); // Timestamp of data acquistion + + pulse_counter1= 0; + pulse_counter2= 0; + buffer.push(acq_pck); + buffer_counter++; + + StorageTrigger = false; } - printf(" %s\n", e->d_name); - } - - printf("Closing the root directory... "); - fflush(stdout); - err = closedir(d); - printf("%s\n", (err < 0 ? "Fail :(" : "OK")); - if (err < 0) { - error("error: %s (%d)\n", strerror(errno), -errno); - } - - // Display the numbers file - printf("Opening \"/fs/numbers.txt\"... "); - fflush(stdout); - f = fopen("/fs/numbers.txt", "r"); - printf("%s\n", (!f ? "Fail :(" : "OK")); - if (!f) { - error("error: %s (%d)\n", strerror(errno), -errno); - } - - printf("numbers:\n"); - while (!feof(f)) { - int c = fgetc(f); - printf("%c", c); - } - - printf("\rClosing \"/fs/numbers.txt\"... "); - fflush(stdout); - err = fclose(f); - printf("%s\n", (err < 0 ? "Fail :(" : "OK")); - if (err < 0) { - error("error: %s (%d)\n", strerror(errno), -errno); - } - - // Tidy up - printf("Unmounting... "); - fflush(stdout); - err = fileSystem.unmount(); - printf("%s\n", (err < 0 ? "Fail :(" : "OK")); - if (err < 0) { - error("error: %s (%d)\n", strerror(-err), err); + if(buffer.full()) + { + fclose(fp); + warning = 1; // Turn warning led ON if buffer gets full (abnormal situation) + pc.putc('X'); // Debug message + } + else if(!buffer.empty()) + { + pc.putc('G'); // Debug message + + /* Remove packet from buffer and writes it to file */ + buffer.pop(temp); + buffer_counter--; + fwrite((void *)&temp, sizeof(packet_t), 1, fp); + svd_pck++; + + /* Create new data file + (Deactivated because the code doesn't works fine doing that so many times) */ + if(svd_pck == SAVE_WHEN) + { + //fclose(fp); + //sprintf(name_file, "%s%s%d", name_dir, "/part", num_parts++); + //t2 = t.read_ms(); + //fp = fopen(name_file, "w"); + //printf("t2=%d\r\n",(t.read_ms()-t2)); + //pc.printf("%d\r\n", buffer_counter); // Debug message + svd_pck = 0; + } + } + + /* Software debounce for start button */ + if((t.read_ms() > 10) && (t.read_ms() < 1000)) + start.fall(toggle_logging); } - printf("Initializing the block device... "); - fflush(stdout); + /* Reset device if start button is pressed while logging */ + fclose(fp); + logging = 0; + NVIC_SystemReset(); + return 0; +} - err = blockDevice.init(); - printf("%s\n", (err ? "Fail :(" : "OK")); - if (err) { - error("error: %s (%d)\n", strerror(-err), err); - } +void sampleISR() +{ + StorageTrigger = true; +} - printf("Erasing the block device... "); - fflush(stdout); - err = blockDevice.erase(0, blockDevice.size()); - printf("%s\n", (err ? "Fail :(" : "OK")); - if (err) { - error("error: %s (%d)\n", strerror(-err), err); +uint32_t count_files_in_sd(const char *fsrc) +{ + DIR *d = opendir(fsrc); + struct dirent *p; + uint32_t counter = 0; + + while ((p = readdir(d)) != NULL) + { + if(strcmp(p->d_name, ".Trash-1000")) + counter++; } + closedir(d); + return counter; +} - printf("Deinitializing the block device... "); - fflush(stdout); - err = blockDevice.deinit(); - printf("%s\n", (err ? "Fail :(" : "OK")); - if (err) { - error("error: %s (%d)\n", strerror(-err), err); - } - - printf("\r\n"); - - printf("Mbed OS filesystem example done!\n"); +void freq_channel1_ISR() +{ + pulse_counter1++; } + +void freq_channel2_ISR() +{ + pulse_counter2++; +} + +void toggle_logging() +{ + running = !running; + start.fall(NULL); +}