diff options
Diffstat (limited to 'test_fw/src/sd.cpp')
| -rw-r--r-- | test_fw/src/sd.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/test_fw/src/sd.cpp b/test_fw/src/sd.cpp new file mode 100644 index 0000000..486c347 --- /dev/null +++ b/test_fw/src/sd.cpp @@ -0,0 +1,158 @@ +#include <Arduino.h> +#include <etl/vector.h> + +#include "channel.h" +#include "log.h" +#include "board.h" + +#define ENABLE_SD 0 + +#if ENABLE_SD +#define SDCARD_SPI SD_SPI +#include <SD.h> +static SDClass sd; +#endif + + +void setup1() { + while (MEAS_CHANNEL == nullptr) + { + delay(5); + } +} + +inline const char* name_for_meas(Measurement meas) +{ + switch (meas) + { + case Measurement::LUX: + return "lux"; + case Measurement::TEMP: + return "temp"; + case Measurement::HUM: + return "hum"; + case Measurement::PRES: + return "pres"; + case Measurement::GAS: + return "gas"; + case Measurement::AX: + return "ax"; + case Measurement::AY: + return "ay"; + case Measurement::AZ: + return "az"; + case Measurement::GX: + return "gx"; + case Measurement::GY: + return "gy"; + case Measurement::GZ: + return "gz"; + +#if USE_BSEC + case Measurement::CO2: + return "co2"; + case Measurement::IAQ: + return "iaq"; +#endif + + default: + return "unknown"; + } +} + +void loop1() { + static etl::vector<Message, 128> chunk; + + while (chunk.available() > chunk.capacity() / 2) + { + Message read; + if (!xQueueReceive(MEAS_CHANNEL, &read, portMAX_DELAY)) + { + LOGGER.println("failed to receive message from channel"); + continue; + } + + chunk.push_back(read); + + if (LOGGER) + { + for (int i = 0; i < static_cast<size_t>(Measurement::MAX); i++) + { + const auto name = name_for_meas(static_cast<Measurement>(i)); + const auto& value = read.measurement[i]; + + // This awkwardness is to support the fact that the RTT implementation + // doesn't support formatting floats and instead silently fails -- manually + // format first, then printf the string. + char buf[32]; + snprintf(buf, sizeof(buf), "%s:%f,", name, value); + + LOGGER.printf("%s", buf); + } + + LOGGER.println(); + } + } + +#if !ENABLE_SD + chunk.clear(); + return; +#endif + +#if ENABLE_SD + constexpr auto sd_period = 50; + static unsigned int sd_last_connect = 0; + static bool sd_connected = false; + + if (!digitalRead(CARD_DETECT)) + { + sd_connected = false; + analogWrite(LED_CAPTURING, 0); + return; + } + + if (millis() - sd_last_connect > sd_period && !sd_connected) + { + sd_last_connect = millis(); + + if (!sd.begin(SD_CS)) + { + LOGGER.println("failed connection to sd card"); + sd_connected = false; + analogWrite(LED_CAPTURING, 0); + return; + } + + sd_connected = true; + analogWrite(LED_CAPTURING, 24); + } + + auto data = sd.open("data.csv", O_CREAT | O_WRITE | O_APPEND); + if (data.size() == 0) + { + data.write("uptime_ms,"); + + for (int i = 0; i < static_cast<size_t>(Measurement::MAX); i++) + { + const auto name = name_for_meas(static_cast<Measurement>(i)); + data.printf("%s,", name); + } + + data.print('\n'); + } + + for (const auto& m : chunk) + { + data.printf("%d,", m.uptime); + + for (const auto &value : m.measurement) + { + data.printf("%f,", value); + } + + data.print('\n'); + } + + data.close(); +#endif +} |
