Skip to content

Pir fixes - #2227

Open
Sn0w3y wants to merge 7 commits into
openshwprojects:mainfrom
Sn0w3y:pir-fixes
Open

Sn0w3y wants to merge 7 commits into
openshwprojects:mainfrom
Sn0w3y:pir-fixes

Conversation

@Sn0w3y

@Sn0w3y Sn0w3y commented Sep 14, 2026

Copy link
Copy Markdown

No description provided.

ENABLE_DRIVER_PIR was only defined in the WINDOWS/simulator block, so the
driver could not be compiled for BK7231T/BK7231N at all - startDriver PIR
silently did nothing on those chips.
The driver passed SPECIAL_CHANNEL_FLASHVARS_LAST (264) and its neighbours
straight into HAL_FlashVars_SaveChannel(), which takes a raw slot index in
range <0, MAX_RETAIN_CHANNELS) - 12 on every platform. Every save therefore
hit the range check and returned without writing anything, and every read
came back as 0. On-time, sensitivity, light threshold and mode were lost on
each power cycle and had to be entered again.

The SPECIAL_CHANNEL_FLASHVARS_* constants are only understood by
CHANNEL_Set/CHANNEL_Get, which subtract SPECIAL_CHANNEL_FLASHVARS_FIRST
first. Use plain slot indices 0..3 instead; the LED driver's remembered
state occupies the last four slots, so there is no overlap, and a compile
time check keeps it that way.

Also apply sane defaults when nothing has been stored yet (an on-time of 0
would switch the lamp off immediately), only write on an actual change to
spare the flash, and stop calling CHANNEL_Get(-1) when no sensor pin is
mapped.
Re-triggering was gated on g_isDark. As soon as the lamp switched on, its
own light reached the light sensor, g_isDark went false and no further
motion could extend the timer. The lamp switched off with someone still in
the room, went dark, immediately re-triggered and switched on again -
a blink cycle for as long as anybody was moving.

The light level now only gates switching the lamp ON; while it is already
on, motion alone keeps it on.
Gives a few seconds of warning before the on-time expires, so you can wave
and keep the light on instead of being left in the dark. Motion during the
warning aborts it and restores the full on-time.

The sequence is driven from runQuickTick (25 ms), which the PIR driver did
not use before; the one second tick is too coarse for a blink.
The sensitivity is written to a PWM_ScriptOnly pin. When that pin uses the
inverted _n role, new_pins.c drives it with (100 - value), so a slider
setting of 1 arrived at the PIR module as 99% duty - the slider meant the
exact opposite of what it showed. Pre-invert in the driver so the value the
user sets is the duty cycle that reaches the hardware, and show that duty
in the web UI.

NOTE for existing users with an inverted sensitivity pin: the stored value
now means the opposite of what it did before. To keep the previous physical
behaviour, replace the stored sensitivity S with (100 - S) once.
PIR_OnChannelChanged was empty, so motion was only ever evaluated in the
one second tick. That cost up to a second of delay, and worse, a short PIR
pulse falling between two ticks was missed completely - the lamp simply did
not come on.

The motion input is scanned by PIN_ticks every 25 ms and CHANNEL_Set feeds
DRV_OnChannelChanged, so handling it there reacts right away. The per-second
poll stays for the opposite case: while the input remains high there is no
channel change and therefore no callback.
The raw ADC value jitters by a few counts, so right at the threshold
isDark flipped every second and the lamp could not settle. Average the
reading over eight seconds and require the average to move clearly past
the threshold before changing state.

The width of that band is configurable from the web UI as "Light
Hysteresis" and is stored alongside the other PIR settings. The page also
shows the raw and averaged value and the resulting dark/bright decision,
which makes the threshold much easier to set.
@openshwprojects

Copy link
Copy Markdown
Owner

We could merge it but we need compile/test errors fixes first

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.

2 participants