diff --git a/ground_station/platformio.ini b/ground_station/platformio.ini index e5316fda..dbdbcfb1 100644 --- a/ground_station/platformio.ini +++ b/ground_station/platformio.ini @@ -39,7 +39,7 @@ build_flags = -DCFG_TUSB_CONFIG_FILE='"sdkconfig.h"' ; Use default TinyUSB configuration -DFIRMWARE_VERSION='"1.1.1"' ; Enter Firmware Version here -DUSB_MANUFACTURER='"CATS"' ; USB Manufacturer string - -DUSB_PRODUCT='"CATS Ground Station"' ; USB Product String + -DUSB_PRODUCT='"Ground Station"' ; USB Product String -D USB_SERIAL="0" ; Enter Device Serial Number here -D USB_VID=0x239A ; Default Adafruit USB VID -D USB_PID=0x80AB ; Default Adafruit USB PID diff --git a/ground_station/src/config.cpp b/ground_station/src/config.cpp index bfa1f964..e20e737d 100644 --- a/ground_station/src/config.cpp +++ b/ground_station/src/config.cpp @@ -75,5 +75,5 @@ void Config::load() { } config.neverStopLogging = stop; - config.receiverMode = static_cast(mode); + config.receiverMode = static_cast(mode); } diff --git a/ground_station/src/config.hpp b/ground_station/src/config.hpp index 239e32ab..ca5582a7 100644 --- a/ground_station/src/config.hpp +++ b/ground_station/src/config.hpp @@ -8,7 +8,7 @@ #include -enum ReceiverTelemetryMode_e : bool { SINGLE = false, DUAL = true }; +enum class ReceiverTelemetryMode : bool { kSingle = false, kDual = true }; // Maximum number of characters for link & test phrases inline constexpr uint32_t kMaxPhraseLen = 16; @@ -16,7 +16,7 @@ inline constexpr uint32_t kMaxPhraseLen = 16; struct systemConfig_t { int16_t timeZoneOffset; bool neverStopLogging; - ReceiverTelemetryMode_e receiverMode; + ReceiverTelemetryMode receiverMode; char linkPhrase1[kMaxPhraseLen + 1]; char linkPhrase2[kMaxPhraseLen + 1]; char testingPhrase[kMaxPhraseLen + 1]; diff --git a/ground_station/src/hmi/hmi.cpp b/ground_station/src/hmi/hmi.cpp index 45ae81c2..0e977827 100644 --- a/ground_station/src/hmi/hmi.cpp +++ b/ground_station/src/hmi/hmi.cpp @@ -481,11 +481,19 @@ void Hmi::settings() { (*static_cast(data_ptr)) = true; configChanged = true; window.updateSettings(settingIndex); + + if (&systemConfig.config.receiverMode == data_ptr) { + console.log.println("telemetry mode changed"); + } } if (leftButton.wasPressed() && *static_cast(data_ptr)) { (*static_cast(data_ptr)) = false; configChanged = true; window.updateSettings(settingIndex); + + if (&systemConfig.config.receiverMode == data_ptr) { + console.log.println("telemetry mode changed"); + } } break; } @@ -530,21 +538,36 @@ void Hmi::settings() { if (backButton.wasPressed()) { state = MENU; + bool closeCurrentFile = false; if (configChanged) { - configChanged = false; - if (systemConfig.config.receiverMode == SINGLE) { + if (systemConfig.config.receiverMode == ReceiverTelemetryMode::kSingle) { + if (strcmp(link1.getLinkPhrase(), systemConfig.config.linkPhrase1) != 0) { + closeCurrentFile = true; + } + // Set both link phrases to the same link1.setLinkPhrase(systemConfig.config.linkPhrase1, kMaxPhraseLen); link2.setLinkPhrase(systemConfig.config.linkPhrase1, kMaxPhraseLen); } else { + if ((strcmp(link1.getLinkPhrase(), systemConfig.config.linkPhrase1) != 0) || + (strcmp(link2.getLinkPhrase(), systemConfig.config.linkPhrase2) != 0)) { + closeCurrentFile = true; + } + // Use two different link phrases link1.setLinkPhrase(systemConfig.config.linkPhrase1, kMaxPhraseLen); link2.setLinkPhrase(systemConfig.config.linkPhrase2, kMaxPhraseLen); } link1.setTestingPhrase(systemConfig.config.testingPhrase, kMaxPhraseLen); + + if (closeCurrentFile) { + recorder.closeCurrentFile(); + } + systemConfig.save(); console.log.println("Save config"); + configChanged = false; } window.initMenu(menuIndex); } diff --git a/ground_station/src/logging/recorder.cpp b/ground_station/src/logging/recorder.cpp index 7f7f142b..b7853bbd 100644 --- a/ground_station/src/logging/recorder.cpp +++ b/ground_station/src/logging/recorder.cpp @@ -4,53 +4,74 @@ #include "recorder.hpp" -bool Recorder::begin() { - int32_t number = 0; +#include "config.hpp" - if (!fatfs.chdir(directory)) { +bool Recorder::begin() { + if (!fatfs.chdir(m_directory)) { console.error.print("[REC] Open directory failed"); - console.error.println(directory); - fatfs.mkdir(&directory[1]); + console.error.println(m_directory); + fatfs.mkdir(&m_directory[1]); console.log.println("[REC] Crating directory"); - if (!fatfs.chdir(directory)) { + if (!fatfs.chdir(m_directory)) { console.error.println("[REC] Open directory failed"); return false; } } - do { - snprintf(fileName, 30, "log_%03ld.csv", number); - number++; - } while (fatfs.exists(fileName)); + setNewFileName(); - queue = xQueueCreate(64, sizeof(RecorderElement)); + m_queue = xQueueCreate(64, sizeof(RecorderElement)); xTaskCreate(recordTask, "task_recorder", 4096, this, 1, nullptr); - initialized = true; - return initialized; + m_initialized = true; + return m_initialized; } void Recorder::createFile() { - file = fatfs.open(fileName, FILE_WRITE); - console.log.println(fileName); - if (!file) { + m_file = fatfs.open(m_fileName, FILE_WRITE); + console.log.println(m_fileName); + console.error.printf("[REC] File %s created\n", m_fileName); + if (!m_file) { console.error.println("[REC] Open file failed"); return; } - fileCreated = true; - file.println( + m_fileCreated = true; + m_file.println( "link,ts[deciseconds],state,errors,lat[deg/10000],lon[deg/10000],altitude[m],velocity[m/" "s],battery[decivolts],pyro1,pyro2"); } +void Recorder::setNewFileName() { + int32_t number = 0; + do { + if (systemConfig.config.receiverMode == ReceiverTelemetryMode::kSingle) { + snprintf(m_fileName, 60, "%s_%03ld.csv", systemConfig.config.linkPhrase1, number); + } else { + snprintf(m_fileName, 60, "%s_%s_%03ld.csv", systemConfig.config.linkPhrase1, systemConfig.config.linkPhrase2, + number); + } + ++number; + } while (fatfs.exists(m_fileName)); + + console.log.printf("[REC] New file name set to %s\n", m_fileName); +} + +void Recorder::closeCurrentFile() { + // Close previously opened file + console.log.printf("[REC] Closing %s\n", m_fileName); + m_file.close(); + console.log.printf("[REC] %s closed\n", m_fileName); + setNewFileName(); +} + void Recorder::recordTask(void *pvParameter) { - auto *ref = static_cast(pvParameter); + auto *rec = static_cast(pvParameter); char line[128]; uint32_t count = 0; RecorderElement element{}; - while (ref->initialized) { - if (xQueueReceive(ref->queue, &element, portMAX_DELAY) == pdPASS) { - if (!ref->fileCreated) { - ref->createFile(); + while (rec->m_initialized) { + if (xQueueReceive(rec->m_queue, &element, portMAX_DELAY) == pdPASS) { + if (!rec->m_fileCreated) { + rec->createFile(); } const auto &data = element.data; const auto pyro1_continuity = static_cast(data.pyro_continuity & 0x01U); @@ -58,12 +79,12 @@ void Recorder::recordTask(void *pvParameter) { snprintf(line, 128, "%hu,%d,%d,%d,%d,%d,%d,%d,%d,%hu,%hu", element.source, data.timestamp, data.state, data.errors, data.lat, data.lon, data.altitude, data.velocity, data.voltage, static_cast(pyro1_continuity), static_cast(pyro2_continuity)); - ref->file.println(line); + rec->m_file.println(line); count++; if (count == 10) { count = 0; - ref->file.sync(); + rec->m_file.sync(); } } } diff --git a/ground_station/src/logging/recorder.hpp b/ground_station/src/logging/recorder.hpp index 306afe77..5f68f7b4 100644 --- a/ground_station/src/logging/recorder.hpp +++ b/ground_station/src/logging/recorder.hpp @@ -4,6 +4,8 @@ #pragma once +#include + #include "telemetry/telemetryData.hpp" #include "utils.hpp" @@ -14,33 +16,34 @@ struct RecorderElement { class Recorder { public: - explicit Recorder(const char* directory) : directory(directory) {} + explicit Recorder(const char* directory) : m_directory(directory) {} bool begin(); - void enable() { enabled = true; } + void enable() { m_enabled = true; } - void disable() { enabled = false; } + void closeCurrentFile(); void record(packedRXMessage* data, uint8_t link_source) { - if (enabled) { + if (m_enabled) { RecorderElement rec_elem = {*data, link_source}; - xQueueSend(queue, &rec_elem, 0); + xQueueSend(m_queue, &rec_elem, 0); } } private: - bool initialized = false; - bool enabled = false; - bool fileCreated = false; + bool m_initialized = false; + bool m_enabled = false; + bool m_fileCreated = false; - const char* directory; + const char* m_directory{nullptr}; - char fileName[30] = {}; + char m_fileName[60] = {}; - QueueHandle_t queue{nullptr}; - File file{}; + QueueHandle_t m_queue{nullptr}; + File32 m_file{}; void createFile(); + void setNewFileName(); static void recordTask(void* pvParameter); }; diff --git a/ground_station/src/main.cpp b/ground_station/src/main.cpp index 5509c718..29bcd960 100644 --- a/ground_station/src/main.cpp +++ b/ground_station/src/main.cpp @@ -26,7 +26,7 @@ void setup() { console.begin(); - if (!utils.begin(0, "DRIVE")) { + if (!utils.begin()) { console.error.println("[MAIN] Could not initialize utilities"); } @@ -45,7 +45,7 @@ void loop() { static bool ini{false}; if (millis() > 5000 && !ini) { ini = true; - if (systemConfig.config.receiverMode == SINGLE) { + if (systemConfig.config.receiverMode == ReceiverTelemetryMode::kSingle) { // Set both link phrases to the same link1.setLinkPhrase(systemConfig.config.linkPhrase1, kMaxPhraseLen); link2.setLinkPhrase(systemConfig.config.linkPhrase1, kMaxPhraseLen); @@ -66,7 +66,7 @@ void loop() { } // In single mode, both antennas track the same rocket - if (systemConfig.config.receiverMode == SINGLE) { + if (systemConfig.config.receiverMode == ReceiverTelemetryMode::kSingle) { const bool link1DataValid = (link1.data.lat() != 0) && (link1.data.lon() != 0); const bool link2DataValid = (link2.data.lat() != 0) && (link2.data.lon() != 0); // Check if data from link 1 is newer than link 2 diff --git a/ground_station/src/telemetry/telemetry.cpp b/ground_station/src/telemetry/telemetry.cpp index 9ac8c7d0..585f1428 100644 --- a/ground_station/src/telemetry/telemetry.cpp +++ b/ground_station/src/telemetry/telemetry.cpp @@ -25,6 +25,8 @@ void Telemetry::setLinkPhrase(const char* phrase, uint32_t length) { void Telemetry::setLinkPhrase(const String& phrase) { setLinkPhrase(phrase.c_str(), phrase.length()); } +const char* Telemetry::getLinkPhrase() { return reinterpret_cast(linkPhrase); } + void Telemetry::setTestingPhrase(const char* phrase, uint32_t length) { memset(testingPhrase, 0, kMaxPhraseLen + 1); memcpy(testingPhrase, phrase, length); diff --git a/ground_station/src/telemetry/telemetry.hpp b/ground_station/src/telemetry/telemetry.hpp index 508424e9..cef2ebe1 100644 --- a/ground_station/src/telemetry/telemetry.hpp +++ b/ground_station/src/telemetry/telemetry.hpp @@ -17,6 +17,8 @@ class Telemetry { void setLinkPhrase(const char* phrase, uint32_t length); void setLinkPhrase(const String& phrase); + const char* getLinkPhrase(); + void setTestingPhrase(const char* phrase, uint32_t length); void setTestingPhrase(const String& phrase);