DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
sen0192.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file sen0192.cpp
6 * @brief SEN0192 microwave motion sensor - debounced presence tracker + GPIO binding. See sen0192.h.
7 */
8
10
11#if DETWS_ENABLE_SEN0192
12
13// ---------------------------------------------------------------------------
14// Pure presence state machine (host-tested).
15// ---------------------------------------------------------------------------
16
17void sen0192_motion_init(Sen0192Motion *m, uint32_t hold_ms, bool active_high)
18{
19 m->present = false;
20 m->seeded = false;
21 m->active_high = active_high;
22 m->hold_ms = hold_ms;
23 m->last_active_ms = 0;
24 m->motion_events = 0;
25}
26
27bool sen0192_motion_update(Sen0192Motion *m, bool level_high, uint32_t now_ms)
28{
29 bool active = (level_high == m->active_high);
30 if (active)
31 {
32 m->last_active_ms = now_ms;
33 m->seeded = true;
34 if (!m->present)
35 {
36 m->present = true;
37 m->motion_events++;
38 return true; // clear -> present edge
39 }
40 return false;
41 }
42 sen0192_motion_tick(m, now_ms); // inactive sample: presence may age out
43 return false;
44}
45
46bool sen0192_motion_tick(Sen0192Motion *m, uint32_t now_ms)
47{
48 if (m->present && m->seeded && (uint32_t)(now_ms - m->last_active_ms) > m->hold_ms)
49 m->present = false;
50 return m->present;
51}
52
53bool sen0192_motion_present(const Sen0192Motion *m)
54{
55 return m->present;
56}
57
58uint32_t sen0192_motion_events(const Sen0192Motion *m)
59{
60 return m->motion_events;
61}
62
63uint32_t sen0192_motion_active_age_ms(const Sen0192Motion *m, uint32_t now_ms)
64{
65 return m->seeded ? (uint32_t)(now_ms - m->last_active_ms) : 0;
66}
67
68// ---------------------------------------------------------------------------
69// ESP32 GPIO binding
70// ---------------------------------------------------------------------------
71
72#if defined(ARDUINO)
73
74#include "services/clock.h" // detws_millis()
75#include <Arduino.h>
76
77namespace
78{
79// The SEN0192 binding state, owned by one instance (internal linkage): the presence tracker and the pin.
80struct Sen0192Ctx
81{
82 Sen0192Motion motion;
83 int pin = -1;
84};
85Sen0192Ctx s_sen;
86} // namespace
87
88bool sen0192_begin(void)
89{
90 s_sen.pin = DETWS_SEN0192_PIN;
91 pinMode(s_sen.pin, INPUT);
92 sen0192_motion_init(&s_sen.motion, DETWS_SEN0192_HOLD_MS, DETWS_SEN0192_ACTIVE_HIGH != 0);
93 return true;
94}
95
96bool sen0192_poll(void)
97{
98 if (s_sen.pin < 0)
99 return false;
100 bool level = digitalRead(s_sen.pin) != 0;
101 return sen0192_motion_update(&s_sen.motion, level, detws_millis());
102}
103
104bool sen0192_present(void)
105{
106 sen0192_motion_tick(&s_sen.motion, detws_millis()); // age presence out even between poll()s
107 return sen0192_motion_present(&s_sen.motion);
108}
109
110uint32_t sen0192_motion_count(void)
111{
112 return sen0192_motion_events(&s_sen.motion);
113}
114
115#else // host build: no GPIO. The presence state machine above is host-tested.
116
117bool sen0192_begin(void)
118{
119 return false;
120}
121bool sen0192_poll(void)
122{
123 return false;
124}
125bool sen0192_present(void)
126{
127 return false;
128}
129uint32_t sen0192_motion_count(void)
130{
131 return 0;
132}
133
134#endif // ARDUINO
135
136#endif // DETWS_ENABLE_SEN0192
#define DETWS_SEN0192_PIN
GPIO the SEN0192 OUT line is wired to.
#define DETWS_SEN0192_ACTIVE_HIGH
SEN0192 OUT polarity: 1 = the OUT line reads HIGH on motion, 0 = active-LOW.
#define DETWS_SEN0192_HOLD_MS
Presence is held this many ms after the last active (motion) sample before it clears.
Pluggable monotonic clock for all library timing.
uint32_t detws_millis(void)
The library's monotonic time at 1000 Hz (milliseconds).
Definition clock.h:71
DFRobot SEN0192 10.525 GHz microwave Doppler motion sensor (DETWS_ENABLE_SEN0192).