Skip to content

Feat splitter refactor#30

Merged
nitin710 merged 17 commits intomasterfrom
feat-SplitterRefactor
Sep 11, 2025
Merged

Feat splitter refactor#30
nitin710 merged 17 commits intomasterfrom
feat-SplitterRefactor

Conversation

@Joseph-Jacobson
Copy link
Contributor

@Joseph-Jacobson Joseph-Jacobson commented Jul 14, 2025

Description

  • Supporting testing in conjunction with moving the splitters into EmotiBit sendData
  • Quality of life changes for testing including automatic building

Requirements

To run this branch you need:

  • FeatherWing 1.14.1
  • XPlat 1.7.2
    PR #329

Issues Referenced

None

Documentation update

None

Notes for Reviewer

  • Information on choosing the test on firmware has been added in the Featherwing PR.
  • Added createPacketFixedLengthTest to facilitate testing the splitting.

Testing

Please follow "Mock Data Testing" in the "EmotiBit Feature Test Protocols" document. This has been updated with the new changes

Results

✅Choose between Packet Fixed Length and Sawtooth tests
✅Splits at the desired delimiter

Feature Tests

Feature Test Result
Mock Data Testing ✔️
Packet Fixed Length Test ✔️
Arduino String Test ✔️
Create Packet Test ✔️

Shared files

  • Firmware binary: [Link to firmware binary]
  • Other files.

Checklist to allow merge

  • All dependent repositories used were on branch master
  • Software
    • Get approval from the reviewer
    • Passed testing on Windows
    • Passed testing on macOS (for major changes/GUI changes/ PRs adding files distributed with the EmotiBit software)
    • Passed testing on linux (ubuntu) (for major changes/GUI changes/ PRs adding files distributed with the EmotiBit software)
    • Update software bundle version in ofxEmotiBitVersion.h
  • Firmware
    • Set testingMode to TestingMode::NONE
    • Set const bool DIGITAL_WRITE_DEBUG = false (if set true while testing)
    • Update version in EmotiBit.h
    • Update library.properties to the correct version (should match EmotiBit.h)
  • doxygen style comments included for new code snippets
  • Required documentation updated

Screenshots:

Summary by CodeRabbit

  • New Features

    • Added selectable test data modes, including a fixed-length option, to support more flexible mock data generation.
    • Increased maximum test length from 200 to 512.
  • Tests

    • Improved the mock data test script to automatically run the test executable and generate the expected output before verification.
  • Documentation

    • Expanded Mock Data Test README with a step-by-step workflow and a command reference for choosing test types.
  • Chores

    • Bumped version from 1.7.1 to 1.7.2.

@nitin710 nitin710 changed the base branch from blePrototype-Example to master July 14, 2025 23:49
@Joseph-Jacobson Joseph-Jacobson marked this pull request as ready for review July 16, 2025 16:01
Copy link
Collaborator

@nitin710 nitin710 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the new capability to modify the test type. However, I think there might be a bug that might cause some undefined behavior with string literal comparison. Check out the comments for more information.
Highlighted some more stylistic issues.

- replaced const char* with enum
- extracted 3
- naming
- spacing
@Joseph-Jacobson Joseph-Jacobson requested a review from nitin710 July 29, 2025 22:33
Copy link
Collaborator

@nitin710 nitin710 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See review comments. Otherwise looks good!

Also see the latest PR template, specifically the testing section. Let's conform this PR to that.

Copy link
Collaborator

@produceconsumerobot produceconsumerobot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good. Added some small suggestions and queries.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code readability might be improved to start the conditional with the testType rather than the testCount

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure, but it seems like using <= EmotiBitPacket::maxTestLength might create one extra packet. E.g. if you set maxTestLength = 1, wouldn't it actually create 2 packets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Started with conditional, second comment addressed below

}

// End case to visually signal end of test
else if (testCount == EmotiBitPacket::maxTestLength + 1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxTestLength + 1 also seems to suggest maxTestLength + 1 packets may be created

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The +1 accounts for the "start message"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using testCount is fine, it does the job, but I wonder if having payloadLen as an input would have given a little more transparency into how the input translates into a test packet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to payloadLength as an input

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine to have a "0" marker at the end and I probably wouldn't recommend changing it now because it might require changing in a few places, but I wonder if it's necessary. Could you have just used PACKET_DELIMITER_CSV as the packet-end marker that you search for in the comparison script?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a ToDo

@coderabbitai
Copy link

coderabbitai bot commented Aug 22, 2025

Walkthrough

Version bumped to 1.7.2. Introduced TestType enum and extended createTestDataPacket to accept a test type, adding a fixed-length packet generator. Increased max test length to 512. Updated tests to call the new API, added execution step in test script, and expanded README instructions. Minor formatting tweaks elsewhere.

Changes

Cohort / File(s) Summary of changes
Metadata
library.properties
Bumped version from 1.7.1 to 1.7.2; no other metadata changes.
String formatting
src/ArduinoString.h
Formatting-only indentation change in operator+=; no logic changes.
EmotiBitPacket API & logic
src/EmotiBitPacket.h, src/EmotiBitPacket.cpp
Added enum TestType { FIXED_PACKET_LENGTH, SAWTOOTH }. Updated createTestDataPacket(String&, TestType) (default SAWTOOTH). Added createTestPacketFixedLength(int). Increased maxTestLength to 512. Adjusted start-of-test message text. Integrated branching for SAWTOOTH vs FIXED_PACKET_LENGTH paths.
Tests: docs and runner
tests/MockDataTest/README.md, tests/MockDataTest/scripts/run_test.sh
Expanded README with workflow and command table. Script now runs the built executable before file checks to ensure output exists.
Tests: main
tests/MockDataTest/src/main.cpp
Updated call to createTestDataPacket to pass EmotiBitPacket::TestType::SAWTOOTH.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Tester
  participant Main as tests/MockDataTest main
  participant Packet as EmotiBitPacket
  note over Tester,Main: Test execution (MockDataTest)
  Tester->>Main: Run executable
  Main->>Packet: createTestDataPacket(dataMessage, testType)
  alt testType == SAWTOOTH
    Packet->>Packet: createTestSawtoothData(...)
    Packet-->>Main: dataMessage (sawtooth)
  else testType == FIXED_PACKET_LENGTH
    Packet->>Packet: createTestPacketFixedLength(payloadLength)
    Packet-->>Main: dataMessage (fixed length)
  end
  Main-->>Tester: Output CSV/test packet
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I twitch my whiskers—new tests in sight,
Two paths now blossom: sawtooth’s bite,
Or tidy lengths, all dash-aligned,
A packet parade, precisely designed.
Version hops up—1.7.2—
I thump in joy: “The mocks are true!” 🐇💾

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-SplitterRefactor

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (6)
src/EmotiBitPacket.h (2)

364-367: Doc mismatch: note references isRecording which isn’t part of the API.

createTestDataPacket() doesn’t use an isRecording flag; it relies on internal static state (firstMessage/testCount). Update the note to describe actual behavior, including that the first call emits a begin marker and the (maxTestLength + 1)-th data call emits an end marker.

Suggested replacement:

  • “On first invocation, a begin-of-test packet is emitted. Subsequent invocations emit test packets until maxTestLength is reached. The next invocation emits an end-of-test packet.”

373-377: Param name/docs imply payload length, but implementation targets total packet length.

createTestPacketFixedLength(int payloadLength) subtracts headerString.length() and delimiter overhead to compute dash count, i.e., it makes the total packet length equal to the passed value. If the intent is total packet length, rename the parameter and adjust docs; if the intent is payload length, drop the header length subtraction.

Two options:

  • If total packet length is intended (current behavior), update docs and param name (source-compatible if only used internally):
-//! @param payloadLength payload length of the packet to create
+//! @param packetLength total packet length to create (including header and delimiters)
-static String createTestPacketFixedLength(int payloadLength);
+static String createTestPacketFixedLength(int packetLength);
  • If payload length is intended, adjust implementation to use the number directly and set header.dataLength accordingly.
- int dataLength = payloadLength - (int)headerString.length() - payloadLengthOffset;
+ int dataLength = payloadLength; // payload length equals requested length
src/EmotiBitPacket.cpp (4)

556-567: Clarity: “payloadLength” is the desired total packet length, not payload bytes.

The function computes dataLength by subtracting header length and fixed suffix length, which means the input is a target packet size. Consider renaming the parameter or documenting the contract inline to avoid confusion.

Example:

-String EmotiBitPacket::createTestPacketFixedLength(int payloadLength)
+// desiredTotalLength: target total packet size including header, delimiter, data, and trailing PACKET_DELIMITER_CSV
+String EmotiBitPacket::createTestPacketFixedLength(int desiredTotalLength)
 {
-    int payloadLengthOffset = (String(PAYLOAD_DELIMITER) + "0" + String(PACKET_DELIMITER_CSV)).length();
+    int payloadLengthOffset = (String(PAYLOAD_DELIMITER) + "0" + String(PACKET_DELIMITER_CSV)).length();
     ...
-    int dataLength = payloadLength - (int)headerString.length() - payloadLengthOffset;
+    int dataLength = desiredTotalLength - (int)headerString.length() - payloadLengthOffset;

518-518: Use a non-sensor tag for the end-of-test marker.

Using TypeTag::EDA for the terminal “0” looks like a real EDA sample and can pollute downstream analytics. Prefer USER_NOTE (consistent with the start-of-test) or a dedicated control tag.

Apply this diff:

-        EmotiBitPacket::Header endHeader = EmotiBitPacket::createHeader(EmotiBitPacket::TypeTag::EDA, 0, 0, 1, 0, 0);
+        EmotiBitPacket::Header endHeader = EmotiBitPacket::createHeader(EmotiBitPacket::TypeTag::USER_NOTE, 0, 0, 1, 0, 0);

484-514: Provide a reset path for repeated runs and test-type switching.

firstMessage and testCount are static and never reset, so subsequent runs (or switching test types) won’t emit the start/end markers. Recommend adding a small resetTest() or a bool reset argument to reinitialize these.

If you share the expected UX (e.g., toggling sendTestData, changing test type from the console), I can wire up a minimal resetTest() and reference usage locations.


528-541: Edge-case guard: future-proof against numValues == 1.

If numValues is ever changed to 1, ((numValues - 1)) hits division by zero. Cheap guard keeps this robust.

Apply this diff:

-    int numValues = 10; // Number of values to generate
+    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);
+        int denom = max(1, numValues - 1);
+        int value = minVal + ((maxVal - minVal) * i) / denom;
         payload += value;
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b7ce552 and 0e3750e.

📒 Files selected for processing (7)
  • library.properties (1 hunks)
  • src/ArduinoString.h (1 hunks)
  • src/EmotiBitPacket.cpp (3 hunks)
  • src/EmotiBitPacket.h (2 hunks)
  • tests/MockDataTest/README.md (1 hunks)
  • tests/MockDataTest/scripts/run_test.sh (1 hunks)
  • tests/MockDataTest/src/main.cpp (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
tests/MockDataTest/src/main.cpp (1)
src/EmotiBitPacket.cpp (2)
  • createTestDataPacket (484-524)
  • createTestDataPacket (484-484)
src/EmotiBitPacket.cpp (2)
src/ArduinoString.h (1)
  • String (6-25)
src/EmotiBitPacket.h (1)
  • createPacket (345-360)
src/EmotiBitPacket.h (1)
src/EmotiBitPacket.cpp (6)
  • createTestDataPacket (484-524)
  • createTestDataPacket (484-484)
  • createTestSawtoothData (526-542)
  • createTestSawtoothData (526-526)
  • createTestPacketFixedLength (544-569)
  • createTestPacketFixedLength (544-544)
🪛 Shellcheck (0.10.0)
tests/MockDataTest/scripts/run_test.sh

[warning] 46-46: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

(SC2164)


[warning] 48-48: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

(SC2164)

🪛 LanguageTool
tests/MockDataTest/README.md

[grammar] ~6-~6: There might be a mistake here.
Context: ...ype. A typical workflow will consist of: 1. Going into debug mode 2. Setting sendTes...

(QB_NEW_EN)


[grammar] ~7-~7: There might be a mistake here.
Context: ...ill consist of: 1. Going into debug mode 2. Setting sendTestData to true 3. Choosing...

(QB_NEW_EN)


[grammar] ~8-~8: There might be a mistake here.
Context: ...bug mode 2. Setting sendTestData to true 3. Choosing the Sawtooth test '#' 4. Pressi...

(QB_NEW_EN)


[grammar] ~9-~9: There might be a mistake here.
Context: ...o true 3. Choosing the Sawtooth test '#' 4. Pressing record in the oscilliscope and ...

(QB_NEW_EN)


[grammar] ~10-~10: Ensure spelling is correct
Context: ...ooth test '#' 4. Pressing record in the oscilliscope and waiting for the test to finish 5. C...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~10-~10: There might be a mistake here.
Context: ...scope and waiting for the test to finish 5. Comparing the SD card result with the ba...

(QB_NEW_EN)


[grammar] ~13-~13: There might be a mistake here.
Context: ...ing the extension | Command | Details | |--------|--------| | < | Sets "sendTest...

(QB_NEW_EN)


[grammar] ~14-~14: There might be a mistake here.
Context: ... Command | Details | |--------|--------| | < | Sets "sendTestData" to true| | > |...

(QB_NEW_EN)

🔇 Additional comments (3)
library.properties (1)

2-2: Version bump to 1.7.2 looks consistent with the new test APIs.

No issues from this change alone.

src/ArduinoString.h (1)

71-75: No functional change; operator+= (int) remains correct.

Indent-only tweak; behavior unchanged.

src/EmotiBitPacket.h (1)

257-261: Convert TestType to a scoped enum

All current references use TestType::SAWTOOTH and TestType::FIXED_PACKET_LENGTH, and there are no raw uses of SAWTOOTH or FIXED_PACKET_LENGTH in the codebase. Converting to enum class will preserve existing usage and eliminate potential name collisions.

Locations to update:

  • src/EmotiBitPacket.h (around lines 257–261)

Proposed change:

-enum TestType {
-    FIXED_PACKET_LENGTH,
-    SAWTOOTH
-};
+enum class TestType {
+    FIXED_PACKET_LENGTH,
+    SAWTOOTH
+};

@Joseph-Jacobson
Copy link
Contributor Author

Ready for merge

@nitin710 nitin710 merged commit f6a080a into master Sep 11, 2025
1 check passed
@nitin710 nitin710 deleted the feat-SplitterRefactor branch September 11, 2025 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments