diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0d7c41..3ed3697 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,27 +15,34 @@ jobs: uses: actions/checkout@v4 with: submodules: true + fetch-depth: 1 - name: Install ARM GCC Toolchain run: | - sudo apt-get update - sudo apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi cmake build-essential - - - name: Setup Raspberry Pi Pico SDK - uses: actions/checkout@v4 + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib cmake build-essential + + - name: Cache Pico SDK + id: cache-pico-sdk + uses: actions/cache@v4 with: - repository: raspberrypi/pico-sdk - ref: master path: pico-sdk - submodules: true + key: pico-sdk-${{ runner.os }}-master + - name: Setup Raspberry Pi Pico SDK + if: steps.cache-pico-sdk.outputs.cache-hit != 'true' + run: | + git clone --depth 1 --branch master https://github.com/raspberrypi/pico-sdk.git + cd pico-sdk + git submodule update --init --depth 1 + - name: Configure CMake env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk run: cmake -B build - name: Build project - run: cmake --build build + run: cmake --build build --parallel 2 - name: Upload UF2 Artifact uses: actions/upload-artifact@v4 diff --git a/README.md b/README.md index 4084dae..7dd19b9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Embedded Avionics Data Logger (C++ / RP2350) -A flight data recorder(aka "Black Box") built for the Raspberry Pi Pico 2(RP2350). This project captures real-time motion data from an MPU6050 IMU and logs it to an SD card using a custom C++ wrapper around the FatFs filesystem provided by carlk3 (https://github.com/carlk3/no-OS-FatFS-SD-SDIO-SPI-RPi-Pico) +A flight data recorder(aka "Black Box") built for the Raspberry Pi Pico 2(RP2350). This project captures real-time motion data from an MPU6050 IMU and logs it to an SD card using a custom C++ wrapper around the FatFs filesystem provided by carlk3 (https://github.com/carlk3/no-OS-FatFS-SD-SDIO-SPI-RPi-Pico) ![Recorder Demo](assets/demo.gif) @@ -64,5 +64,5 @@ cmake --build build - [x] **Gyroscope Data Capture** (X/Y/Z) - [x] **Add Accelerometer Data:** Expand MPU6050 driver to capture acceleration. - [ ] **Error Codes:** Instead of just one LED, use different blink patterns. -- [ ] **Timestamps:** Add millisecond precision timestamps to the log. -- [ ] **FreeRTOS:** RTRefactor the codebase into prioritized Tasks (Sensing vs. Logging) using FreeRTOS to prevent SD card latency. +- [x] **Timestamps:** Add millisecond precision timestamps to the log. +- [ ] **FreeRTOS:** Refactor the codebase into prioritized Tasks (Sensing vs. Logging) using FreeRTOS to prevent SD card latency. diff --git a/src/main.cpp b/src/main.cpp index cb655d4..3ed5ed8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,8 +24,10 @@ int main() { sleep_ms(50); } - Gyro_t current_gyro; - Accel_t current_accel; + Gyro_t g; + Accel_t a; + uint32_t timestamp; + while(true) { if(Utils::is_button_clicked()){ Utils::turnOff_green(); @@ -33,12 +35,12 @@ int main() { printf("\n--- Stoping Flight Recorder ---\n"); break; } + timestamp = to_ms_since_boot(get_absolute_time()); + mpu.getGyro(&g); + mpu.getAccel(&a); + recorder.log_data(timestamp, g, a); - mpu.getGyro(¤t_gyro); - mpu.getAccel(¤t_accel); - recorder.log_data(current_gyro, current_accel); - - printf("Logged: Gyro X:%d Y:%d Z:%d Accel X:%d Y:%d Z:%d \n", current_gyro.x, current_gyro.y, current_gyro.z , current_accel.x, current_accel.y, current_accel.z) ; + printf("Logged: %d Gyro X:%d Y:%d Z:%d Accel X:%d Y:%d Z:%d \n", timestamp, g.x, g.y, g.z , a.x, a.y, a.z) ; sleep_ms(50); } diff --git a/src/recorder/Recorder.cpp b/src/recorder/Recorder.cpp index cacc6f2..8391e5f 100644 --- a/src/recorder/Recorder.cpp +++ b/src/recorder/Recorder.cpp @@ -53,20 +53,40 @@ Recorder::Recorder(spi_inst_t* spi_port, uint miso, uint mosi, uint sck, uint cs void Recorder::start_recording() { this->card_p->mount(); - FRESULT fr = file.open("0:flight_data.csv", FA_WRITE | FA_OPEN_APPEND); + + char filename[20]; + int file_idx = 0; + FRESULT fr; + + // Loop until we find a filename that DOES NOT exist + while (true) { + sprintf(filename, "flight_%03d.csv", file_idx); + FILINFO fno; + fr = f_stat(filename, &fno); + + if (fr == FR_NO_FILE) { + // This name is free + break; + } + file_idx++; + } + + fr = file.open(filename, FA_WRITE | FA_OPEN_APPEND); if (fr == FR_OK) { is_open = true; + file.puts("Timestamp_ms,GyroX,GyroY,GyroZ,AccelX,AccelY,AccelZ\n"); + file.sync(); return; } Utils::handle_error("SD Open Failed"); } -void Recorder::log_data(const Gyro_t& gyro, const Accel_t& accel) +void Recorder::log_data(uint32_t timestamp, const Gyro_t& gyro, const Accel_t& accel) { if(!is_open) return; char buffer[64]; - sprintf(buffer, "G: %d, %d, %d A: %d, %d, %d\n", gyro.x, gyro.y, gyro.z, accel.x, accel.y, accel.z); + sprintf(buffer, "%lu, %d, %d, %d, %d, %d, %d\n", timestamp, gyro.x, gyro.y, gyro.z, accel.x, accel.y, accel.z); file.puts(buffer); file.sync(); } diff --git a/src/recorder/Recorder.h b/src/recorder/Recorder.h index 5fab621..e7b616a 100644 --- a/src/recorder/Recorder.h +++ b/src/recorder/Recorder.h @@ -15,7 +15,7 @@ class Recorder { FatFsNs::SdCard* card_p = nullptr; void start_recording(); - void log_data(const Gyro_t& gyro, const Accel_t& accel); + void log_data(uint32_t timestamp, const Gyro_t& gyro, const Accel_t& accel); void stop_recording(); private: