aboutsummaryrefslogtreecommitdiff
path: root/test_fw/src/sd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test_fw/src/sd.cpp')
-rw-r--r--test_fw/src/sd.cpp158
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
+}