diff --git a/library.properties b/library.properties index 11c336e..7fb9717 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=EmotiBit XPlat Utils -version=1.7.1 +version=1.7.2 author=Connected Future Labs maintainer=Connected Future Labs sentence=A Utilities Library required for the successfull operation of EmotiBit FeatherWing and EmotiBit Oscilloscope Library diff --git a/src/ArduinoString.h b/src/ArduinoString.h index 1ea046d..fe81326 100644 --- a/src/ArduinoString.h +++ b/src/ArduinoString.h @@ -70,8 +70,8 @@ namespace EmotiBit String& operator+=(int val) { - str += std::to_string(val); - return *this; + str += std::to_string(val); + return *this; } size_t indexOf(char val, size_t from) const diff --git a/src/EmotiBitPacket.cpp b/src/EmotiBitPacket.cpp index 13b54ff..a3812eb 100644 --- a/src/EmotiBitPacket.cpp +++ b/src/EmotiBitPacket.cpp @@ -117,7 +117,7 @@ const char* const EmotiBitPacket::TypeTagGroups::COMPOSITE_PAYLOAD[] = }; uint8_t EmotiBitPacket::TypeTagGroups::NUM_COMPOSITE_PAYLOAD = sizeof(EmotiBitPacket::TypeTagGroups::COMPOSITE_PAYLOAD) / sizeof(EmotiBitPacket::TypeTagGroups::COMPOSITE_PAYLOAD[0]); -const uint32_t EmotiBitPacket::maxTestLength = 200; // testing value +const uint32_t EmotiBitPacket::maxTestLength = 512; // testing value #ifdef ARDUINO const String EmotiBitPacket::TIMESTAMP_STRING_FORMAT = "%Y-%m-%d_%H-%M-%S-%f"; @@ -481,37 +481,41 @@ EmotiBitPacket::Header EmotiBitPacket::createHeaderWithTime(const string &typeTa #endif -void EmotiBitPacket::createTestDataPacket(String &dataMessage) +void EmotiBitPacket::createTestDataPacket(String &dataMessage, TestType testType) { - //ToDo: Edit function to be more modular in the future so we can add more test data messages - static bool firstMessage = true; - static int testCount = 0; - dataMessage = ""; - + static bool firstMessage = true; + static int testCount = 0; + dataMessage = ""; // First message to signify start of test - if (firstMessage) + if (firstMessage) { firstMessage = false; EmotiBitPacket::Header beginHeader = EmotiBitPacket::createHeader(EmotiBitPacket::TypeTag::USER_NOTE, 0, 0, 1, 0, 0); - String data = String(maxTestLength); + String data = String("Test Length: ") + String(maxTestLength) + EmotiBitPacket::PACKET_DELIMITER_CSV; dataMessage = EmotiBitPacket::createPacket(beginHeader, data); } - - else if (testCount <= EmotiBitPacket::maxTestLength) + //ToDo: Refactor testing structure to be more modular so we can add more tests easily + else if (testType == TestType::SAWTOOTH && testCount <= EmotiBitPacket::maxTestLength) { - int dataLength = 0; + int dataLength = 0; String data = EmotiBitPacket::createTestSawtoothData(dataLength); //Set data first so dataLength is set for the header EmotiBitPacket::Header header = EmotiBitPacket::createTestHeader(dataLength); dataMessage = EmotiBitPacket::createPacket(header, data); - testCount++; - } + testCount++; + } + + else if (testType == TestType::FIXED_PACKET_LENGTH && testCount <= EmotiBitPacket::maxTestLength) // Change splitter to fixedlength + { + dataMessage = EmotiBitPacket::createTestPacketFixedLength(testCount); + testCount++; + } // End case to visually signal end of test else if (testCount == EmotiBitPacket::maxTestLength + 1) { - EmotiBitPacket:: Header endHeader = EmotiBitPacket::createHeader(EmotiBitPacket::TypeTag::EDA, 0, 0, 1, 0, 0); + EmotiBitPacket::Header endHeader = EmotiBitPacket::createHeader(EmotiBitPacket::TypeTag::EDA, 0, 0, 1, 0, 0); String data = String(0); dataMessage = EmotiBitPacket::createPacket(endHeader, data); testCount++; @@ -521,35 +525,63 @@ void EmotiBitPacket::createTestDataPacket(String &dataMessage) String EmotiBitPacket::createTestSawtoothData(int& outLength) { - String payload; + String payload; - int numValues = 10; // Number of values to generate - int minVal = 0; // Minimum value - int maxVal = 100; // Maximum value + int numValues = 10; // Number of values to generate + int minVal = 0; // Minimum value + int maxVal = 100; // Maximum value + for (uint8_t i = 0; i < numValues; ++i) { - if (i > 0) payload += EmotiBitPacket::PAYLOAD_DELIMITER; - int value = minVal + ((maxVal - minVal) * i) / (numValues - 1); - payload += value; - } + if (i > 0) payload += EmotiBitPacket::PAYLOAD_DELIMITER; + int value = minVal + ((maxVal - minVal) * i) / (numValues - 1); + payload += value; + } outLength = numValues; - return payload; + return payload; +} + +String EmotiBitPacket::createTestPacketFixedLength(int payloadLength) +{ + String packet; + String data; + int payloadLengthOffset = (String(PAYLOAD_DELIMITER) + "0" + String(PACKET_DELIMITER_CSV)).length(); + static uint32_t timestamp = 0; + static uint16_t packetNumber = 0; + EmotiBitPacket::Header header = EmotiBitPacket::createHeader(EmotiBitPacket::TypeTag::USER_NOTE, timestamp++, packetNumber++, 1); + + String headerString = EmotiBitPacket::headerToString(header); + + // Calculate number of dashes needed + int dataLength = payloadLength - (int)headerString.length() - payloadLengthOffset; + if (dataLength < 0) dataLength = 0; // Prevent negative + + for (int i = 0; i < dataLength; i++) + { + data += "-"; + } + data += "0"; // Add marker at the end, consider replacing with a packet delimiter + data += EmotiBitPacket::PACKET_DELIMITER_CSV; // Add delimiter + + packet = headerString + EmotiBitPacket::PAYLOAD_DELIMITER + data; + + return packet; } EmotiBitPacket::Header EmotiBitPacket::createTestHeader(uint16_t dataLength) { static uint32_t timestamp = 0; - static uint16_t packetNumber = 0; - static uint8_t protocolVersion = 0; - static uint8_t dataReliability = 0; + static uint16_t packetNumber = 0; + static uint8_t protocolVersion = 0; + static uint8_t dataReliability = 0; - EmotiBitPacket::Header header = EmotiBitPacket::createHeader( - EmotiBitPacket::TypeTag::EDA, + EmotiBitPacket::Header header = EmotiBitPacket::createHeader( + EmotiBitPacket::TypeTag::EDA, timestamp++, - packetNumber++, - dataLength, - protocolVersion++, - dataReliability++ - ); - return header; + packetNumber++, + dataLength, + protocolVersion++, + dataReliability++ + ); + return header; } \ No newline at end of file diff --git a/src/EmotiBitPacket.h b/src/EmotiBitPacket.h index e92c419..28a129e 100644 --- a/src/EmotiBitPacket.h +++ b/src/EmotiBitPacket.h @@ -246,7 +246,6 @@ class EmotiBitPacket { static const char* LSL_LOCAL_CLOCK_TIMESTAMP; static const char* LSL_MARKER_DATA; }; - static const char PACKET_DELIMITER_CSV; static const uint16_t MAX_TO_EMOTIBIT_PACKET_LEN = 255; #ifdef ARDUINO @@ -255,6 +254,11 @@ class EmotiBitPacket { static const string TIMESTAMP_STRING_FORMAT; #endif +enum TestType { + FIXED_PACKET_LENGTH, + SAWTOOTH +}; + EmotiBitPacket(); @@ -357,14 +361,20 @@ class EmotiBitPacket { //! @brief Appends a test data message to the passed dataMessage reference //! @param dataMessage reference to the String to append the test data message to + //! @param testType Type of the test to create data for //! @note Tests will start when isRecording is true, and with the current implementation, the test will end at the end of the test length - static void createTestDataPacket(String &dataMessage); + static void createTestDataPacket(String &dataMessage, TestType testType = TestType::SAWTOOTH); //! @brief Creates a test sawtooth data message //! @param outLength reference to an int to store the length of the created sawtooth data message //! @return String representation of the test sawtooth data message static String createTestSawtoothData(int& outLength); + //! @brief Creates test data that iterates in increasing length to test splitting functionality + //! @param payloadLength payload length of the packet to create + //! @return String representation of the splitter data message + static String createTestPacketFixedLength(int payloadLength); + //! @brief Tests the conversion of headers to a String //! @param dataLength Length of the data to be included in the header diff --git a/tests/MockDataTest/README.md b/tests/MockDataTest/README.md index 3964a7a..266f4be 100644 --- a/tests/MockDataTest/README.md +++ b/tests/MockDataTest/README.md @@ -1,4 +1,17 @@ # Description - This tests verifies that the Mock Data Testing data is identical between the EmotiBit SD card and a generated expected output. - The data is verified with the bash script, comparing the SD card output with the outputed test.csv file from the executable -- Instructions to run this test can be found in the EmotiBit Test Protocols Document under Mock Data Testing \ No newline at end of file +- Instructions to run this test can be found in the EmotiBit Test Protocols Document under Mock Data Testing + +The following table shows commands for choosing the test type. A typical workflow will consist of: +1. Going into debug mode +2. Setting sendTestData to true +3. Choosing the Sawtooth test '#' +4. Pressing record in the oscilliscope and waiting for the test to finish +5. Comparing the SD card result with the bash script, specifying the extension + +| Command | Details | +|--------|--------| +| < | Sets "sendTestData" to true| +| > | Sets "sendTestData" to false| +| # | Sets test data to Sawtooth (this is also the default)| \ No newline at end of file diff --git a/tests/MockDataTest/scripts/run_test.sh b/tests/MockDataTest/scripts/run_test.sh index 652d469..ab6f218 100644 --- a/tests/MockDataTest/scripts/run_test.sh +++ b/tests/MockDataTest/scripts/run_test.sh @@ -43,6 +43,10 @@ if [[ -z "$EMOTIBIT_CSV" ]]; then exit 1 fi +cd "$PROJECT_ROOT/build/Release" +"$EXECUTABLE" +cd "$PROJECT_ROOT/build" + if [[ ! -f "$TEST_FILE" ]]; then echo "Test file not found: $TEST_FILE" exit 1 diff --git a/tests/MockDataTest/src/main.cpp b/tests/MockDataTest/src/main.cpp index 474aa07..83ee07c 100644 --- a/tests/MockDataTest/src/main.cpp +++ b/tests/MockDataTest/src/main.cpp @@ -49,7 +49,7 @@ int main() { } while (x <= EmotiBitPacket::maxTestLength + 2) { // Loop until maxTestLength + 2 to account for the first and last messages - EmotiBitPacket::createTestDataPacket(dataMessage); + EmotiBitPacket::createTestDataPacket(dataMessage, EmotiBitPacket::TestType::SAWTOOTH); testfile << dataMessage.str; x++; }