diff --git a/.github/workflows/build-and-upload-binaries.yml b/.github/workflows/build-and-upload-binaries.yml index df418dee..3db237d3 100644 --- a/.github/workflows/build-and-upload-binaries.yml +++ b/.github/workflows/build-and-upload-binaries.yml @@ -50,3 +50,10 @@ jobs: name: emotibit-firmware-${{ env.VERSION }} path: firmware_binaries/ retention-days: 30 + + - name: Clean up working directory and downloaded libraries + if: always() + run: | + cd ${{ github.workspace }}/.. + find . -maxdepth 1 -type d ! -name "." ! -name "EmotiBit_FeatherWing" -exec rm -rf {} + + find . -maxdepth 1 -type f -exec rm -f {} + diff --git a/EmotiBit.cpp b/EmotiBit.cpp index 13a46a96..41d50b21 100644 --- a/EmotiBit.cpp +++ b/EmotiBit.cpp @@ -1648,7 +1648,7 @@ uint8_t EmotiBit::update() static uint16_t serialPrevAvailable = Serial.available(); if (Serial.available() > serialPrevAvailable) { - if(Serial.read() == 'F') + if(Serial.peek() == 'F') { #ifdef ARDUINO_FEATHER_ESP32 if(!_sdWrite) // if not writing to SD card @@ -1678,7 +1678,7 @@ uint8_t EmotiBit::update() #endif } - else + else if (!_debugMode) { printEmotiBitInfo(); } @@ -1746,31 +1746,15 @@ uint8_t EmotiBit::update() { dataSendTimer = millis(); + // Perform data calculations in main loop + processData(); + // Send data to SD card and over wireless + sendData(); - - if (_sendTestData) + if (startBufferOverflowTest) { - addTestData(_outDataPackets); - if (getPowerMode() == PowerMode::NORMAL_POWER) - { - _emotiBitWiFi.sendData(_outDataPackets); - } - writeSdCardMessage(_outDataPackets); - _outDataPackets = ""; - } - else - { - // Perform data calculations in main loop - processData(); - - // Send data to SD card and over wireless - sendData(); - - if (startBufferOverflowTest) - { - startBufferOverflowTest = false; - bufferOverflowTest(); - } + startBufferOverflowTest = false; + bufferOverflowTest(); } } @@ -3423,35 +3407,81 @@ void EmotiBit::processData() void EmotiBit::sendData() { + if (_sendTestData) + { + addTestData(_outDataPackets); + } + for (int16_t i = 0; i < (uint8_t)EmotiBit::DataType::length; i++) { - addPacket((EmotiBit::DataType) i); + if (!_sendTestData) + { + addPacket((EmotiBit::DataType) i); + } + if (_outDataPackets.length() > OUT_MESSAGE_TARGET_SIZE) { - // Avoid overrunning our reserve memory - //if (_outDataPackets.length() > 2000) - //{ - // Serial.println(_outDataPackets.length()); - //} + int16_t firstIndex; + firstIndex = 0; + while (firstIndex < _outDataPackets.length()) { + int16_t lastIndex; + //Serial.println(firstIndex); + lastIndex = _outDataPackets.length() - 1; // message.length() - 1 to handle \n + + // Search for the largest packet larger than MAX_SEND_LEN + while (lastIndex - firstIndex > MAX_SEND_LEN - 1) { + // Start at the end of the message and search for a packet delimiter less than MAX_SEND_LEN + lastIndex = _outDataPackets.lastIndexOf(EmotiBitPacket::PACKET_DELIMITER_CSV, lastIndex - 1); + //Serial.println(lastIndex); + if (lastIndex <= firstIndex) + { + // If we don't find a packet less than MAX_SEND_LEN, send the whole thing + lastIndex = _outDataPackets.length() - 1; + break; + } + } + + String s = _outDataPackets.substring(firstIndex, lastIndex + 1); //ToDo:: Consider methods to optimize this - if (getPowerMode() == PowerMode::NORMAL_POWER) - { - _emotiBitWiFi.sendData(_outDataPackets); + if (getPowerMode() == PowerMode::NORMAL_POWER) { + _emotiBitWiFi.sendData(s); + } + writeSdCardMessage(s); + firstIndex = lastIndex + 1; } - //Serial.println("_emotiBitWiFi.sendData()"); - writeSdCardMessage(_outDataPackets); - //Serial.println("writeSdCardMessage()"); _outDataPackets = ""; - } } - if (_outDataPackets.length() > 0) + if (_outDataPackets.length() > 0) //ToDo: Consider removing this check since it only clears the remaining data on the buffer { - if (getPowerMode() == PowerMode::NORMAL_POWER) - { - _emotiBitWiFi.sendData(_outDataPackets); + int16_t firstIndex; + firstIndex = 0; + while (firstIndex < _outDataPackets.length()) { + int16_t lastIndex; + //Serial.println(firstIndex); + lastIndex = _outDataPackets.length() - 1; // message.length() - 1 to handle \n + + // Search for the largest packet larger than MAX_SEND_LEN + while (lastIndex - firstIndex > MAX_SEND_LEN - 1) { + // Start at the end of the message and search for a packet delimiter less than MAX_SEND_LEN + lastIndex = _outDataPackets.lastIndexOf(EmotiBitPacket::PACKET_DELIMITER_CSV, lastIndex - 1); + //Serial.println(lastIndex); + if (lastIndex <= firstIndex) + { + // If we don't find a packet less than MAX_SEND_LEN, send the whole thing + lastIndex = _outDataPackets.length() - 1; + break; + } + } + + String s = _outDataPackets.substring(firstIndex, lastIndex + 1); + + if (getPowerMode() == PowerMode::NORMAL_POWER) { + _emotiBitWiFi.sendData(s); + } + writeSdCardMessage(s); + firstIndex = lastIndex + 1; } - writeSdCardMessage(_outDataPackets); _outDataPackets = ""; } } @@ -3631,22 +3661,24 @@ bool EmotiBit::writeSdCardMessage(const String & s) { if (_sdWrite && s.length() > 0) { if (_dataFile) { - static int16_t firstIndex; - firstIndex = 0; - while (firstIndex < s.length()) { - static int16_t lastIndex; - if (s.length() - firstIndex > MAX_SD_WRITE_LEN) { - lastIndex = firstIndex + MAX_SD_WRITE_LEN; - } - else { - lastIndex = s.length(); - } + if (s.length() > MAX_SEND_LEN) + { + Serial.println("Message too long for SD card write: "); + EmotiBitPacket::Header header = EmotiBitPacket::createHeader( + EmotiBitPacket::TypeTag::DATA_OVERFLOW, + millis(), + _outDataPacketCounter++, + 1, 1, 100); + String data = String(s.length()); + String errorPacket = EmotiBitPacket::createPacket(header, data); + Serial.println(errorPacket); + _dataFile.print(errorPacket); + return false; // ToDo: handle this case + } #ifdef DEBUG_GET_DATA Serial.println("writing to SD card"); #endif // DEBUG - _dataFile.print(s.substring(firstIndex, lastIndex)); - firstIndex = lastIndex; - } + _dataFile.print(s); static uint32_t syncTimer = millis(); if (millis() - syncTimer > targetFileSyncDelay) @@ -3839,8 +3871,8 @@ void EmotiBit::updateBatteryIndication(float battPercent) void EmotiBit::addTestData(String &dataMessage) { - if (_sdWrite){ //only send test data if we are recording - EmotiBitPacket::createTestDataPacket(dataMessage); + if (_sdWrite) { //only send test data if we are recording so testing has sd card files with defined start/stop points for diffing + EmotiBitPacket::createTestDataPacket(dataMessage, _testDataType); } } @@ -3947,6 +3979,10 @@ void EmotiBit::processDebugInputs(String &debugPackets, uint16_t &packetNumber) Serial.println("Press S to reset maxReadSensors metrics"); Serial.println("[ACUTE TESTING MODE] Press n to printEntireNvm"); Serial.println("[ACUTE TESTING MODE] Press N to eraseEeprom"); + Serial.println("Press > to toggle ON Send Test Data"); + Serial.println("Press < to toggle OFF Send Test Data"); + Serial.println("Press @ to toggle Packet Fixed Length Test if Send Test Data is ON"); + Serial.println("Press # to toggle Sawtooth Test Data if Send Test Data is ON"); } else if (c == ':') { @@ -4293,6 +4329,25 @@ void EmotiBit::processDebugInputs(String &debugPackets, uint16_t &packetNumber) _emotibitNvmController.eraseEeprom(); } } + else if (c == '>') { + _sendTestData = true; + Serial.println("Entering Sending Test Data Mode"); + } + else if (c == '<') + { + _sendTestData = false; + Serial.println("Exiting Sending Test Data Mode"); + } + else if (c == '@' && _sendTestData == true) + { + _testDataType = EmotiBitPacket::TestType::FIXED_PACKET_LENGTH; + Serial.println("TestDataType: Fixed Packet Length Test"); + } + else if (c == '#' && _sendTestData == true) + { + _testDataType = EmotiBitPacket::TestType::SAWTOOTH; + Serial.println("TestDataType: Sawtooth Test"); + } } } diff --git a/EmotiBit.h b/EmotiBit.h index 08c6f430..867807f7 100644 --- a/EmotiBit.h +++ b/EmotiBit.h @@ -55,7 +55,7 @@ class EmotiBit { - String firmware_version = "1.14.0"; + String firmware_version = "1.14.1"; @@ -298,7 +298,7 @@ class EmotiBit { static const uint16_t OUT_MESSAGE_RESERVE_SIZE = 2048; static const uint16_t OUT_MESSAGE_TARGET_SIZE = 1024; static const uint16_t DATA_SEND_INTERVAL = 100; - static const uint16_t MAX_SD_WRITE_LEN = 512; // 512 is the size of the sdFat buffer + static const uint16_t MAX_SEND_LEN = 512; static const uint16_t MAX_DATA_BUFFER_SIZE = 48; static const uint16_t NORMAL_POWER_MODE_PACKET_INTERVAL = 200; static const uint16_t LOW_POWER_MODE_PACKET_INTERVAL = 1000; @@ -425,6 +425,7 @@ class EmotiBit { volatile bool _sdWrite; PowerMode _powerMode; bool _sendTestData = false; + EmotiBitPacket::TestType _testDataType = EmotiBitPacket::TestType::SAWTOOTH; // Default to Sawtooth DataType _serialData = DataType::length; volatile bool buttonPressed = false; bool startBufferOverflowTest = false; diff --git a/EmotiBitWiFi.cpp b/EmotiBitWiFi.cpp index 96e556c0..a2728401 100644 --- a/EmotiBitWiFi.cpp +++ b/EmotiBitWiFi.cpp @@ -423,32 +423,10 @@ int8_t EmotiBitWiFi::sendUdp(WiFiUDP& udp, const String& message, const IPAddres return wifiStatus; } - int16_t firstIndex; - firstIndex = 0; - while (firstIndex < message.length()) { - int16_t lastIndex; - //Serial.println(firstIndex); - lastIndex = message.length() - 1; // message.length() - 1 to handle \n - - // Search for the largest packet larger than MAX_SEND_LEN - while (lastIndex - firstIndex > MAX_SEND_LEN - 1) { - // Start at the end of the message and search for a packet delimiter less than MAX_SEND_LEN - lastIndex = message.lastIndexOf(EmotiBitPacket::PACKET_DELIMITER_CSV, lastIndex - 1); - //Serial.println(lastIndex); - if (lastIndex <= firstIndex) - { - // If we don't find a packet less than MAX_SEND_LEN, send the whole thing - lastIndex = message.length() - 1; - break; - } - } - //Serial.println(message.substring(firstIndex, lastIndex)); - for (uint8_t n = 0; n < _nDataSends; n++) { - udp.beginPacket(ip, port); - udp.print(message.substring(firstIndex, lastIndex + 1)); // use lastIndex + 1 to get \n back - udp.endPacket(); - } - firstIndex = lastIndex + 1; // increment substring indexes for breaking up sends + for (uint8_t n = 0; n < _nDataSends; n++) { + udp.beginPacket(ip, port); + udp.print(message); + udp.endPacket(); } return SUCCESS; diff --git a/depends_urls.json b/depends_urls.json index 27658d7f..02d568c3 100644 --- a/depends_urls.json +++ b/depends_urls.json @@ -18,7 +18,7 @@ "Arduino Low Power": "https://github.com/arduino-libraries/ArduinoLowPower", "RTCZero": "https://github.com/arduino-libraries/RTCZero", "Adafruit IS31FL3731 Library": "https://github.com/adafruit/Adafruit_IS31FL3731", - "Adafruit_GFX_Library": "https://github.com/adafruit/Adafruit-GFX-Library", + "Adafruit GFX Library": "https://github.com/adafruit/Adafruit-GFX-Library", "Adafruit BusIO": "https://github.com/adafruit/Adafruit_BusIO" } } diff --git a/download_dependencies.sh b/download_dependencies.sh index ca00639e..694b99bd 100755 --- a/download_dependencies.sh +++ b/download_dependencies.sh @@ -77,11 +77,14 @@ for dep in "${DEPS[@]}"; do if [ -n "$version" ] && [ "$version" != "" ]; then echo " Cloning repository at version: $version" - # Try cloning with v prefix + # Try cloning with v prefix first if git clone --depth 1 --branch "v$version" --single-branch "$github" "$lib_path" 2>/dev/null; then - echo " Cloned at tag: v$version" + echo " Cloned at tag: v$version" + # Try cloning without v prefix + elif git clone --depth 1 --branch "$version" --single-branch "$github" "$lib_path" 2>/dev/null; then + echo " Cloned at tag: $version" else - echo " Warning: Specified version tag 'v$version' not found, cloning default branch" + echo " Warning: Specified version tags 'v$version' and '$version' not found, cloning default branch" git clone --depth 1 "$github" "$lib_path" fi else diff --git a/library.properties b/library.properties index 83369769..904dc66c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=EmotiBit FeatherWing -version=1.14.2 +version=1.14.3 author=Connected Future Labs maintainer=Connected Future Labs sentence=A library written for EmotiBit FeatherWing that supports all sensors included on the wing. @@ -7,4 +7,4 @@ paragraph= Requires dependent libraries as shown in the getting started document category=Sensors url=https://github.com/EmotiBit/EmotiBit_FeatherWing architectures=* -depends=EmotiBit BMI160, EmotiBit MAX30101, EmotiBit MLX90632, EmotiBit NCP5623, EmotiBit SI7013, EmotiBit XPlat Utils, EmotiBit ADS1X15, EmotiBit External EEPROM, EmotiBit EmojiLib, EmotiBit ArduinoFilters, EmotiBit SimpleFTPServer, EmotiBit KTD2026, WiFi101, SdFat (=2.2.0), ArduinoJson (=6.21.2), Arduino Low Power (=1.2.2), RTCZero (=1.6.0), Adafruit IS31FL3731 Library (=2.0.2), Adafruit GFX Library (=1.11.9), Adafruit BusIO (1.15.0) +depends=EmotiBit BMI160, EmotiBit MAX30101, EmotiBit MLX90632, EmotiBit NCP5623, EmotiBit SI7013, EmotiBit XPlat Utils, EmotiBit ADS1X15, EmotiBit External EEPROM, EmotiBit EmojiLib, EmotiBit ArduinoFilters, EmotiBit SimpleFTPServer, EmotiBit KTD2026, WiFi101, SdFat (=2.2.0), ArduinoJson (=6.21.2), Arduino Low Power (=1.2.2), RTCZero (=1.6.0), Adafruit IS31FL3731 Library (=2.0.2), Adafruit GFX Library (=1.11.9), Adafruit BusIO (=1.15.0) diff --git a/testing/PacketFixedLengthTest/README.md b/testing/PacketFixedLengthTest/README.md new file mode 100644 index 00000000..5865a39e --- /dev/null +++ b/testing/PacketFixedLengthTest/README.md @@ -0,0 +1,16 @@ +# Description +- This tests verifies that the Packet Fixed Length Test data in the EmotiBit SD card does not go over the 512 max data length. If there are packets that go over that length, then it will be signified by Debug Overloads. +- The data is verified with the bash script, checking the SD card output + +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 Packet Fixed Length 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 Packet Fixed Length Test| \ No newline at end of file diff --git a/testing/PacketFixedLengthTest/run_test.sh b/testing/PacketFixedLengthTest/run_test.sh new file mode 100644 index 00000000..d4b971d3 --- /dev/null +++ b/testing/PacketFixedLengthTest/run_test.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -u + +EMOTIBIT_CSV="" + +# Parse required -p or --path argument +while [[ $# -gt 0 ]]; do + case "$1" in + -p|--path) + EMOTIBIT_CSV="$2" + shift 2 + ;; + *) + echo "Usage: $0 -p|--path " + exit 1 + ;; + esac +done + +if [[ -z "$EMOTIBIT_CSV" ]]; then + echo "Error: You must specify -p or --path " + exit 1 +fi + +if grep -q ',DO,' "$EMOTIBIT_CSV"; then + echo "DO found in $EMOTIBIT_CSV" + exit 1 +else + echo "No DO found in $EMOTIBIT_CSV" + exit 0 +fi \ No newline at end of file