Generalized-Core-Counter 3.20
Particle-based generalized core counter firmware
Loading...
Searching...
No Matches
PIRSensor.h
Go to the documentation of this file.
1// src/PIRSensor.h
2#ifndef PIRSENSOR_H
3#define PIRSENSOR_H
4
5#include "ISensor.h"
6#include "Particle.h"
7#include "device_pinout.h"
8#include "MyPersistentData.h" // for sysStatus (verboseMode)
9
26class PIRSensor : public ISensor {
27public:
31 static PIRSensor& instance() {
32 static PIRSensor _instance;
33 return _instance;
34 }
35
40 bool setup() override {
41 // Configure PIR-related pins from device_pinout
42 pinMode(intPin, INPUT_PULLDOWN); // PIR interrupt output with pull-down
43 pinMode(disableModule, OUTPUT); // Sensor enable line (active LOW)
44 pinMode(ledPower, OUTPUT); // Sensor indicator LED power
45
46 // Enable sensor and LED by default
47 digitalWrite(disableModule, LOW); // Bring low to turn sensor ON
48 digitalWrite(ledPower, LOW); // Active-LOW: bring low to turn LED ON
49
50 // Attach interrupt on RISING edge (PIR output is active-high).
51 attachInterrupt(intPin, pirISR, RISING);
52
53 reset(); // Ensure SensorData is initialized
54 _isReady = true; // Mark as ready
55 return true; // Return true so device doesn't reset
56 }
57
67 bool loop() override {
68 if (!_isReady) {
69 return false;
70 }
71
72 // If no motion flag, nothing to report
73 if (!_motionDetected) {
74 return false;
75 }
76
77 // Clear flag and apply debounce: ignore events within 500 ms
78 _motionDetected = false;
79 unsigned long nowMs = millis();
80 if (nowMs - _lastEventMs < 500) {
81 return false;
82 }
83 _lastEventMs = nowMs;
84
85 _data.timestamp = Time.now();
86 _data.hasNewData = true;
87 return true;
88 }
89
94 SensorData getData() const override {
95 return _data;
96 }
97
101 const char* getSensorType() const override {
102 return "PIR"; // String literal, no allocation
103 }
104
108 bool isReady() const override {
109 return _isReady;
110 }
111
115 void reset() override {
116 _data = SensorData();
117 strncpy(_data.sensorType, "PIR", sizeof(_data.sensorType) - 1);
118 _data.sensorType[sizeof(_data.sensorType) - 1] = '\0';
119 // Clear any pending motion
120 _motionDetected = false;
121 }
122
126 bool usesInterrupt() const override { return true; }
127
131 void onSleep() override {
132 if (!_isReady) {
133 return;
134 }
135
136 detachInterrupt(intPin);
137 digitalWrite(disableModule, HIGH); // Disable sensor module
138 digitalWrite(ledPower, HIGH); // Active-LOW: bring high to turn LED OFF
139 _isReady = false;
140 Log.info("PIR sensor powered down for sleep");
141 }
142
146 bool onWake() override {
147 // For ULTRA_LOW_POWER naps we normally keep the PIR powered
148 // and its interrupt attached across sleep so it can wake the
149 // MCU. In that case we should NOT clear the motion flag here,
150 // otherwise the wake-causing event is lost before the main
151 // loop can count it.
152
153 pinMode(disableModule, OUTPUT);
154 pinMode(ledPower, OUTPUT);
155 pinMode(intPin, INPUT_PULLDOWN);
156
157 digitalWrite(disableModule, LOW);
158 digitalWrite(ledPower, LOW); // Active-LOW: LED ON after wake
159
160 attachInterrupt(intPin, pirISR, RISING);
161
162 _isReady = true;
163 Log.info("PIR sensor powered up after wake (interrupt attached)");
164 return true;
165 }
166
167private:
168 PIRSensor() : _isReady(false) {
169 strncpy(_data.sensorType, "PIR", sizeof(_data.sensorType) - 1);
170 _data.sensorType[sizeof(_data.sensorType) - 1] = '\0'; // Ensure null termination
171 }
172 ~PIRSensor() {}
173
174 // Prevent copying
175 PIRSensor(const PIRSensor&) = delete;
176 PIRSensor& operator=(const PIRSensor&) = delete;
177
178 bool _isReady;
179 SensorData _data;
180
181 // Debounce state: last accepted motion event time (ms)
182 unsigned long _lastEventMs = 0;
183
184 // PIR-specific state
185 static volatile bool _motionDetected; // Set by ISR, read/cleared in loop()
186 static volatile uint32_t _isrCount; // Counts how many times ISR fired
187
188 // ISR handler
189 static void pirISR();
190};
191
192#endif /* PIRSENSOR_H */
Persistent Data Storage Structures - EEPROM/Retained Memory Management.
Abstract interface for all sensors.
Definition ISensor.h:75
PIR (Passive Infrared) Motion Sensor Implementation.
Definition PIRSensor.h:26
void reset() override
Reset sensor state.
Definition PIRSensor.h:115
static PIRSensor & instance()
Get singleton instance.
Definition PIRSensor.h:31
bool loop() override
Poll the PIR sensor for motion detection.
Definition PIRSensor.h:67
bool isReady() const override
Check if sensor is ready.
Definition PIRSensor.h:108
SensorData getData() const override
Get latest sensor reading.
Definition PIRSensor.h:94
bool setup() override
Initialize the PIR sensor.
Definition PIRSensor.h:40
const char * getSensorType() const override
Get sensor type identifier.
Definition PIRSensor.h:101
bool onWake() override
Wake sensor from deep sleep: power up and re-attach ISR.
Definition PIRSensor.h:146
bool usesInterrupt() const override
This sensor uses a hardware interrupt for motion events.
Definition PIRSensor.h:126
void onSleep() override
Prepare sensor for deep sleep: detach ISR and power down.
Definition PIRSensor.h:131
const pin_t ledPower
const pin_t disableModule
const pin_t intPin
Pinout definitions for the carrier board and sensors.
Generic sensor data structure.
Definition ISensor.h:23
char sensorType[16]
Type of sensor ("PIR", "Ultrasonic", etc.).
Definition ISensor.h:28