3-phase PV router
Loading...
Searching...
No Matches
processing.cpp
Go to the documentation of this file.
1
11
12#include <Arduino.h>
13
14#include "calibration.h"
15#include "dualtariff.h"
16#include "processing.h"
17#include "utils_pins.h"
18#include "shared_var.h"
19
20// Define operating limits for the LP filters which identify DC offset in the voltage
21// sample streams. By limiting the output range, these filters always should start up
22// correctly.
23constexpr int32_t l_DCoffset_V_min{ (512L - 100L) * 256L };
24constexpr int32_t l_DCoffset_V_max{ (512L + 100L) * 256L };
25constexpr int16_t i_DCoffset_I_nom{ 512L };
26
28
34constexpr float f_offsetOfEnergyThresholdsInAFmode{ 0.1F };
35
37
50
51constexpr float f_lowerThreshold_default{ initThreshold(true) };
52constexpr float f_upperThreshold_default{ initThreshold(false) };
53
54float f_energyInBucket_main{ 0.0F };
57
58// for improved control of multiple loads
59bool b_recentTransition{ false };
60uint8_t postTransitionCount{ 0 };
61constexpr uint8_t POST_TRANSITION_MAX_COUNT{ 3 };
62// constexpr uint8_t POST_TRANSITION_MAX_COUNT{50}; /**< for testing only */
64
65int32_t l_sumP[NO_OF_PHASES]{};
70
73
75
77
78// For an enhanced polarity detection mechanism, which includes a persistence check
82
85
86bool beyondStartUpPeriod{ false };
87
104template< size_t N >
105constexpr void initializeArray(int32_t (&array)[N], int32_t value)
106{
107 for (size_t i = 0; i < N; ++i)
108 {
109 array[i] = value;
110 }
111}
112
127constexpr uint16_t getOutputPins()
128{
129 uint16_t output_pins{ 0 };
130
131 for (const auto &loadPin : physicalLoadPin)
132 {
133 if (bit_read(output_pins, loadPin))
134 return 0;
135
136 bit_set(output_pins, loadPin);
137 }
138
139 if constexpr (WATCHDOG_PIN_PRESENT)
140 {
141 if (bit_read(output_pins, watchDogPin))
142 return 0;
143
144 bit_set(output_pins, watchDogPin);
145 }
146
147 if constexpr (RELAY_DIVERSION)
148 {
149 for (uint8_t idx = 0; idx < relays.get_size(); ++idx)
150 {
151 const auto relayPin = relays.get_relay(idx).get_pin();
152
153 if (bit_read(output_pins, relayPin))
154 return 0;
155
156 bit_set(output_pins, relayPin);
157 }
158 }
159
160 return output_pins;
161}
162
178constexpr uint16_t getInputPins()
179{
180 uint16_t input_pins{ 0 };
181
182 if constexpr (DUAL_TARIFF)
183 {
184 if (bit_read(input_pins, dualTariffPin))
185 return 0;
186
187 bit_set(input_pins, dualTariffPin);
188 }
189
190 if constexpr (DIVERSION_PIN_PRESENT)
191 {
192 if (bit_read(input_pins, diversionPin))
193 return 0;
194
195 bit_set(input_pins, diversionPin);
196 }
197
198 if constexpr (PRIORITY_ROTATION == RotationModes::PIN)
199 {
200 if (bit_read(input_pins, rotationPin))
201 return 0;
202
203 bit_set(input_pins, rotationPin);
204 }
205
206 if constexpr (OVERRIDE_PIN_PRESENT)
207 {
208 if (bit_read(input_pins, forcePin))
209 return 0;
210
211 bit_set(input_pins, forcePin);
212 }
213
214 return input_pins;
215}
216
231{
232 initializeArray(l_DCoffset_V, 512L * 256L); // nominal mid-point value of ADC @ x256 scale
233
234 setPinsAsOutput(getOutputPins()); // set the output pins as OUTPUT
235 setPinsAsInputPullup(getInputPins()); // set the input pins as INPUT_PULLUP
236
237 for (uint8_t i = 0; i < NO_OF_DUMPLOADS; ++i)
238 {
241 }
242
243 // First stop the ADC
244 bit_clear(ADCSRA, ADEN);
245
246 // Activate free-running mode
247 ADCSRB = 0x00;
248
249 // Set up the ADC to be free-running
250 bit_set(ADCSRA, ADPS0); // Set the ADC's clock to system clock / 128
251 bit_set(ADCSRA, ADPS1);
252 bit_set(ADCSRA, ADPS2);
253
254 bit_set(ADCSRA, ADATE); // set the Auto Trigger Enable bit in the ADCSRA register. Because
255 // bits ADTS0-2 have not been set (i.e. they are all zero), the
256 // ADC's trigger source is set to "free running mode".
257
258 bit_set(ADCSRA, ADIE); // set the ADC interrupt enable bit. When this bit is written
259 // to one and the I-bit in SREG is set, the
260 // ADC Conversion Complete Interrupt is activated.
261
262 bit_set(ADCSRA, ADEN); // Enable the ADC
263
264 bit_set(ADCSRA, ADSC); // start ADC manually first time
265
266 sei(); // Enable Global Interrupts
267}
268
284{
285 uint16_t pinsON{ 0 };
286 uint16_t pinsOFF{ 0 };
287
288 uint8_t i{ NO_OF_DUMPLOADS };
289
290 do
291 {
292 --i;
293 // update the local load's state.
295 {
296 // setPinOFF(physicalLoadPin[i]);
297 pinsOFF |= bit(physicalLoadPin[i]);
298 }
299 else
300 {
301 ++countLoadON[i];
302 // setPinON(physicalLoadPin[i]);
303 pinsON |= bit(physicalLoadPin[i]);
304 }
305 } while (i);
306
307 setPinsOFF(pinsOFF);
308 setPinsON(pinsON);
309}
310
336{
337 if constexpr (PRIORITY_ROTATION != RotationModes::OFF)
338 {
340 {
341 uint8_t i{ NO_OF_DUMPLOADS - 1 };
342 const auto temp{ loadPrioritiesAndState[i] };
343 do
344 {
346 --i;
347 } while (i);
348 loadPrioritiesAndState[0] = temp;
349
351 }
352
353 if constexpr (!DUAL_TARIFF)
354 {
355 if (0x00 == (loadPrioritiesAndState[0] & loadStateOnBit))
356 {
357 Shared::EDD_isIdle = true;
358 }
359 else
360 {
361 Shared::EDD_isIdle = false;
363 }
364 }
365 }
366
367 const bool bDiversionEnabled{ Shared::b_diversionEnabled };
368 uint8_t idx{ NO_OF_DUMPLOADS };
369 do
370 {
371 --idx;
372 const auto iLoad{ loadPrioritiesAndState[idx] & loadStateMask };
374 } while (idx);
375}
376
394void processPolarity(const uint8_t phase, const int16_t rawSample)
395{
396 // remove DC offset from each raw voltage sample by subtracting the accurate value
397 // as determined by its associated LP filter.
398 l_sampleVminusDC[phase] = (static_cast< int32_t >(rawSample) << 8) - l_DCoffset_V[phase];
400}
401
419void processCurrentRawSample(const uint8_t phase, const int16_t rawSample)
420{
421 // extra items for an LPF to improve the processing of data samples from CT1
422 static int32_t lpf_long[NO_OF_PHASES]{}; // new LPF, for offsetting the behaviour of CTx as a HPF
423
424 // remove most of the DC offset from the current sample (the precise value does not matter)
425 int32_t sampleIminusDC = (static_cast< int32_t >(rawSample - i_DCoffset_I_nom)) << 8;
426
427 // extra filtering to offset the HPF effect of CTx
428 const int32_t last_lpf_long{ lpf_long[phase] };
429 lpf_long[phase] += alpha * (sampleIminusDC - last_lpf_long);
430 sampleIminusDC += (lpf_gain * lpf_long[phase]);
431
432 // calculate the "real power" in this sample pair and add to the accumulated sum
433 const int32_t filtV_div4 = l_sampleVminusDC[phase] >> 2; // reduce to 16-bits (now x64, or 2^6)
434 const int32_t filtI_div4 = sampleIminusDC >> 2; // reduce to 16-bits (now x64, or 2^6)
435 int32_t instP = filtV_div4 * filtI_div4; // 32-bits (now x4096, or 2^12)
436 instP >>= 12; // scaling is now x1, as for Mk2 (V_ADC x I_ADC)
437
438 l_sumP[phase] += instP; // cumulative power, scaling as for Mk2 (V_ADC x I_ADC)
439 l_sumP_atSupplyPoint[phase] += instP; // cumulative power, scaling as for Mk2 (V_ADC x I_ADC)
440}
441
458void confirmPolarity(const uint8_t phase)
459{
460 static uint8_t count[NO_OF_PHASES]{};
461
463 {
464 count[phase] = 0;
465 return;
466 }
467
468 if (++count[phase] > PERSISTENCE_FOR_POLARITY_CHANGE)
469 {
470 count[phase] = 0;
472 }
473}
474
492void processVoltage(const uint8_t phase)
493{
494 // for the Vrms calculation (for datalogging only)
495 const int32_t filtV_div4{ l_sampleVminusDC[phase] >> 2 }; // reduce to 16-bits (now x64, or 2^6)
496 int32_t inst_Vsquared{ filtV_div4 * filtV_div4 }; // 32-bits (now x4096, or 2^12)
497
498 if constexpr (DATALOG_PERIOD_IN_SECONDS > 10)
499 {
500 inst_Vsquared >>= 16; // scaling is now x1/16 (V_ADC x I_ADC)
501 }
502 else
503 {
504 inst_Vsquared >>= 12; // scaling is now x1 (V_ADC x I_ADC)
505 }
506
507 l_sum_Vsquared[phase] += inst_Vsquared; // cumulative V^2 (V_ADC x I_ADC)
508 //
509 // store items for use during next loop
510 l_cumVdeltasThisCycle[phase] += l_sampleVminusDC[phase]; // for use with LP filter
511 polarityConfirmedOfLastSampleV[phase] = polarityConfirmed[phase]; // for identification of half cycle boundaries
512 ++n_samplesDuringThisMainsCycle[phase]; // for real power calculations
513}
514
531void processStartUp(const uint8_t phase)
532{
533 // wait until the DC-blocking filters have had time to settle
534 if (millis() <= (initialDelay + startUpPeriod))
535 {
536 return; // still settling, do nothing
537 }
538
539 // the DC-blocking filters have had time to settle
540 beyondStartUpPeriod = true;
541 l_sumP[phase] = 0;
542 l_sumP_atSupplyPoint[phase] = 0;
545
547 // can't say "Go!" here 'cos we're in an ISR!
548}
549
564{
565 bool bOK_toAddLoad{ true };
566 const auto tempLoad{ nextLogicalLoadToBeAdded() };
567
568 if (tempLoad == NO_OF_DUMPLOADS)
569 {
570 return;
571 }
572
573 // a load which is now OFF has been identified for potentially being switched ON
575 {
576 // During the post-transition period, any increase in the energy level is noted.
578
579 // the energy thresholds must remain within range
581 {
583 }
584
585 // Only the active load may be switched during this period. All other loads must
586 // wait until the recent transition has had sufficient opportunity to take effect.
587 bOK_toAddLoad = (tempLoad == activeLoad);
588 }
589
590 if (bOK_toAddLoad)
591 {
593 activeLoad = tempLoad;
595 b_recentTransition = true;
596 }
597}
598
613{
614 bool bOK_toRemoveLoad{ true };
615 const auto tempLoad{ nextLogicalLoadToBeRemoved() };
616
617 if (tempLoad == NO_OF_DUMPLOADS)
618 {
619 return;
620 }
621
622 // a load which is now ON has been identified for potentially being switched OFF
624 {
625 // During the post-transition period, any decrease in the energy level is noted.
627
628 // the energy thresholds must remain within range
630 {
632 }
633
634 // Only the active load may be switched during this period. All other loads must
635 // wait until the recent transition has had sufficient opportunity to take effect.
636 bOK_toRemoveLoad = (tempLoad == activeLoad);
637 }
638
639 if (bOK_toRemoveLoad)
640 {
642 activeLoad = tempLoad;
644 b_recentTransition = true;
645 }
646}
647
664{
665 // Restrictions apply for the period immediately after a load has been switched.
666 // Here the b_recentTransition flag is checked and updated as necessary.
667 // if (b_recentTransition)
668 // b_recentTransition = (++postTransitionCount < POST_TRANSITION_MAX_COUNT);
669 // for optimization, the next line is equivalent to the two lines above
671
673 {
674 // the energy state is in the upper half of the working range
675 f_lowerEnergyThreshold = f_lowerThreshold_default; // reset the "opposite" threshold
677 {
678 // Because the energy level is high, some action may be required
680 }
681 }
682 else
683 {
684 // the energy state is in the lower half of the working range
685 f_upperEnergyThreshold = f_upperThreshold_default; // reset the "opposite" threshold
687 {
688 // Because the energy level is low, some action may be required
690 }
691 }
692
693 updatePhysicalLoadStates(); // allows the logical-to-physical mapping to be changed
694
695 updatePortsStates(); // update the control ports for each of the physical loads
696
697 // Now that the energy-related decisions have been taken, min and max limits can now
698 // be applied to the level of the energy bucket. This is to ensure correct operation
699 // when conditions change, i.e. when import changes to export, and vice versa.
700 //
702 {
704 }
705 else if (f_energyInBucket_main < 0)
706 {
708 }
709}
710
726void processMinusHalfCycle(const uint8_t phase)
727{
728 // This is a convenient point to update the Low Pass Filter for removing the DC
729 // component from the phase that is being processed.
730 // The portion which is fed back into the integrator is approximately one percent
731 // of the average offset of all the SampleVs in the previous mains cycle.
732 //
733 l_DCoffset_V[phase] += (l_cumVdeltasThisCycle[phase] >> 12);
734 l_cumVdeltasThisCycle[phase] = 0;
735
736 // To ensure that this LP filter will always start up correctly when 240V AC is
737 // available, its output value needs to be prevented from drifting beyond the likely range
738 // of the voltage signal.
739 //
740 if (l_DCoffset_V[phase] < l_DCoffset_V_min)
741 {
743 }
744 else if (l_DCoffset_V[phase] > l_DCoffset_V_max)
745 {
747 }
748}
749
763{
764 for (uint8_t index = 0; index < NO_OF_DUMPLOADS; ++index)
765 {
766 if (0x00 == (loadPrioritiesAndState[index] & loadStateOnBit))
767 {
768 return (index);
769 }
770 }
771
772 return (NO_OF_DUMPLOADS);
773}
774
788{
789 uint8_t index{ NO_OF_DUMPLOADS };
790 do
791 {
793 {
794 return (index);
795 }
796 } while (index);
797
798 return (NO_OF_DUMPLOADS);
799}
800
817void processLatestContribution(const uint8_t phase)
818{
819 // for efficiency, the energy scale is Joules * SUPPLY_FREQUENCY
820 // add the latest energy contribution to the main energy accumulator
822
823 // apply any adjustment that is required.
824 if (0 == phase)
825 {
826 f_energyInBucket_main -= REQUIRED_EXPORT_IN_WATTS; // energy scale is Joules x 50
827 Shared::b_newMainsCycle = true; // a 50 Hz 'tick' for use by the main code
828 }
829 // Applying max and min limits to the main accumulator's level
830 // is deferred until after the energy related decisions have been taken
831 //
832}
833
849{
851 {
852 return; // data logging period not yet reached
853 }
854
856
857 uint8_t phase{ NO_OF_PHASES };
858 do
859 {
860 --phase;
862 l_sumP_atSupplyPoint[phase] = 0;
863
865 l_sum_Vsquared[phase] = 0;
866 } while (phase);
867
868 uint8_t i{ NO_OF_DUMPLOADS };
869 do
870 {
871 --i;
873 countLoadON[i] = 0;
874 } while (i);
875
879
882
883 // signal the main processor that logging data are available
884 // we skip the period from start to running stable
886}
887
905void processPlusHalfCycle(const uint8_t phase)
906{
907 processLatestContribution(phase); // runs at 6.6 ms intervals
908
909 // A performance check to monitor and display the minimum number of sets of
910 // ADC samples per mains cycle, the expected number being 20ms / (104us * 6) = 32.05
911 //
912 if (0 == phase)
913 {
915 {
917 }
918
920 }
921
922 l_sumP[phase] = 0;
924}
925
943void processRawSamples(const uint8_t phase)
944{
945 // The raw V and I samples are processed in "phase pairs"
946 const auto &lastPolarity{ polarityConfirmedOfLastSampleV[phase] };
947
949 {
950 // the polarity of this sample is positive
951 if (Polarities::POSITIVE != lastPolarity)
952 {
953 // This is the start of a new +ve half cycle, for this phase, just after the zero-crossing point.
955 {
957 }
958 else
959 {
960 processStartUp(phase);
961 }
962 }
963
964 // still processing samples where the voltage is POSITIVE ...
965 // check to see whether the trigger device can now be reliably armed
966 if ((0 == phase) && beyondStartUpPeriod && (2 == n_samplesDuringThisMainsCycle[0])) // lower value for larger sample set
967 {
968 // This code is executed once per 20mS, shortly after the start of each new mains cycle on phase 0.
970 }
971 }
972 else
973 {
974 // the polarity of this sample is negative
975 if (Polarities::NEGATIVE != lastPolarity)
976 {
977 // This is the start of a new -ve half cycle (just after the zero-crossing point)
979 }
980 }
981}
982
1000void processVoltageRawSample(const uint8_t phase, const int16_t rawSample)
1001{
1002 processPolarity(phase, rawSample);
1003 confirmPolarity(phase);
1004
1005 processRawSamples(phase); // deals with aspects that only occur at particular stages of each mains cycle
1006
1007 processVoltage(phase);
1008
1009 if (phase == 0)
1010 {
1012 }
1013}
1014
1029{
1030 // display relevant settings for selected output mode
1031 DBUG(F("Output mode: "));
1033 {
1034 DBUGLN(F("normal"));
1035 }
1036 else
1037 {
1038 DBUGLN(F("anti-flicker"));
1039 DBUG(F("\toffsetOfEnergyThresholds = "));
1041 }
1042 DBUG(F("\tf_capacityOfEnergyBucket_main = "));
1044 DBUG(F("\tf_lowerEnergyThreshold = "));
1046 DBUG(F("\tf_upperEnergyThreshold = "));
1048}
1049
1080ISR(ADC_vect)
1081{
1082 static uint8_t sample_index{ 0 };
1083 int16_t rawSample;
1084
1085 switch (sample_index)
1086 {
1087 case 0:
1088 rawSample = ADC; // store the ADC value (this one is for Voltage L1)
1089 ADMUX = bit(REFS0) + sensorV[1]; // the conversion for I1 is already under way
1090 ++sample_index; // increment the control flag
1091 //
1092 processVoltageRawSample(0, rawSample);
1093 break;
1094 case 1:
1095 rawSample = ADC; // store the ADC value (this one is for Current L1)
1096 ADMUX = bit(REFS0) + sensorI[1]; // the conversion for V2 is already under way
1097 ++sample_index; // increment the control flag
1098 //
1099 processCurrentRawSample(0, rawSample);
1100 break;
1101 case 2:
1102 rawSample = ADC; // store the ADC value (this one is for Voltage L2)
1103 ADMUX = bit(REFS0) + sensorV[2]; // the conversion for I2 is already under way
1104 ++sample_index; // increment the control flag
1105 //
1106 processVoltageRawSample(1, rawSample);
1107 break;
1108 case 3:
1109 rawSample = ADC; // store the ADC value (this one is for Current L2)
1110 ADMUX = bit(REFS0) + sensorI[2]; // the conversion for V3 is already under way
1111 ++sample_index; // increment the control flag
1112 //
1113 processCurrentRawSample(1, rawSample);
1114 break;
1115 case 4:
1116 rawSample = ADC; // store the ADC value (this one is for Voltage L3)
1117 ADMUX = bit(REFS0) + sensorV[0]; // the conversion for I3 is already under way
1118 ++sample_index; // increment the control flag
1119 //
1120 processVoltageRawSample(2, rawSample);
1121 break;
1122 case 5:
1123 rawSample = ADC; // store the ADC value (this one is for Current L3)
1124 ADMUX = bit(REFS0) + sensorI[0]; // the conversion for V1 is already under way
1125 sample_index = 0; // reset the control flag
1126 //
1127 processCurrentRawSample(2, rawSample);
1128 break;
1129 default:
1130 sample_index = 0; // to prevent lockup (should never get here)
1131 }
1132} // end of ISR
Calibration values definition.
constexpr float alpha
Definition calibration.h:54
constexpr float lpf_gain
Definition calibration.h:53
constexpr float f_powerCal[NO_OF_PHASES]
Definition calibration.h:34
constexpr uint8_t loadPrioritiesAtStartup[NO_OF_DUMPLOADS]
Definition config.h:82
constexpr bool RELAY_DIVERSION
Definition config.h:40
constexpr bool OVERRIDE_PIN_PRESENT
Definition config.h:37
constexpr uint8_t dualTariffPin
Definition config.h:85
constexpr uint8_t forcePin
Definition config.h:88
constexpr RelayEngine relays
Definition config.h:91
constexpr uint8_t physicalLoadPin[NO_OF_DUMPLOADS]
Definition config.h:81
constexpr bool DUAL_TARIFF
Definition config.h:41
constexpr uint8_t diversionPin
Definition config.h:86
constexpr uint8_t NO_OF_DUMPLOADS
Definition config.h:32
constexpr bool WATCHDOG_PIN_PRESENT
Definition config.h:39
constexpr bool DIVERSION_PIN_PRESENT
Definition config.h:35
constexpr uint8_t rotationPin
Definition config.h:87
constexpr uint8_t watchDogPin
Definition config.h:89
constexpr int16_t REQUIRED_EXPORT_IN_WATTS
constexpr uint32_t WORKING_ZONE_IN_JOULES
constexpr conditional< DATALOG_PERIOD_IN_SECONDS *SUPPLY_FREQUENCY >=UINT8_MAX, uint16_t, uint8_t >::type DATALOG_PERIOD_IN_MAINS_CYCLES
constexpr uint8_t DATALOG_PERIOD_IN_SECONDS
constexpr uint8_t NO_OF_PHASES
constexpr uint8_t SUPPLY_FREQUENCY
#define DBUGLN(...)
Definition debug.h:97
#define DBUG(...)
Definition debug.h:96
Classes/types needed for dual-tariff support.
uint8_t i
constexpr uint16_t getInputPins()
Retrieves the input pins configuration.
constexpr void initializeArray(int32_t(&array)[N], int32_t value)
Initializes all elements of a given array to a specified value.
constexpr uint16_t getOutputPins()
Retrieves the output pins configuration.
void initializeProcessing()
Initializes the processing engine, including ports, load states, and ADC setup.
ISR(ADC_vect)
Interrupt Service Routine - Interrupt-Driven Analog Conversion.
void updatePhysicalLoadStates()
Updates the physical load states based on logical load priorities and states.
void processLatestContribution(const uint8_t phase)
Process the latest contribution after each phase-specific new cycle.
void updatePortsStates()
Updates the control ports for each of the physical loads.
void processStartUp(const uint8_t phase)
Processes the startup period for the router.
void processStartNewCycle()
Processes the start of a new mains cycle on phase 0.
void processMinusHalfCycle(const uint8_t phase)
Processes the start of a new negative half cycle for the specified phase.
void processVoltageRawSample(const uint8_t phase, const int16_t rawSample)
Processes the current voltage raw sample for the specified phase.
void proceedLowEnergyLevel()
Handles the case when the energy level is low, potentially removing a load.
void processPolarity(const uint8_t phase, const int16_t rawSample)
Processes the polarity of the current voltage sample for a specific phase.
void processRawSamples(const uint8_t phase)
Processes raw voltage and current samples for the specified phase.
uint8_t nextLogicalLoadToBeAdded()
Retrieve the next logical load that could be added.
void processPlusHalfCycle(const uint8_t phase)
Process the start of a new positive half cycle for the specified phase.
void processDataLogging()
Process data logging at the end of each logging period.
uint8_t nextLogicalLoadToBeRemoved()
Retrieve the next logical load that could be removed (in reverse order).
void confirmPolarity(const uint8_t phase)
Confirms the polarity of the current voltage sample for a specific phase.
void processVoltage(const uint8_t phase)
Processes the current voltage sample for the specified phase.
void proceedHighEnergyLevel()
Handles the case when the energy level is high, potentially adding a load.
void processCurrentRawSample(const uint8_t phase, const int16_t rawSample)
Processes the current raw sample for the specified phase.
volatile bool EDD_isIdle
Definition shared_var.h:16
volatile int32_t copyOf_sum_Vsquared[NO_OF_PHASES]
Definition shared_var.h:23
volatile float copyOf_energyInBucket_main
Definition shared_var.h:24
volatile bool b_datalogEventPending
Definition shared_var.h:10
volatile bool b_overrideLoadOn[NO_OF_DUMPLOADS]
Definition shared_var.h:12
volatile bool b_reOrderLoads
Definition shared_var.h:13
volatile uint16_t copyOf_sampleSetsDuringThisDatalogPeriod
Definition shared_var.h:26
volatile int32_t copyOf_sumP_atSupplyPoint[NO_OF_PHASES]
Definition shared_var.h:22
volatile uint8_t copyOf_lowestNoOfSampleSetsPerMainsCycle
Definition shared_var.h:25
volatile uint16_t copyOf_countLoadON[NO_OF_DUMPLOADS]
Definition shared_var.h:27
volatile uint16_t absenceOfDivertedEnergyCountInSeconds
Definition shared_var.h:17
volatile bool b_newMainsCycle
Definition shared_var.h:11
volatile bool b_diversionEnabled
Definition shared_var.h:14
Polarities polarityConfirmedOfLastSampleV[NO_OF_PHASES]
uint8_t n_lowestNoOfSampleSetsPerMainsCycle
float f_energyInBucket_main
constexpr OutputModes outputMode
constexpr int16_t i_DCoffset_I_nom
constexpr int32_t l_DCoffset_V_min
constexpr int32_t l_DCoffset_V_max
float f_upperEnergyThreshold
uint16_t countLoadON[NO_OF_DUMPLOADS]
constexpr float f_offsetOfEnergyThresholdsInAFmode
remove_cv< remove_reference< decltype(DATALOG_PERIOD_IN_MAINS_CYCLES)>::type >::type n_cycleCountForDatalogging
constexpr uint8_t POST_TRANSITION_MAX_COUNT
constexpr auto initThreshold(const bool lower)
set default threshold at compile time so the variable can be read-only
constexpr float f_capacityOfEnergyBucket_main
LoadStates physicalLoadState[NO_OF_DUMPLOADS]
int32_t l_sum_Vsquared[NO_OF_PHASES]
int32_t l_sumP[NO_OF_PHASES]
Polarities polarityConfirmed[NO_OF_PHASES]
bool b_recentTransition
uint8_t n_samplesDuringThisMainsCycle[NO_OF_PHASES]
constexpr float f_lowerThreshold_default
void printParamsForSelectedOutputMode()
Print the settings used for the selected output mode.
constexpr float f_midPointOfEnergyBucket_main
bool beyondStartUpPeriod
int32_t l_cumVdeltasThisCycle[NO_OF_PHASES]
int32_t l_sampleVminusDC[NO_OF_PHASES]
Polarities polarityOfMostRecentSampleV[NO_OF_PHASES]
uint16_t i_sampleSetsDuringThisDatalogPeriod
constexpr float f_upperThreshold_default
float f_lowerEnergyThreshold
int32_t l_DCoffset_V[NO_OF_PHASES]
int32_t l_sumP_atSupplyPoint[NO_OF_PHASES]
uint8_t activeLoad
uint8_t postTransitionCount
Public functions/variables of processing engine.
constexpr uint16_t startUpPeriod
Definition processing.h:27
constexpr uint8_t PERSISTENCE_FOR_POLARITY_CHANGE
Definition processing.h:24
uint8_t loadPrioritiesAndState[NO_OF_DUMPLOADS]
Definition processing.h:22
constexpr uint8_t sensorV[NO_OF_PHASES]
Definition processing.h:18
constexpr uint8_t sensorI[NO_OF_PHASES]
Definition processing.h:19
constexpr uint16_t initialDelay
Definition processing.h:26
Polarities
Definition types.h:35
@ NEGATIVE
Definition types.h:36
@ POSITIVE
Definition types.h:37
constexpr uint8_t loadStateMask
Definition types.h:55
constexpr uint8_t loadStateOnBit
Definition types.h:56
LoadStates
Definition types.h:49
@ LOAD_OFF
Definition types.h:50
@ LOAD_ON
Definition types.h:51
OutputModes
Definition types.h:42
@ ANTI_FLICKER
Definition types.h:43
Some utility functions for pins manipulation.
constexpr void bit_set(T &_dest, const uint8_t bit)
Set the specified bit to 1.
Definition utils_pins.h:54
void setPinsOFF(uint16_t pins)
Set the Pins state to OFF.
Definition utils_pins.h:181
constexpr uint8_t bit_read(const T &_src, const uint8_t bit)
Read the specified bit.
Definition utils_pins.h:67
void setPinsAsInputPullup(uint16_t pins)
Set the pins as INPUT_PULLUP.
Definition utils_pins.h:226
void setPinsAsOutput(uint16_t pins)
Set the pins as OUTPUT.
Definition utils_pins.h:215
void setPinsON(uint16_t pins)
Set the Pins state to ON.
Definition utils_pins.h:149
constexpr uint8_t bit_clear(T &_dest, const uint8_t bit)
Clear the specified bit.
Definition utils_pins.h:80