Conversation
… and community files - Fix BTN_STATE_REPEAT→PRESS transition: reset ticks and repeat counter to prevent incorrect immediate long-press detection after repeat sequences - Add compile-time check for DEBOUNCE_TICKS exceeding 3-bit field maximum - Add version macros (MULTIBUTTON_VERSION 1.1.0) - Add optional thread-safety support via MULTIBUTTON_THREAD_SAFE compile flag - Add unit tests (10 test cases covering all major functionality) - Add CMakeLists.txt for CMake-based builds - Add English README.md, move Chinese docs to README_CN.md - Add GitHub Actions CI (gcc + clang, Make + CMake) - Add CHANGELOG.md, CONTRIBUTING.md, issue/PR templates - Replace emoji in examples with ASCII for terminal compatibility - Expand .gitignore for common build artifacts and IDE files https://claude.ai/code/session_013EiKtprKjkhPtQhGKQW8gD
There was a problem hiding this comment.
Pull request overview
This PR modernizes the MultiButton library by adding a unit test suite and CI/build support, reorganizing documentation (English README + separate Chinese README), and fixing a state-machine issue in the REPEAT→PRESS transition.
Changes:
- Fixed REPEAT→PRESS transition by resetting timing/repeat counters to prevent incorrect behavior.
- Added unit tests plus Make/CMake + GitHub Actions CI to validate core button behaviors.
- Refactored documentation (new concise English README, moved detailed Chinese docs to README_CN).
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test_button.c |
New minimal unit test runner + 10 deterministic state-machine tests. |
multi_button.c |
REPEAT→PRESS bug fix; added optional locking around list operations/ticks. |
multi_button.h |
Added version macros, DEBOUNCE_TICKS compile-time check, and thread-safety lock macro hooks. |
examples/basic_example.c |
Replaced emoji output with ASCII-friendly output. |
examples/advanced_example.c |
Replaced emoji output with ASCII-friendly output. |
examples/poll_example.c |
Replaced emoji output with ASCII-friendly output. |
README.md |
Rewrote into concise English README + quick start + API summary. |
README_CN.md |
Added/moved detailed Chinese documentation into a dedicated file. |
Makefile |
Updated test target to build/run unit tests; added test build rules. |
CMakeLists.txt |
Added CMake build with options for examples/tests and ctest integration. |
.github/workflows/ci.yml |
New CI pipeline (gcc/clang via Make; plus CMake build/test). |
CONTRIBUTING.md |
Added contribution/build/style guidelines. |
CHANGELOG.md |
Added changelog with versioned entries including this release. |
.gitignore |
Expanded ignored build artifacts and IDE/CMake outputs. |
.github/PULL_REQUEST_TEMPLATE.md |
Added PR template. |
.github/ISSUE_TEMPLATE/bug_report.md |
Added bug report template. |
.github/ISSUE_TEMPLATE/feature_request.md |
Added feature request template. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+284
to
+290
| 在 `multi_button_config.h` 中可以自定义以下参数: | ||
|
|
||
| ```c | ||
| #define TICKS_INTERVAL 5 // 定时器中断间隔 (ms) | ||
| #define DEBOUNCE_TIME_MS 15 // 去抖时间 (ms) | ||
| #define SHORT_PRESS_TIME_MS 300 // 短按时间阈值 (ms) | ||
| #define LONG_PRESS_TIME_MS 1000 // 长按时间阈值 (ms) |
Comment on lines
+195
to
+202
| ```c | ||
| void btn1_single_click_handler(void* btn) | ||
| { | ||
| printf("Button 1: Single Click\n"); | ||
| } | ||
|
|
||
| button_attach(&btn1, BTN_SINGLE_CLICK, btn1_single_click_handler); | ||
| ``` |
Comment on lines
+298
to
301
| MULTIBUTTON_LOCK(); | ||
| Button* target; | ||
| for (target = head_handle; target; target = target->next) { | ||
| button_handler(target); |
Comment on lines
+16
to
+28
|
|
||
| #define ASSERT(expr) do { \ | ||
| if (!(expr)) { \ | ||
| printf(" FAIL: %s (line %d)\n", #expr, __LINE__); \ | ||
| return 1; \ | ||
| } \ | ||
| } while(0) | ||
|
|
||
| #define RUN_TEST(fn) do { \ | ||
| tests_run++; \ | ||
| printf(" [%d] %s ... ", tests_run, #fn); \ | ||
| if (fn() == 0) { tests_passed++; printf("OK\n"); } \ | ||
| else { tests_failed++; printf("FAILED\n"); } \ |
| - name: Build library and examples | ||
| run: make all CC=${{ matrix.cc }} | ||
| - name: Run tests | ||
| run: make test |
Comment on lines
+158
to
+160
| # Test dependency | ||
| $(OBJ_DIR)/test_button.o: tests/test_button.c multi_button.h | ||
|
|
- Makefile: Chinese comment -> English - poll_example.c: Unicode bullet (•) -> ASCII dash (-) - test_button.c: Unicode arrow (→) -> ASCII arrow (->) https://claude.ai/code/session_013EiKtprKjkhPtQhGKQW8gD
clang -std=c99 treats implicit function declarations as errors. usleep() requires _DEFAULT_SOURCE feature test macro to be visible in strict C99 mode. Add the define only for example compilation since the library itself has no POSIX dependencies. https://claude.ai/code/session_013EiKtprKjkhPtQhGKQW8gD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR modernizes the MultiButton library with comprehensive unit tests, improved documentation structure, and a critical bug fix in the state machine. The main English README is now concise and beginner-friendly, with the detailed Chinese documentation moved to a separate file. A new test suite validates all major functionality, and a bug in the repeat-to-press state transition has been fixed.
Key Changes
Bug Fix
ticksandrepeatcounter are now properly reset. This prevents incorrect immediate long-press detection after a repeat sequence (the button would incorrectly fireBTN_LONG_PRESS_STARTimmediately upon re-entering PRESS state because ticks was not reset).Documentation
Testing & CI/CD
tests/test_button.c): 10 test cases covering:.github/workflows/ci.yml): Automated testing with gcc and clang, both Make and CMake builds.github/Build System
testtarget runs unit tests instead of just examplesCode Quality
multi_button.h:MULTIBUTTON_VERSION_MAJOR/MINOR/PATCHDEBOUNCE_TICKSdoesn't exceed 3-bit field maximum (7)MULTIBUTTON_THREAD_SAFEcompile flag with lock macros (zero overhead on bare-metal)API Documentation
Implementation Details
The repeat-to-press bug fix in
multi_button.c(lines 214-215) ensures that when a button transitions from the REPEAT state back to PRESS (after being held longer than SHORT_TICKS), the timing counters are reset. This prevents the state machine from immediately triggeringBTN_LONG_PRESS_STARTon the next tick, which would be incorrect behavior.The unit test suite uses a minimal in-house test framework with mock GPIO to drive the state machine deterministically, validating all 7 event types and edge cases without external dependencies.
https://claude.ai/code/session_013EiKtprKjkhPtQhGKQW8gD