diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ff1a518
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.pio
+CMakeListsPrivate.txt
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 8822db8..3463fba 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index cb860b6..9ce81f0 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,8 @@
-
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dea4edf..e5b6297 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,77 @@
-cmake_minimum_required (VERSION 2.6)
-project (pooltrainer_firmware)
+# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE
+# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
+#
+# If you need to override existing CMake configuration or add extra,
+# please create `CMakeListsUser.txt` in the root of project.
+# The `CMakeListsUser.txt` will not be overwritten by PlatformIO.
-add_executable(test sessiontest.cpp)
\ No newline at end of file
+cmake_minimum_required(VERSION 3.2)
+project(firmware)
+
+include(CMakeListsPrivate.txt)
+
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeListsUser.txt)
+include(CMakeListsUser.txt)
+endif()
+
+add_custom_target(
+ PLATFORMIO_BUILD ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion run
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_BUILD_VERBOSE ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion run --verbose
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_UPLOAD ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion run --target upload
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_CLEAN ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion run --target clean
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_MONITOR ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion device monitor
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_TEST ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_PROGRAM ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion run --target program
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_UPLOADFS ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion run --target uploadfs
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_UPDATE_ALL ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion update
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_custom_target(
+ PLATFORMIO_REBUILD_PROJECT_INDEX ALL
+ COMMAND ${PLATFORMIO_CMD} -f -c clion init --ide clion
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
diff --git a/SessionChunkIO.h b/SessionChunkIO.h
deleted file mode 100644
index 8df9110..0000000
--- a/SessionChunkIO.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#include
-#include
-
-
-class ESP8266HttpMsgPackWriter {
-public:
- HttpWriterAdaptor(ESP8266WebServer
- * o)
- :
- obj_(o) {}
-
- void write(const char *data, uint32_t size) {
- obj_->sendContent_P(data, size);
- }
-
-private:
- ESP8266WebServer *obj_;
-};
diff --git a/dimensions.txt b/dimensions.txt
new file mode 100644
index 0000000..b9b95cb
--- /dev/null
+++ b/dimensions.txt
@@ -0,0 +1,6 @@
+92 x 28 x 30
+35x20
+
+
+ 95x 50 x 30 (absolute min)
+100 x 55 x 35
\ No newline at end of file
diff --git a/firmware.ino b/firmware.ino
deleted file mode 100644
index 4357902..0000000
--- a/firmware.ino
+++ /dev/null
@@ -1,138 +0,0 @@
-#include "HX711.h"
-#include
-#include // for NTP
-#include // for NTP
-#include
-#include
-
-#include "config.h"
-
-
-int16_t compressMeasurement(int32_t value) {
- return (int16_t)(measurement / DIVIDER)
-}
-
-
-
-HX711 scale;
-WiFiUDP ntpUDP;
-NTPClient timeClient(ntpUDP, "pool.ntp.org");
-TrainingSession session;
-ESP8266WebServer webServer(80);
-
-bool makeMeasurement(long & measurementOut)
-{
- if (scale.is_ready())
- {
- measurementOut = scale.get_value(MEASUREMENT_AVG_COUNT);
- return true;
- }
- else
- return false;
-}
-
-
-void setup()
-{
- digitalWrite(LED_PIN, HIGH);
-
- // Serial
- Serial.begin(115200);
- while(!Serial) {}
-
- // wifi
- WiFi.mode(WIFI_STA);
- WiFi.hostname(HOSTNAME);
- WiFi.begin(WIFI_SSID, WIFI_PASSWD);
-
- Serial.print(F("\n\n"));
- Serial.println(F("Waiting for WIFI connection..."));
- while (WiFi.status() != WL_CONNECTED) {
- delay(1000);
- }
-
- Serial.print(F("Connected to WiFi. IP:"));
- Serial.println(WiFi.localIP());
-
- timeClient.begin();
- timeClient.update();
-
- // initialize cell
- scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
- scale.tare( TARE_AVG_COUNT );
-
- // NTP
- session.init( &timeClient );
- Serial.print("Initialized NTP client: ");
- Serial.println(timeClient.getEpochTime());
-
- // webserver
- webServer.on("/api/session", [] () {
- session.send(&webServer);
- });
- webServer.on("/api/save", [] () {
- webServer.send(200, "text/plain", session.saveToFileSystem());
- });
- webServer.on("/api/tare", [] () {
- scale.tare( TARE_AVG_COUNT );
- webServer.send(200, "text/plain", "OK");
- });
- webServer.on("/", HTTP_GET, [](){
- Serial.println("index.html requested");
- File file = SPIFFS.open("/index.html", "r");
- size_t sent = webServer.streamFile(file, "text/html");
- file.close();
- });
- webServer.on("/swimtrainer.webmanifest", HTTP_GET, [](){
- File file = SPIFFS.open("/swimtrainer.webmanifest", "r");
- size_t sent = webServer.streamFile(file, "application/manifest+json");
- file.close();
- });
-
-
-
- webServer.begin();
- Serial.println("Webserver started");
-
- // flash file system
- if(!SPIFFS.begin()){
- Serial.println("An Error has occurred while mounting SPIFFS");
- }
-}
-
-
-void loop()
-{
- const long cycleStart = millis();
-
-
- digitalWrite(LED_PIN, HIGH);
-
-
- long measurement = 0;
- if(makeMeasurement(measurement))
- {
- session.addPoint(measurement);
- } else {
- Serial.println("Measurement skipped - cell not ready");
- }
-
- webServer.handleClient();
-
- const long cycleDuration = millis() - cycleStart;
- if( cycleDuration <= DELAY)
- {
- delay(DELAY - cycleDuration);
- }
- else
- {
- Serial.print("Skipping measurement, cycle duration was ");
- Serial.println(cycleDuration);
- const long skipped = (cycleDuration / DELAY);
- //for(int i=0; i < skipped; ++i)
- // session.addPoint(0xFFFFFFFE);
-
- delay(DELAY * (skipped + 1) - cycleDuration);
- }
-
-}
\ No newline at end of file
diff --git a/lib/basic/Dtypes.h b/lib/basic/Dtypes.h
new file mode 100644
index 0000000..512fe62
--- /dev/null
+++ b/lib/basic/Dtypes.h
@@ -0,0 +1,17 @@
+inline void _assert(const char* expression, const char* message, const char* file, int line)
+{
+ Serial.print("Assert ");
+ Serial.print(file);
+ Serial.print(" : ");
+ Serial.print(line);
+ Serial.print(" '");
+ Serial.print(expression);
+ Serial.println("' failed.");
+}
+
+template< typename T>
+inline String toString(const T & t) {
+ return String(t);
+}
+
+#define assert(EXPRESSION, MSG) ((EXPRESSION) ? (void)0 : _assert(#EXPRESSION, #MSG, __FILE__, __LINE__))
\ No newline at end of file
diff --git a/MockDtypes.h b/lib/basic/MockDtypes.h
similarity index 100%
rename from MockDtypes.h
rename to lib/basic/MockDtypes.h
diff --git a/MockSerial.h b/lib/basic/MockSerial.h
similarity index 100%
rename from MockSerial.h
rename to lib/basic/MockSerial.h
diff --git a/lib/scale/MockScale.h b/lib/scale/MockScale.h
new file mode 100644
index 0000000..a07a549
--- /dev/null
+++ b/lib/scale/MockScale.h
@@ -0,0 +1,32 @@
+#include
+
+
+class MockScale
+{
+public:
+ MockScale( uint16_t valueMin=0, uint16_t valueMax=50)
+ : valueMin_(valueMin), valueMax_(valueMax), currentValue_(valueMin), direction(1)
+ {}
+
+ bool measure(uint16_t & measurementOut) {
+ currentValue_ += direction;
+ if ( currentValue_ >= valueMax_)
+ direction = -1;
+ else if ( currentValue_ <= valueMin_ )
+ direction = +1;
+
+ measurementOut = currentValue_;
+ return true;
+ }
+
+ void begin(uint32_t , uint32_t ) {
+ };
+
+ void tare(uint32_t ) {
+ }
+private:
+ uint16_t valueMin_;
+ uint16_t valueMax_;
+ uint16_t currentValue_;
+ int direction;
+};
diff --git a/lib/scale/Scale.h b/lib/scale/Scale.h
new file mode 100644
index 0000000..47a7f7c
--- /dev/null
+++ b/lib/scale/Scale.h
@@ -0,0 +1,30 @@
+#include "HX711.h"
+#include
+
+
+template
+class Scale
+{
+public:
+ bool measure(uint16_t & measurementOut) {
+ if (hx711_.is_ready())
+ {
+ uint32_t value = hx711_.get_value(MEASUREMENT_AVG_COUNT);
+ measurementOut = (int16_t)(value / DIVIDER);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ void begin(uint32_t pinDOUT, uint32_t pinSCK) {
+ hx711_.begin(pinDOUT, pinSCK);
+ };
+
+ void tare(uint32_t numMeasurementsToAverage=50) {
+ hx711_.tare(numMeasurementsToAverage);
+ }
+
+private:
+ HX711 hx711_;
+};
diff --git a/session/Session.h b/lib/session/MeasurementSession.h
similarity index 95%
rename from session/Session.h
rename to lib/session/MeasurementSession.h
index e52e036..30e4f51 100644
--- a/session/Session.h
+++ b/lib/session/MeasurementSession.h
@@ -1,12 +1,12 @@
#include "SessionChunk.h"
-template
-class Session {
+template
+class MeasurementSession {
public:
typedef SessionChunk Chunk_T;
- Session()
+ MeasurementSession()
: currentChunk(&chunks[0]),
otherChunk(&chunks[1]) {}
@@ -100,8 +100,9 @@ private:
reader.seek(Chunk_T::template valueOffset());
const uint32_t PART_SIZE = 32;
- static_assert( PART_SIZE < CHUNK_SIZE && CHUNK_SIZE % PART_SIZE == 0);
-
+#ifndef ARDUINO
+ static_assert((PART_SIZE < CHUNK_SIZE) && (CHUNK_SIZE % PART_SIZE == 0));
+#endif
Measurement_T buffer[PART_SIZE];
for(uint32_t i = 0; i < CHUNK_SIZE; i += PART_SIZE)
{
diff --git a/session/MockStorage.h b/lib/session/MockStorage.h
similarity index 100%
rename from session/MockStorage.h
rename to lib/session/MockStorage.h
diff --git a/session/SessionChunk.h b/lib/session/SessionChunk.h
similarity index 97%
rename from session/SessionChunk.h
rename to lib/session/SessionChunk.h
index 9881405..ed16f40 100644
--- a/session/SessionChunk.h
+++ b/lib/session/SessionChunk.h
@@ -1,7 +1,8 @@
#include "StreamingMsgPackEncoder.h"
+#include
-template
+template
class SessionChunk
{
public:
diff --git a/session/SpiffsStorage.h b/lib/session/SpiffsStorage.h
similarity index 92%
rename from session/SpiffsStorage.h
rename to lib/session/SpiffsStorage.h
index d4d625a..2e44b6c 100644
--- a/session/SpiffsStorage.h
+++ b/lib/session/SpiffsStorage.h
@@ -20,7 +20,7 @@ private:
class SpiffsStorageReader
{
public:
- SpiffsBackendReader(const String &fileName) :
+ SpiffsStorageReader(const String &fileName) :
f_(SPIFFS.open(fileName, "w"))
{}
diff --git a/session/StreamingMsgPackEncoder.h b/lib/session/StreamingMsgPackEncoder.h
similarity index 99%
rename from session/StreamingMsgPackEncoder.h
rename to lib/session/StreamingMsgPackEncoder.h
index 5a357ea..efef8cd 100644
--- a/session/StreamingMsgPackEncoder.h
+++ b/lib/session/StreamingMsgPackEncoder.h
@@ -1,3 +1,4 @@
+#pragma once
template struct TypeToMsgPackCode{};
template<> struct TypeToMsgPackCode { static const char CODE; };
diff --git a/platformio.ini b/platformio.ini
new file mode 100644
index 0000000..2e85943
--- /dev/null
+++ b/platformio.ini
@@ -0,0 +1,25 @@
+;PlatformIO Project Configuration File
+;
+; Build options: build flags, source filter
+; Upload options: custom upload port, speed and extra flags
+; Library options: dependencies, extra library storages
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[env:d1]
+platform = espressif8266
+board = d1
+framework = arduino
+monitor_port = /dev/ttyUSB0
+upload_port = /dev/ttyUSB0
+monitor_speed = 115200
+lib_deps =
+ ESP Async WebServer
+ AsyncTCP
+ NTPClient
+
+;[env:native]
+;platform = native
+;test_ignore = test_embedded
diff --git a/src/ConfigHardware.h b/src/ConfigHardware.h
new file mode 100644
index 0000000..8cfbef7
--- /dev/null
+++ b/src/ConfigHardware.h
@@ -0,0 +1,10 @@
+#include
+
+// HX711 load cell
+const int CONFIG_SCALE_DOUT_PIN = D2;
+const int CONFIG_SCALE_SCK_PIN = D3;
+const uint8_t CONFIG_TARE_AVG_COUNT = 50; // number of measurements in tare-phase (to find 0 )
+const int CONFIG_VALUE_DIVIDER = 128; // uint32 measurements are divided by this factor, before stored in uint16_t
+
+
+const uint32_t CONFIG_SESSION_CHUNK_SIZE = 1024*8 - 3 * sizeof(uint32_t);
diff --git a/src/ConfigWifi.h b/src/ConfigWifi.h
new file mode 100644
index 0000000..0e18227
--- /dev/null
+++ b/src/ConfigWifi.h
@@ -0,0 +1,5 @@
+
+
+const char *CONFIG_WIFI_SSID = "WLAN";
+const char *CONFIG_WIFI_PASSWORD = "Bau3rWLAN";
+const char* CONFIG_HOSTNAME = "smartcords";
diff --git a/config.h b/src/config.h
similarity index 64%
rename from config.h
rename to src/config.h
index af74308..0c8d400 100644
--- a/config.h
+++ b/src/config.h
@@ -1,14 +1,5 @@
-// WIFI Parameters
-const char* WIFI_SSID = "RepeaterWZ";
-const char* WIFI_PASSWD = "Bau3rWLAN";
-const char* HOSTNAME = "swimtrainer";
-const bool CORS_HEADER = true;
-// HX711 connection
-const int LOADCELL_DOUT_PIN = D2;
-const int LOADCELL_SCK_PIN = D3;
-const int LED_PIN = D1;
// Measurement parameters
const int DELAY = 100; // interval in ms between measurements
diff --git a/src/firmware_main.cpp b/src/firmware_main.cpp
new file mode 100644
index 0000000..a6a5922
--- /dev/null
+++ b/src/firmware_main.cpp
@@ -0,0 +1,123 @@
+// Arduino & ESP headers
+#include
+#include
+#include
+#include
+#include // for NTP
+#include // for NTP
+
+// Own libs
+#include "Dtypes.h"
+#include "MockScale.h"
+#include "MeasurementSession.h"
+#include "SpiffsStorage.h"
+
+// Configuration
+#include "ConfigWifi.h"
+#include "ConfigHardware.h"
+
+AsyncWebServer server(80);
+WiFiUDP ntpUDP;
+NTPClient timeClient(ntpUDP, "pool.ntp.org");
+
+typedef MeasurementSession Session_T;
+
+template
+class SessionManager
+{
+public:
+ void begin();
+
+ void startMeasurements();
+ void stopMeasurements();
+ void iteration();
+private:
+ MockScale scale;
+ Session_T session;
+};
+
+SessionManager sessionManager;
+
+void onNotFound(AsyncWebServerRequest *request) {
+ request->send(404, "text/plain", "Not found");
+}
+
+template
+void httpSetup(SessionManager * sessionManager)
+{
+ server.on("/api/session/start", HTTP_POST, [sessionManager](AsyncWebServerRequest * req) {
+ req->send(200, "text/plain", F("OK"));
+ sessionManager->startMeasurements();
+ });
+ server.on("/api/session/stop", HTTP_POST, [sessionManager](AsyncWebServerRequest * req) {
+ req->send(200, "text/plain", F("OK"));
+ sessionManager->stopMeasurements();
+ });
+ server.on("/api/session/data", HTTP_GET, [sessionManager](AsyncWebServerRequest * req) {
+ //TODO
+ });
+
+
+ server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
+ request->send(200, "text/plain", "Hello, world");
+ });
+
+ // Send a GET request to /get?message=
+ server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
+ String message;
+ if (request->hasParam(PARAM_MESSAGE)) {
+ message = request->getParam(PARAM_MESSAGE)->value();
+ } else {
+ message = "No message sent";
+ }
+ request->send(200, "text/plain", "Hello, GET: " + message);
+ });
+
+ // Send a POST request to /post with a form field message set to
+ server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
+ String message;
+ if (request->hasParam(PARAM_MESSAGE, true)) {
+ message = request->getParam(PARAM_MESSAGE, true)->value();
+ } else {
+ message = "No message sent";
+ }
+ request->send(200, "text/plain", "Hello, POST: " + message);
+ });
+
+ server.onNotFound(onNotFound);
+
+ server.begin();
+}
+
+void setup()
+{
+ // Serial
+ Serial.begin(115200);
+ while(!Serial) {}
+
+ // WiFi
+ WiFi.mode(WIFI_STA);
+ WiFi.begin(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD);
+ Serial.print(F("\n\n"));
+ Serial.println(F("Waiting for WIFI connection..."));
+ while (WiFi.status() != WL_CONNECTED) {
+ delay(1000);
+ }
+ Serial.print(F("Connected to WiFi. IP:"));
+ Serial.println(WiFi.localIP());
+
+ // NTP
+ timeClient.begin();
+ timeClient.update();
+ session.init( timeClient.getEpochTime() );
+
+ // Scale
+ scale.begin(CONFIG_SCALE_DOUT_PIN, CONFIG_SCALE_SCK_PIN);
+ scale.tare( CONFIG_TARE_AVG_COUNT );
+
+ // HTTP & Websocket server
+ httpSetup();
+}
+
+void loop() {
+}
diff --git a/sessiontest.cpp b/test/test_common/sessiontest.cpp
similarity index 63%
rename from sessiontest.cpp
rename to test/test_common/sessiontest.cpp
index 8777f12..2c9cbb0 100644
--- a/sessiontest.cpp
+++ b/test/test_common/sessiontest.cpp
@@ -1,8 +1,8 @@
#include "MockDtypes.h"
#include "MockSerial.h"
-#include "session/Session.h"
-#include "session/MockStorage.h"
-
+#include "MeasurementSession.h"
+#include "MockStorage.h"
+#include
#include
template
@@ -14,14 +14,15 @@ std::vector parseMessagePack(const uint8_t * data, uint32_t &star
const int expectedMapSize = 3;
auto mapHeader = reinterpret_cast(&data[offset]);
offset += 1;
- assert( *mapHeader == (0b10000000 | expectedMapSize), "Map Header wrong");
+ TEST_ASSERT_MESSAGE( *mapHeader == (0b10000000 | expectedMapSize), "Map Header wrong");
// string255: sessionStartTime
auto stringHeader = reinterpret_cast(&data[offset++]);
auto stringSize = reinterpret_cast(&data[offset++]);
- assert(*stringHeader == '\xd9', "String header wrong");
+
+ TEST_ASSERT_EQUAL(*stringHeader, '\xd9');
std::string sessionStartTimeStr = std::string((const char*)(&data[offset]), (size_t)(*stringSize));
- assert( sessionStartTimeStr == "sessionStartTime", "sessionStartTime string is wrong");
+ TEST_ASSERT( sessionStartTimeStr == "sessionStartTime");
offset += *stringSize;
//uint32
@@ -32,9 +33,9 @@ std::vector parseMessagePack(const uint8_t * data, uint32_t &star
// string255: startIndex
stringHeader = reinterpret_cast(&data[offset++]);
stringSize = reinterpret_cast(&data[offset++]);
- assert(*stringHeader == '\xd9', "String header wrong");
+ TEST_ASSERT_MESSAGE(*stringHeader == '\xd9', "String header wrong");
std::string startIndexStr = std::string((const char*)(&data[offset]), (size_t)(*stringSize));
- assert( startIndexStr == "startIndex", "startIndex string is wrong");
+ TEST_ASSERT_MESSAGE( startIndexStr == "startIndex", "startIndex string is wrong");
offset += *stringSize;
//uint32
@@ -45,14 +46,14 @@ std::vector parseMessagePack(const uint8_t * data, uint32_t &star
// string255: values
stringHeader = reinterpret_cast(&data[offset++]);
stringSize = reinterpret_cast(&data[offset++]);
- assert(*stringHeader == '\xd9', "String header wrong");
+ TEST_ASSERT_MESSAGE(*stringHeader == '\xd9', "String header wrong");
std::string valueStr = std::string((const char*)(&data[offset]), (size_t)(*stringSize));
- assert( valueStr == "values", "values string is wrong");
+ TEST_ASSERT_MESSAGE( valueStr == "values", "values string is wrong");
offset += *stringSize;
// vector
auto vectorHeader = reinterpret_cast(&data[offset++]);
- assert( *vectorHeader == '\xc9', "Vector header wrong");
+ TEST_ASSERT_MESSAGE( *vectorHeader == '\xc9', "Vector header wrong");
size_t vectorLength = ntohl(*reinterpret_cast(&data[offset])) / sizeof(Measurement_T);
offset += 4;
offset += 1; // jump over type
@@ -68,12 +69,12 @@ void testSessionChunkAdd()
SessionChunk chunk;
for( uint16_t i=0; i < size; ++i) {
bool res = chunk.addPoint(i);
- assert(res, "Adding point failed");
- assert( chunk.numMeasurements() == i+1, "Number of measurements reported wrong");
+ TEST_ASSERT_MESSAGE(res, "Adding point failed");
+ TEST_ASSERT_MESSAGE( chunk.numMeasurements() == i+1, "Number of measurements reported wrong");
}
bool res = chunk.addPoint(0);
- assert(!res, "Full chunk was not detected");
- assert(chunk.numMeasurements() == size, "Point appears to be added");
+ TEST_ASSERT_MESSAGE(!res, "Full chunk was not detected");
+ TEST_ASSERT_MESSAGE(chunk.numMeasurements() == size, "Point appears to be added");
}
void testSessionChunkGetterSetter()
@@ -83,8 +84,8 @@ void testSessionChunkGetterSetter()
const uint32_t time = 244213;
const uint32_t startIdx = 131;
chunk.init(time, startIdx);
- assert( chunk.getStartIndex() == startIdx, "Start Index wrong");
- assert( chunk.getStartTime() == time, "Start time wrong");
+ TEST_ASSERT_MESSAGE( chunk.getStartIndex() == startIdx, "Start Index wrong");
+ TEST_ASSERT_MESSAGE( chunk.getStartTime() == time, "Start time wrong");
}
void testSessionChunkSerialization()
@@ -98,8 +99,8 @@ void testSessionChunkSerialization()
chunk.init(startTime, startIndex);
for( uint16_t i=0; i < fillSize; ++i) {
bool res = chunk.addPoint(i);
- assert(res, "Adding point failed");
- assert( chunk.numMeasurements() == i+1, "Number of measurements reported wrong");
+ TEST_ASSERT_MESSAGE(res, "Adding point failed");
+ TEST_ASSERT_MESSAGE( chunk.numMeasurements() == i+1, "Number of measurements reported wrong");
}
std::vector data;
@@ -109,16 +110,16 @@ void testSessionChunkSerialization()
uint32_t readStartTime=0;
uint32_t readStartIndex=0;
auto result = parseMessagePack(&data[0], readStartTime, readStartIndex);
- assert(startIndex == readStartIndex && startTime == readStartTime, "");
- assert(result.size() == fillSize, "Wrong result array size");
+ TEST_ASSERT_MESSAGE(startIndex == readStartIndex && startTime == readStartTime, "");
+ TEST_ASSERT_MESSAGE(result.size() == fillSize, "Wrong result array size");
for( uint16_t i=0; i < fillSize; ++i) {
- assert(result[i] == i, "Wrong array contents");
+ TEST_ASSERT_MESSAGE(result[i] == i, "Wrong array contents");
}
}
void testSession() {
const uint32_t SESSION_SIZE = 128;
- typedef Session MockSession;
+ typedef MeasurementSession MockSession;
const uint32_t startTime = 194842;
const uint_t fillSize = SESSION_SIZE * 4 + 7;
@@ -136,19 +137,40 @@ void testSession() {
uint32_t readStartTime=0;
uint32_t readStartIndex=0;
auto result = parseMessagePack(&data[0], readStartTime, readStartIndex);
- assert(readStartIndex == 0 && startTime == readStartTime, "");
- assert(result.size() == fillSize, "Wrong result array size");
+ TEST_ASSERT_MESSAGE(readStartIndex == 0 && startTime == readStartTime, "");
+ TEST_ASSERT_MESSAGE(result.size() == fillSize, "Wrong result array size");
for( uint16_t i=0; i < fillSize; ++i) {
- assert(result[i] == i, "Wrong array contents");
+ TEST_ASSERT_MESSAGE(result[i] == i, "Wrong array contents");
}
}
+void allTests()
+{
+ UNITY_BEGIN();
+ RUN_TEST(testSessionChunkAdd);
+ RUN_TEST(testSessionChunkGetterSetter);
+ RUN_TEST(testSessionChunkSerialization);
+ RUN_TEST(testSession);
+ UNITY_END();
+}
+
+#ifdef ARDUINO
+void setup() {
+ // NOTE!!! Wait for >2 secs
+ // if board doesn't support software reset via Serial.DTR/RTS
+ delay(2000);
+ allTests();
+}
+
+void loop() {
+}
+
+#else
+
int main(int argc, char**argv)
{
- testSessionChunkAdd();
- testSessionChunkGetterSetter();
- testSessionChunkSerialization();
- testSession();
-
+ allTests();
return 0;
}
+
+#endif
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
new file mode 100644
index 0000000..d0eab02
--- /dev/null
+++ b/todo.txt
@@ -0,0 +1,20 @@
+-> setup platform.io based development with tests
+ - re-write tests with unity
+
+
+
+- backend
+ /api/session/start
+ /api/session/finish
+ /api/session/data?startIndex=25 (returns nothing if no session is active)
+ // by default only the in-memory data is reported back
+
+ /api/sessionhistory/ -> list in webdav fashion
+ /api/sessionhistory/sessionid?startIndex -> returns full session data
+ // delete file with method
+
+
+ // auto start session? ringbuffer with last n measurements
+ // detect spikes -> more than s spikes -> start session
+ // auto stop session if one full chunk is empty
+