8#if defined(__ESP32__) || defined(__ESP__)
9#define G_INT_ATTR IRAM_ATTR
14#define USTD_MAX_BLP_PIRQS (10)
16volatile unsigned long blp_pirpcounter[USTD_MAX_BLP_PIRQS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
17volatile unsigned long blp_plastIrqTimer[USTD_MAX_BLP_PIRQS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
18volatile unsigned long blp_pbeginIrqTimer[USTD_MAX_BLP_PIRQS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
20void G_INT_ATTR ustd_blp_pirp_master(uint8_t irqno) {
21 unsigned long curr = micros();
22 if (blp_pbeginIrqTimer[irqno] == 0)
23 blp_pbeginIrqTimer[irqno] = curr;
25 ++blp_pirpcounter[irqno];
26 blp_plastIrqTimer[irqno] = curr;
29void G_INT_ATTR ustd_blp_pirp0() {
30 ustd_blp_pirp_master(0);
32void G_INT_ATTR ustd_blp_pirp1() {
33 ustd_blp_pirp_master(1);
35void G_INT_ATTR ustd_blp_pirp2() {
36 ustd_blp_pirp_master(2);
38void G_INT_ATTR ustd_blp_pirp3() {
39 ustd_blp_pirp_master(3);
41void G_INT_ATTR ustd_blp_pirp4() {
42 ustd_blp_pirp_master(4);
44void G_INT_ATTR ustd_blp_pirp5() {
45 ustd_blp_pirp_master(5);
47void G_INT_ATTR ustd_blp_pirp6() {
48 ustd_blp_pirp_master(6);
50void G_INT_ATTR ustd_blp_pirp7() {
51 ustd_blp_pirp_master(7);
53void G_INT_ATTR ustd_blp_pirp8() {
54 ustd_blp_pirp_master(8);
56void G_INT_ATTR ustd_blp_pirp9() {
57 ustd_blp_pirp_master(9);
60void (*ustd_blp_pirp_table[USTD_MAX_BLP_PIRQS])() = {ustd_blp_pirp0, ustd_blp_pirp1, ustd_blp_pirp2, ustd_blp_pirp3,
61 ustd_blp_pirp4, ustd_blp_pirp5, ustd_blp_pirp6, ustd_blp_pirp7,
62 ustd_blp_pirp8, ustd_blp_pirp9};
64unsigned long getBlpResetpIrqCount(uint8_t irqno) {
65 unsigned long count = (
unsigned long)-1;
67 if (irqno < USTD_MAX_BLP_PIRQS) {
68 count = blp_pirpcounter[irqno];
69 blp_pirpcounter[irqno] = 0;
75double getBlpResetpIrqFrequency(uint8_t irqno,
unsigned long minDtUs = 50) {
76 double frequency = 0.0;
78 if (irqno < USTD_MAX_BLP_PIRQS) {
79 unsigned long count = blp_pirpcounter[irqno];
80 unsigned long dt = timeDiff(blp_pbeginIrqTimer[irqno], blp_plastIrqTimer[irqno]);
82 frequency = (count * 500000.0) / dt;
85 blp_pbeginIrqTimer[irqno] = 0;
86 blp_pirpcounter[irqno] = 0;
87 blp_plastIrqTimer[irqno] = 0;
93bool changeBlpSELi(
bool bsel, uint8_t pin_sel, uint8_t irqno) {
94 digitalWrite(pin_sel, bsel);
95 getBlpResetpIrqFrequency(irqno);
123 String POWER_BL0937_VERSION =
"0.1.0";
128 bool irqsAttached =
false;
129 uint8_t pin_CF, pin_CF1, pin_SELi;
130 uint8_t irqno_CF, irqno_CF1, irqno_SELi;
131 int8_t interruptIndex_CF, interruptIndex_CF1;
133 ustd::sensorprocessor frequencyCF = ustd::sensorprocessor(8, 600, 0.1);
134 ustd::sensorprocessor frequencyCF1_I = ustd::sensorprocessor(8, 600, 0.01);
135 ustd::sensorprocessor frequencyCF1_V = ustd::sensorprocessor(8, 600, 0.1);
136 double CFfrequencyVal = 0.0;
137 double CF1_IfrequencyVal = 0.0;
138 double CF1_VfrequencyVal = 0.0;
140 double voltageRenormalisation = 6.221651690201113;
142 double currentRenormalisation =
144 double powerRenormalization = 0.575713594581519;
146 double userCalibrationPowerFactor = 1.0;
147 double userCalibrationVoltageFactor = 1.0;
148 double userCalibrationCurrentFactor = 1.0;
152 PowerBl0937(String name, uint8_t pin_CF, uint8_t pin_CF1, uint8_t pin_SELi,
153 int8_t interruptIndex_CF, uint8_t interruptIndex_CF1)
154 : name(name), pin_CF(pin_CF), pin_CF1(pin_CF1), pin_SELi(pin_SELi),
155 interruptIndex_CF(interruptIndex_CF), interruptIndex_CF1(interruptIndex_CF1) {
175 detachInterrupt(irqno_CF);
176 detachInterrupt(irqno_CF1);
180 bool begin(Scheduler *_pSched) {
183 pinMode(pin_CF, INPUT_PULLUP);
184 pinMode(pin_CF1, INPUT_PULLUP);
185 pinMode(pin_SELi, OUTPUT);
186 digitalWrite(pin_SELi, bSELi);
188 if (interruptIndex_CF >= 0 && interruptIndex_CF < USTD_MAX_BLP_PIRQS &&
189 interruptIndex_CF1 >= 0 && interruptIndex_CF1 < USTD_MAX_BLP_PIRQS &&
190 interruptIndex_CF != interruptIndex_CF1) {
192 irqno_CF = digitalPinToInterrupt(pin_CF);
193 irqno_CF1 = digitalPinToInterrupt(pin_CF1);
195 irqno_CF = digitalPinToInterrupt(pin_CF);
196 irqno_CF1 = digitalPinToInterrupt(pin_CF1);
198 attachInterrupt(irqno_CF, ustd_blp_pirp_table[interruptIndex_CF], CHANGE);
199 attachInterrupt(irqno_CF1, ustd_blp_pirp_table[interruptIndex_CF1], CHANGE);
205 auto ft = [=]() { this->loop(); };
206 tID = pSched->add(ft, name, 2000000);
208 auto fnall = [=](String topic, String msg, String originator) {
209 this->subsMsg(topic, msg, originator);
211 pSched->subscribe(tID, name +
"/power_bl0937/#", fnall);
215 void setUserCalibrationFactors(
double powerFactor = 1.0,
double voltageFactor = 1.0,
216 double currentFactor = 1.0) {
217 userCalibrationPowerFactor = powerFactor;
218 userCalibrationVoltageFactor = voltageFactor;
219 userCalibrationCurrentFactor = currentFactor;
221 frequencyCF1_V.reset();
222 frequencyCF1_I.reset();
227 sprintf(buf,
"%6.1f", CFfrequencyVal);
231 pSched->publish(name +
"/sensor/power", p1);
233 void publish_CF1_V() {
235 sprintf(buf,
"%5.1f", CF1_VfrequencyVal);
239 pSched->publish(name +
"/sensor/voltage", p1);
241 void publish_CF1_I() {
243 sprintf(buf,
"%5.2f", CF1_IfrequencyVal);
247 pSched->publish(name +
"/sensor/current", p1);
257 double watts = getBlpResetpIrqFrequency(interruptIndex_CF) / powerRenormalization *
258 userCalibrationPowerFactor;
259 if ((frequencyCF.lastVal == 0.0 && watts > 0.0) ||
260 (frequencyCF.lastVal > 0.0 && watts == 0.0))
262 if (watts >= 0.0 && watts < 3800) {
263 if (frequencyCF.filter(&watts)) {
264 CFfrequencyVal = watts;
268 double mfreq = getBlpResetpIrqFrequency(interruptIndex_CF1);
270 double volts = mfreq / voltageRenormalisation * userCalibrationVoltageFactor;
271 if (volts < 5.0 || (volts >= 100.0 && volts < 260)) {
272 if ((frequencyCF1_V.lastVal == 0.0 && volts > 0.0) ||
273 (frequencyCF1_V.lastVal > 0.0 && volts == 0.0))
274 frequencyCF1_V.reset();
275 if (frequencyCF1_V.filter(&volts)) {
276 CF1_VfrequencyVal = volts;
281 double currents = mfreq / currentRenormalisation * userCalibrationCurrentFactor;
282 if (currents >= 0.0 && currents < 16.0) {
283 if ((frequencyCF1_I.lastVal == 0.0 && currents > 0.0) ||
284 (frequencyCF1_I.lastVal > 0.0 && currents == 0.0))
285 frequencyCF1_I.reset();
286 if (frequencyCF1_I.filter(¤ts)) {
287 CF1_IfrequencyVal = currents;
292 bSELi = changeBlpSELi(!bSELi, pin_SELi, interruptIndex_CF1);
295 void subsMsg(String topic, String msg, String originator) {
296 if (topic == name +
"/sensor/state/get") {
298 }
else if (topic == name +
"/sensor/power/get") {
300 }
else if (topic == name +
"/sensor/voltage/get") {
302 }
else if (topic == name +
"/sensor/current/get") {
Power, Voltage and Current sensor BL0397.
Definition: mup_power_bl0397.h:121
PowerBl0937(String name, uint8_t pin_CF, uint8_t pin_CF1, uint8_t pin_SELi, int8_t interruptIndex_CF, uint8_t interruptIndex_CF1)
Definition: mup_power_bl0397.h:152