muwerk mupplet Sensor Library
muwerk applets; mupplets: functional units that support specific hardware or reusable applications for sensors
Loading...
Searching...
No Matches
mup_analog_sensor.h
1// mup_analog_sensor_ad.h
2#pragma once
3
4#include "scheduler.h"
5#include "sensors.h"
6
7namespace ustd {
8
50// clang-format on
52 private:
53 String AnalogSensor_VERSION = "0.1.0";
54 Scheduler *pSched;
55 int tID;
56 String name;
57 uint8_t analogPort;
58 String topicName;
59 double analogSensorValue;
60 double linTransA = 1.0; // a*x+b linear transformation of measured values, default no change.
61 double linTransB = 0.0;
62 unsigned long basePollRate = 500000L;
63 uint32_t pollRateMs = 2000;
64 uint32_t lastPollMs = 0;
65 bool bActive = false;
66 bool initialPublish = false;
67#ifdef __ESP32__
68 double adRange = 4096.0; // 12 bit default
69#else
70 double adRange = 1024.0; // 10 bit default
71#endif
72
73 public:
74 enum FilterMode { FAST,
75 MEDIUM,
76 LONGTERM };
77 FilterMode filterMode;
78 ustd::sensorprocessor analogSensor = ustd::sensorprocessor(4, 600, 0.005);
79
80 AnalogSensor(String name, uint8_t analogPort, FilterMode filterMode = FilterMode::MEDIUM, String topicName = "")
81 : name(name), analogPort(analogPort), topicName(topicName), filterMode(filterMode) {
88 setFilterMode(filterMode, true);
89 }
90
92 }
93
98 return analogSensorValue;
99 }
100
101 void begin(Scheduler *_pSched, uint32_t _pollRateMs = 2000, double _linTransA = 1.0, double _linTransB = 0.0) {
117 pSched = _pSched;
118 pollRateMs = _pollRateMs;
119 linTransA = _linTransA;
120 linTransB = _linTransB;
121 initialPublish = false;
122
123 auto ft = [=]() { this->loop(); };
124 tID = pSched->add(ft, name, basePollRate);
125
126 auto fnall = [=](String topic, String msg, String originator) {
127 this->subsMsg(topic, msg, originator);
128 };
129 pSched->subscribe(tID, name + "/sensor/#", fnall);
130 pSched->subscribe(tID, name + "/mqtt/state", fnall);
131 bActive = true;
132 }
133
134 void setFilterMode(FilterMode mode, bool silent = false) {
135 switch (mode) {
136 case FAST:
137 filterMode = FAST;
138 analogSensor.update(1, 15, 0.001);
139 break;
140 case MEDIUM:
141 filterMode = MEDIUM;
142 analogSensor.update(4, 300, 0.005);
143 break;
144 case LONGTERM:
145 default:
146 filterMode = LONGTERM;
147 analogSensor.update(50, 600, 0.01);
148 break;
149 }
150 if (!silent)
151 publishFilterMode();
152 }
153
154 private:
155 void publishAnalogSensor() {
156 char buf[32];
157 sprintf(buf, "%5.3f", analogSensorValue);
158 pSched->publish(name + "/sensor/unitanalogsensor", buf);
159 if (topicName != "unitanalogsensor" && topicName != "") {
160 pSched->publish(name + "/sensor/" + topicName, buf);
161 }
162 }
163
164 void publishFilterMode() {
165 switch (filterMode) {
166 case FilterMode::FAST:
167 pSched->publish(name + "/sensor/mode", "FAST");
168 break;
169 case FilterMode::MEDIUM:
170 pSched->publish(name + "/sensor/mode", "MEDIUM");
171 break;
172 case FilterMode::LONGTERM:
173 pSched->publish(name + "/sensor/mode", "LONGTERM");
174 break;
175 }
176 }
177
178 void loop() {
179 if (bActive) {
180 if (timeDiff(lastPollMs, millis()) >= pollRateMs || !initialPublish) {
181 bool hasChanged = false;
182 lastPollMs = millis();
183 double val = analogRead(analogPort) / (adRange - 1.0);
184 if (val < 0.0) val = 0.0;
185 if (val > 1.0) val = 1.0;
186 if (linTransA != 1.0 || linTransB != 0.0) {
187 val = linTransA * val + linTransB;
188 }
189 if (analogSensor.filter(&val) || !initialPublish) {
190 analogSensorValue = val;
191 hasChanged = true;
192 }
193 if (hasChanged) {
194 publishAnalogSensor();
195 initialPublish = true;
196 }
197 }
198 }
199 }
200
201 void subsMsg(String topic, String msg, String originator) {
202 if (topic == name + "/sensor/unitanalogsensor/get" || topic == name + "/sensor/" + topicName + "/get") {
203 publishAnalogSensor();
204 } else if (topic == name + "/sensor/mode/get") {
205 publishFilterMode();
206 } else if (topic == name + "/sensor/mode/set") {
207 if (msg == "fast" || msg == "FAST") {
208 setFilterMode(FilterMode::FAST);
209 } else {
210 if (msg == "medium" || msg == "MEDIUM") {
211 setFilterMode(FilterMode::MEDIUM);
212 } else {
213 setFilterMode(FilterMode::LONGTERM);
214 }
215 }
216 } else if (topic == name + "mqtt/state") {
217 if (msg == "connected") {
218 initialPublish = false; // republish for mqtt.
219 }
220 }
221 };
222}; // analogsensorAD
223
224} // namespace ustd
mupplet-sensor analog sensor sensor
Definition: mup_analog_sensor.h:51
double getUnitAnalogSensor()
Definition: mup_analog_sensor.h:94
AnalogSensor(String name, uint8_t analogPort, FilterMode filterMode=FilterMode::MEDIUM, String topicName="")
Definition: mup_analog_sensor.h:80
void begin(Scheduler *_pSched, uint32_t _pollRateMs=2000, double _linTransA=1.0, double _linTransB=0.0)
Definition: mup_analog_sensor.h:101