Bounds Finding Cache System
Overview
The Bounds Caching System allows independent bounds finding, keeping the motor ready for immediate test starts. This improves workflow efficiency by eliminating redundant bounds finding when running multiple tests in succession.
Key Features
- Independent Bounds Finding: Run
boundscommand separately from test start - Time-Based Validity: Bounds remain valid for a configurable window (default: 2 minutes)
- Motor State Management: Motor stays energized during validity window, de-energizes after timeout
- Automatic De-energization: Prevents motor overheating during idle periods
- Skip Redundant Finding:
startcommand uses cached bounds if still valid
Commands
bounds
Run bounds finding independently without starting the test.
1
2
3
4
5
6
7
8
9
10
> bounds
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BOUNDS FINDING β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β Bounds finding started... β
β Motor will stay energized after completion. β
β Validity window: 2 minutes β
β β
β Run 'start' within validity window to skip bounds finding. β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
start (with cache)
When bounds are cached and valid:
1
2
3
> start
[FatigueTestUnit] Using cached bounds (valid for 85 more seconds)
[FatigueTestUnit] Test started immediately (no bounds finding)
When bounds are expired or not found:
1
2
3
> start
[FatigueTestUnit] Bounds not cached or expired - running bounds finding
[FatigueTestUnit] Starting bounds finding...
status (shows cache info)
1
2
3
4
5
6
7
8
9
10
11
12
13
> status
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MOTION STATUS β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β State: IDLE β
β Bounded: YES β
β Frequency: 0.50 Hz β
β ... β
β β
β BOUNDS CACHE: β
β Status: Valid (85 sec remaining) β
β Motor: Energized (ready for start) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
State Diagram
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
βββββββββββββββββββββββ
β Motor De-energized β
β Bounds Invalid β
ββββββββββββ¬βββββββββββ
β
βββββββββββββββββββββββββββΌββββββββββββββββββββββββββ
β β β
bounds command start command config change
β β β
βΌ βΌ β
ββββββββββββββββ ββββββββββββββββ β
β BOUNDS β β BOUNDS β β
β FINDING β β FINDING β β
ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β β
bounds found bounds found β
β β β
βΌ βΌ β
ββββββββββββββββββββ ββββββββββββββββ β
β IDLE β β RUNNING β β
β Motor Energized β β Test Active β β
β Timer Started β β Timer Paused β β
ββββββββββ¬ββββββββββ ββββββββ¬ββββββββ β
β β β
βββββββββ΄ββββββββ test complete β
β β β β
timeout start β β
2min command β β
β β β β
βΌ βΌ βΌ β
ββββββββββββββ ββββββββββββ ββββββββββββββββ β
β Motor β β RUNNING β β Motor β β
β De-energizedβ β (no β β De-energized β β
β Bounds β β bounds β β Bounds Valid β β
β Expired β β needed) β β (for next β β
ββββββββββββββ ββββββββββββ β quick start) β β
ββββββββ¬ββββββββ β
β β
timeout orββββββββββββββββββββββ
next start
Configuration
Default Validity Window
1
2
3
namespace BoundsCache {
static constexpr uint32_t DEFAULT_VALIDITY_MINUTES = 2;
}
Changing Validity at Runtime
1
2
// Set validity to 5 minutes
BoundsCache::SetValidityMinutes(5);
Compile-Time Configuration
Modify DEFAULT_VALIDITY_MINUTES in main.cpp to change the default:
1
static constexpr uint32_t DEFAULT_VALIDITY_MINUTES = 5; // 5 minutes
API Reference
BoundsCache Namespace
| Function | Description |
|---|---|
Init() |
Initialize the bounds cache system (create timer) |
AreBoundsValid() |
Check if cached bounds are still valid |
GetRemainingValiditySec() |
Get seconds remaining in validity window |
MarkBoundsFound() |
Mark bounds as found, start de-energize timer |
CancelDeenergizeTimer() |
Cancel timer (e.g., when test starts) |
InvalidateBounds() |
Force invalidation (e.g., on config change) |
SetValidityMinutes(uint32_t) |
Change validity window |
Global Variables
| Variable | Description |
|---|---|
g_bounds_validity_us |
Validity window in microseconds |
g_bounds_timestamp_us |
Timestamp when bounds were last found |
g_motor_energized_for_bounds |
Whether motor is energized from bounds finding |
g_deenergize_timer |
ESP timer handle for de-energize callback |
Workflow Examples
Quick Iteration Workflow
For testing different settings rapidly:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. Find bounds once
> bounds
# 2. Run first test
> start
# 3. Wait for completion or stop
> stop
# 4. Adjust settings
> set -f 0.7
# 5. Start again immediately (bounds still valid)
> start
Standard Test Workflow
For production testing:
1
2
3
4
5
6
7
8
# 1. Configure test parameters
> set -f 0.5 -c 1000 -b -60 60
# 2. Start test (bounds found automatically)
> start
# 3. Monitor progress
> status
Pre-Flight Check Workflow
For verification before actual testing:
1
2
3
4
5
6
7
8
# 1. Run bounds to verify mechanism works
> bounds
# 2. Check status shows valid bounds
> status
# 3. If satisfied, start test
> start
Timing Details
De-energize Timer
- Type: One-shot ESP timer
- Resolution: Microseconds (from
esp_timer_get_time()) - Callback context: ESP timer task (not ISR safe, can call motor functions)
Critical Timing Scenarios
| Scenario | Timer Behavior |
|---|---|
bounds completes |
Timer started for 2 minutes |
start with valid cache |
Timer cancelled, test runs |
| Timer expires (idle) | Motor de-energized, bounds marked expired |
stop during test |
Timer NOT restarted (bounds stay valid) |
| Config change | Timer cancelled, bounds invalidated |
Safety Considerations
Motor Heating Prevention
The de-energize timer ensures the motor doesnβt remain energized indefinitely:
- After bounds finding, motor stays energized (holding torque applied)
- If no test starts within validity window, motor is disabled
- This prevents motor and driver overheating during extended idle periods
Power-On State
At boot:
- Motor starts disabled
- Bounds are invalid
- First
startorboundscommand will energize and find bounds
Error Recovery
If bounds finding fails:
- Motor is disabled immediately
- Bounds remain invalid
- Next
startwill retry bounds finding
Troubleshooting
Bounds Keep Expiring Too Fast
Cause: Validity window too short for your workflow.
Solution: Increase validity window:
1
BoundsCache::SetValidityMinutes(5); // 5 minutes
Motor De-energizes Unexpectedly
Cause: Validity timer expired.
Solution: Run bounds again or start test before timeout.
Start Runs Bounds Even Though Recently Found
Possible Causes:
- Config was changed (invalidates bounds)
- Timer expired
- Motor was manually disabled
Solution: Check status command for bounds cache state.
Motor Stays Energized After Stop
Expected Behavior: After stop, bounds remain valid but motor stays energized for the remaining validity window to allow quick restart.
To force motor disable: Wait for timeout, or change configuration.