Skip to content

Non-linear position estimation for roller shades/shutters - #671

Open
FredM67 wants to merge 8 commits into
rstrouse:mainfrom
FredM67:feature/nonlinear-position-estimation
Open

Non-linear position estimation for roller shades/shutters#671
FredM67 wants to merge 8 commits into
rstrouse:mainfrom
FredM67:feature/nonlinear-position-estimation

Conversation

@FredM67

@FredM67 FredM67 commented Jul 5, 2026

Copy link
Copy Markdown

Summary

  • Adds a logarithmic position model to correct for the drum-radius effect in roller shades (motor turns at constant angular speed, but fabric speed changes as the drum grows/shrinks)
  • Four new per-shade calibration fields: Up mid-time, Down mid-time, Descend time, Up slat time
  • Two-phase model for roller shutters with tilting blades (linear blade-tilt phase at each end, non-linear drum travel in between)
  • Version-guarded backward-compatible backup format (SHADE_HDR_VER 24 → 25, SHADE_REC_SIZE 276 → 320); old backups load cleanly with all new fields defaulting to 0 (linear behaviour)
  • Pre-built ESP32-S3 firmware and LittleFS bins included

Test plan

  • Upgrade from a v24 backup — verify all existing shade settings load correctly, new fields default to 0
  • Set Up/Down mid-time on a roller shade, observe position tracking improvement mid-travel
  • Set Descend/Up slat time on a roller shutter, verify two-phase boundary behaviour around 1%
  • Download backup, re-upload backup — verify all four new fields round-trip correctly
  • Set all four fields to 0 — verify linear behaviour is restored

Closes #644

🤖 Generated with Claude Code

FredM67 and others added 8 commits July 2, 2026 21:51
Motor speed varies with drum radius as shade material winds/unwinds,
causing linear time-interpolation to misestimate position. Adds two
optional calibration fields (upMidTime, downMidTime) that let users
provide the elapsed time at 50% travel. A logarithmic model (alpha
ratio solved via Newton's method) then replaces the linear formula.
Falls back to existing linear behaviour when mid-time fields are zero.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced fixed max-width:127px on Up/Down Time and 50% mid-time fields
with calc(50% - 10px) / 50% so each pair fills the container width.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces descendTime and upSlatTime to model the two motion phases:
- Descent (slats unrolling) followed by blade tilt to fully close
- Blade opening followed by ascent when raising

Both fields are user-measured timestamps from the movement start,
making them easy to determine with a stopwatch. alphaDown and alphaUp
are now computed against the pure descent/ascent duration only,
excluding the linear blade-tilt phase at each end.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
moveToTarget() silently dropped commands when pos == currentPos,
which prevented position recalibration via slider, MQTT, or Home
Assistant when the shade was already at 0% or 100%. Physical
end-stops are ground truth — always send the command so the motor
can jog to the hard stop and self-correct any position drift.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The four non-linear calibration fields were persisted to NVS and returned
via the JSON API but were missing from the binary config file (ShadeConfigFile).
Bump SHADE_HDR_VER to 25 and SHADE_REC_SIZE to 320, add read/write for the
four fields. Old backups (version ≤ 24) load cleanly with defaults of 0
(linear behaviour).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the drum-radius problem, the four calibration fields
(upMidTime, downMidTime, descendTime, upSlatTime), the two-phase
shutter model, and the special 1% blade-expanded boundary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@FredM67

FredM67 commented Jul 6, 2026

Copy link
Copy Markdown
Author

@rstrouse
Because of reformating, the changes shown in the PR are huge. But in fact, that's not that much.

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.

% of close/open for roller shade is wrong...

1 participant