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
19// Define operating limits for the LP filters which identify DC offset in the voltage
20// sample streams. By limiting the output range, these filters always should start up
21// correctly.
22constexpr int32_t l_DCoffset_V_min{ (512L - 100L) * 256L };
23constexpr int32_t l_DCoffset_V_max{ (512L + 100L) * 256L };
24constexpr int16_t i_DCoffset_I_nom{ 512L };
25
27
33constexpr float f_offsetOfEnergyThresholdsInAFmode{ 0.1F };
34
36
49
50constexpr float f_lowerThreshold_default{ initThreshold(true) };
51constexpr float f_upperThreshold_default{ initThreshold(false) };
52
53float f_energyInBucket_main{ 0.0F };
56
57// for improved control of multiple loads
58bool b_recentTransition{ false };
59uint8_t postTransitionCount{ 0 };
60constexpr uint8_t POST_TRANSITION_MAX_COUNT{ 3 };
61// constexpr uint8_t POST_TRANSITION_MAX_COUNT{50}; /**< for testing only */
63
64int32_t l_sumP[NO_OF_PHASES]{};
69
72
74
76
77// For an enhanced polarity detection mechanism, which includes a persistence check
81
84
85bool beyondStartUpPeriod{ false };
86
103template< size_t N >
104constexpr void initializeArray(int32_t (&array)[N], int32_t value)
105{
106 for (size_t i = 0; i < N; ++i)
107 {
108 array[i] = value;
109 }
110}
111
126constexpr uint16_t getOutputPins()
127{
128 uint16_t output_pins{ 0 };
129
130 for (const auto &loadPin : physicalLoadPin)
131 {
132 if (bit_read(output_pins, loadPin))
133 return 0;
134
135 bit_set(output_pins, loadPin);
136 }
137
138 if constexpr (WATCHDOG_PIN_PRESENT)
139 {
140 if (bit_read(output_pins, watchDogPin))
141 return 0;
142
143 bit_set(output_pins, watchDogPin);
144 }
145
146 if constexpr (RELAY_DIVERSION)
147 {
148 for (uint8_t idx = 0; idx < relays.get_size(); ++idx)
149 {
150 const auto relayPin = relays.get_relay(idx).get_pin();
151
152 if (bit_read(output_pins, relayPin))
153 return 0;
154
155 bit_set(output_pins, relayPin);
156 }
157 }
158
159 return output_pins;
160}
161
177constexpr uint16_t getInputPins()
178{
179 uint16_t input_pins{ 0 };
180
181 if constexpr (DUAL_TARIFF)
182 {
183 if (bit_read(input_pins, dualTariffPin))
184 return 0;
185
186 bit_set(input_pins, dualTariffPin);
187 }
188
189 if constexpr (DIVERSION_PIN_PRESENT)
190 {
191 if (bit_read(input_pins, diversionPin))
192 return 0;
193
194 bit_set(input_pins, diversionPin);
195 }
196
197 if constexpr (PRIORITY_ROTATION == RotationModes::PIN)
198 {
199 if (bit_read(input_pins, rotationPin))
200 return 0;
201
202 bit_set(input_pins, rotationPin);
203 }
204
205 if constexpr (OVERRIDE_PIN_PRESENT)
206 {
207 if (bit_read(input_pins, forcePin))
208 return 0;
209
210 bit_set(input_pins, forcePin);
211 }
212
213 return input_pins;
214}
215
230{
231 initializeArray(l_DCoffset_V, 512L * 256L); // nominal mid-point value of ADC @ x256 scale
232
233 setPinsAsOutput(getOutputPins()); // set the output pins as OUTPUT
234 setPinsAsInputPullup(getInputPins()); // set the input pins as INPUT_PULLUP
235
236 for (uint8_t i = 0; i < NO_OF_DUMPLOADS; ++i)
237 {
240 }
241
242 // First stop the ADC
243 bit_clear(ADCSRA, ADEN);
244
245 // Activate free-running mode
246 ADCSRB = 0x00;
247
248 // Set up the ADC to be free-running
249 bit_set(ADCSRA, ADPS0); // Set the ADC's clock to system clock / 128
250 bit_set(ADCSRA, ADPS1);
251 bit_set(ADCSRA, ADPS2);
252
253 bit_set(ADCSRA, ADATE); // set the Auto Trigger Enable bit in the ADCSRA register. Because
254 // bits ADTS0-2 have not been set (i.e. they are all zero), the
255 // ADC's trigger source is set to "free running mode".
256
257 bit_set(ADCSRA, ADIE); // set the ADC interrupt enable bit. When this bit is written
258 // to one and the I-bit in SREG is set, the
259 // ADC Conversion Complete Interrupt is activated.
260
261 bit_set(ADCSRA, ADEN); // Enable the ADC
262
263 bit_set(ADCSRA, ADSC); // start ADC manually first time
264
265 sei(); // Enable Global Interrupts
266}
267
283{
284 uint16_t pinsON{ 0 };
285 uint16_t pinsOFF{ 0 };
286
287 uint8_t i{ NO_OF_DUMPLOADS };
288
289 do
290 {
291 --i;
292 // update the local load's state.
294 {
295 // setPinOFF(physicalLoadPin[i]);
296 pinsOFF |= bit(physicalLoadPin[i]);
297 }
298 else
299 {
300 ++countLoadON[i];
301 // setPinON(physicalLoadPin[i]);
302 pinsON |= bit(physicalLoadPin[i]);
303 }
304 } while (i);
305
306 setPinsOFF(pinsOFF);
307 setPinsON(pinsON);
308}
309
335{
336 if constexpr (PRIORITY_ROTATION != RotationModes::OFF)
337 {
338 if (b_reOrderLoads)
339 {
340 uint8_t i{ NO_OF_DUMPLOADS - 1 };
341 const auto temp{ loadPrioritiesAndState[i] };
342 do
343 {
345 --i;
346 } while (i);
347 loadPrioritiesAndState[0] = temp;
348
349 b_reOrderLoads = false;
350 }
351
352 if constexpr (!DUAL_TARIFF)
353 {
354 if (0x00 == (loadPrioritiesAndState[0] & loadStateOnBit))
355 {
356 EDD_isIdle = true;
357 }
358 else
359 {
360 EDD_isIdle = false;
362 }
363 }
364 }
365
366 const bool bDiversionOff{ b_diversionOff };
367 uint8_t idx{ NO_OF_DUMPLOADS };
368 do
369 {
370 --idx;
371 const auto iLoad{ loadPrioritiesAndState[idx] & loadStateMask };
373 } while (idx);
374}
375
393void processPolarity(const uint8_t phase, const int16_t rawSample)
394{
395 // remove DC offset from each raw voltage sample by subtracting the accurate value
396 // as determined by its associated LP filter.
397 l_sampleVminusDC[phase] = (static_cast< int32_t >(rawSample) << 8) - l_DCoffset_V[phase];
399}
400
418void processCurrentRawSample(const uint8_t phase, const int16_t rawSample)
419{
420 // extra items for an LPF to improve the processing of data samples from CT1
421 static int32_t lpf_long[NO_OF_PHASES]{}; // new LPF, for offsetting the behaviour of CTx as a HPF
422
423 // remove most of the DC offset from the current sample (the precise value does not matter)
424 int32_t sampleIminusDC = (static_cast< int32_t >(rawSample - i_DCoffset_I_nom)) << 8;
425
426 // extra filtering to offset the HPF effect of CTx
427 const int32_t last_lpf_long{ lpf_long[phase] };
428 lpf_long[phase] += alpha * (sampleIminusDC - last_lpf_long);
429 sampleIminusDC += (lpf_gain * lpf_long[phase]);
430
431 // calculate the "real power" in this sample pair and add to the accumulated sum
432 const int32_t filtV_div4 = l_sampleVminusDC[phase] >> 2; // reduce to 16-bits (now x64, or 2^6)
433 const int32_t filtI_div4 = sampleIminusDC >> 2; // reduce to 16-bits (now x64, or 2^6)
434 int32_t instP = filtV_div4 * filtI_div4; // 32-bits (now x4096, or 2^12)
435 instP >>= 12; // scaling is now x1, as for Mk2 (V_ADC x I_ADC)
436
437 l_sumP[phase] += instP; // cumulative power, scaling as for Mk2 (V_ADC x I_ADC)
438 l_sumP_atSupplyPoint[phase] += instP; // cumulative power, scaling as for Mk2 (V_ADC x I_ADC)
439}
440
457void confirmPolarity(const uint8_t phase)
458{
459 static uint8_t count[NO_OF_PHASES]{};
460
462 {
463 count[phase] = 0;
464 return;
465 }
466
467 if (++count[phase] > PERSISTENCE_FOR_POLARITY_CHANGE)
468 {
469 count[phase] = 0;
471 }
472}
473
491void processVoltage(const uint8_t phase)
492{
493 // for the Vrms calculation (for datalogging only)
494 const int32_t filtV_div4{ l_sampleVminusDC[phase] >> 2 }; // reduce to 16-bits (now x64, or 2^6)
495 int32_t inst_Vsquared{ filtV_div4 * filtV_div4 }; // 32-bits (now x4096, or 2^12)
496
497 if constexpr (DATALOG_PERIOD_IN_SECONDS > 10)
498 {
499 inst_Vsquared >>= 16; // scaling is now x1/16 (V_ADC x I_ADC)
500 }
501 else
502 {
503 inst_Vsquared >>= 12; // scaling is now x1 (V_ADC x I_ADC)
504 }
505
506 l_sum_Vsquared[phase] += inst_Vsquared; // cumulative V^2 (V_ADC x I_ADC)
507 //
508 // store items for use during next loop
509 l_cumVdeltasThisCycle[phase] += l_sampleVminusDC[phase]; // for use with LP filter
510 polarityConfirmedOfLastSampleV[phase] = polarityConfirmed[phase]; // for identification of half cycle boundaries
511 ++n_samplesDuringThisMainsCycle[phase]; // for real power calculations
512}
513
530void processStartUp(const uint8_t phase)
531{
532 // wait until the DC-blocking filters have had time to settle
533 if (millis() <= (initialDelay + startUpPeriod))
534 {
535 return; // still settling, do nothing
536 }
537
538 // the DC-blocking filters have had time to settle
539 beyondStartUpPeriod = true;
540 l_sumP[phase] = 0;
541 l_sumP_atSupplyPoint[phase] = 0;
544
546 // can't say "Go!" here 'cos we're in an ISR!
547}
548
563{
564 bool bOK_toAddLoad{ true };
565 const auto tempLoad{ nextLogicalLoadToBeAdded() };
566
567 if (tempLoad == NO_OF_DUMPLOADS)
568 {
569 return;
570 }
571
572 // a load which is now OFF has been identified for potentially being switched ON
574 {
575 // During the post-transition period, any increase in the energy level is noted.
577
578 // the energy thresholds must remain within range
580 {
582 }
583
584 // Only the active load may be switched during this period. All other loads must
585 // wait until the recent transition has had sufficient opportunity to take effect.
586 bOK_toAddLoad = (tempLoad == activeLoad);
587 }
588
589 if (bOK_toAddLoad)
590 {
592 activeLoad = tempLoad;
594 b_recentTransition = true;
595 }
596}
597
612{
613 bool bOK_toRemoveLoad{ true };
614 const auto tempLoad{ nextLogicalLoadToBeRemoved() };
615
616 if (tempLoad == NO_OF_DUMPLOADS)
617 {
618 return;
619 }
620
621 // a load which is now ON has been identified for potentially being switched OFF
623 {
624 // During the post-transition period, any decrease in the energy level is noted.
626
627 // the energy thresholds must remain within range
629 {
631 }
632
633 // Only the active load may be switched during this period. All other loads must
634 // wait until the recent transition has had sufficient opportunity to take effect.
635 bOK_toRemoveLoad = (tempLoad == activeLoad);
636 }
637
638 if (bOK_toRemoveLoad)
639 {
641 activeLoad = tempLoad;
643 b_recentTransition = true;
644 }
645}
646
663{
664 // Restrictions apply for the period immediately after a load has been switched.
665 // Here the b_recentTransition flag is checked and updated as necessary.
666 // if (b_recentTransition)
667 // b_recentTransition = (++postTransitionCount < POST_TRANSITION_MAX_COUNT);
668 // for optimization, the next line is equivalent to the two lines above
670
672 {
673 // the energy state is in the upper half of the working range
674 f_lowerEnergyThreshold = f_lowerThreshold_default; // reset the "opposite" threshold
676 {
677 // Because the energy level is high, some action may be required
679 }
680 }
681 else
682 {
683 // the energy state is in the lower half of the working range
684 f_upperEnergyThreshold = f_upperThreshold_default; // reset the "opposite" threshold
686 {
687 // Because the energy level is low, some action may be required
689 }
690 }
691
692 updatePhysicalLoadStates(); // allows the logical-to-physical mapping to be changed
693
694 updatePortsStates(); // update the control ports for each of the physical loads
695
696 // Now that the energy-related decisions have been taken, min and max limits can now
697 // be applied to the level of the energy bucket. This is to ensure correct operation
698 // when conditions change, i.e. when import changes to export, and vice versa.
699 //
701 {
703 }
704 else if (f_energyInBucket_main < 0)
705 {
707 }
708}
709
725void processMinusHalfCycle(const uint8_t phase)
726{
727 // This is a convenient point to update the Low Pass Filter for removing the DC
728 // component from the phase that is being processed.
729 // The portion which is fed back into the integrator is approximately one percent
730 // of the average offset of all the SampleVs in the previous mains cycle.
731 //
732 l_DCoffset_V[phase] += (l_cumVdeltasThisCycle[phase] >> 12);
733 l_cumVdeltasThisCycle[phase] = 0;
734
735 // To ensure that this LP filter will always start up correctly when 240V AC is
736 // available, its output value needs to be prevented from drifting beyond the likely range
737 // of the voltage signal.
738 //
739 if (l_DCoffset_V[phase] < l_DCoffset_V_min)
740 {
742 }
743 else if (l_DCoffset_V[phase] > l_DCoffset_V_max)
744 {
746 }
747}
748
762{
763 for (uint8_t index = 0; index < NO_OF_DUMPLOADS; ++index)
764 {
765 if (0x00 == (loadPrioritiesAndState[index] & loadStateOnBit))
766 {
767 return (index);
768 }
769 }
770
771 return (NO_OF_DUMPLOADS);
772}
773
787{
788 uint8_t index{ NO_OF_DUMPLOADS };
789 do
790 {
792 {
793 return (index);
794 }
795 } while (index);
796
797 return (NO_OF_DUMPLOADS);
798}
799
816void processLatestContribution(const uint8_t phase)
817{
818 // for efficiency, the energy scale is Joules * SUPPLY_FREQUENCY
819 // add the latest energy contribution to the main energy accumulator
820 f_energyInBucket_main += (l_sumP[phase] / n_samplesDuringThisMainsCycle[phase]) * f_powerCal[phase];
821
822 // apply any adjustment that is required.
823 if (0 == phase)
824 {
825 f_energyInBucket_main -= REQUIRED_EXPORT_IN_WATTS; // energy scale is Joules x 50
826 b_newMainsCycle = true; // a 50 Hz 'tick' for use by the main code
827 }
828 // Applying max and min limits to the main accumulator's level
829 // is deferred until after the energy related decisions have been taken
830 //
831}
832
848{
850 {
851 return; // data logging period not yet reached
852 }
853
855
856 uint8_t phase{ NO_OF_PHASES };
857 do
858 {
859 --phase;
861 l_sumP_atSupplyPoint[phase] = 0;
862
863 copyOf_sum_Vsquared[phase] = l_sum_Vsquared[phase];
864 l_sum_Vsquared[phase] = 0;
865 } while (phase);
866
867 uint8_t i{ NO_OF_DUMPLOADS };
868 do
869 {
870 --i;
872 countLoadON[i] = 0;
873 } while (i);
874
878
881
882 // signal the main processor that logging data are available
883 // we skip the period from start to running stable
885}
886
904void processPlusHalfCycle(const uint8_t phase)
905{
906 processLatestContribution(phase); // runs at 6.6 ms intervals
907
908 // A performance check to monitor and display the minimum number of sets of
909 // ADC samples per mains cycle, the expected number being 20ms / (104us * 6) = 32.05
910 //
911 if (0 == phase)
912 {
914 {
916 }
917
919 }
920
921 l_sumP[phase] = 0;
923}
924
942void processRawSamples(const uint8_t phase)
943{
944 // The raw V and I samples are processed in "phase pairs"
945 const auto &lastPolarity{ polarityConfirmedOfLastSampleV[phase] };
946
948 {
949 // the polarity of this sample is positive
950 if (Polarities::POSITIVE != lastPolarity)
951 {
952 // This is the start of a new +ve half cycle, for this phase, just after the zero-crossing point.
954 {
956 }
957 else
958 {
959 processStartUp(phase);
960 }
961 }
962
963 // still processing samples where the voltage is POSITIVE ...
964 // check to see whether the trigger device can now be reliably armed
965 if ((0 == phase) && beyondStartUpPeriod && (2 == n_samplesDuringThisMainsCycle[0])) // lower value for larger sample set
966 {
967 // This code is executed once per 20mS, shortly after the start of each new mains cycle on phase 0.
969 }
970 }
971 else
972 {
973 // the polarity of this sample is negative
974 if (Polarities::NEGATIVE != lastPolarity)
975 {
976 // This is the start of a new -ve half cycle (just after the zero-crossing point)
978 }
979 }
980}
981
999void processVoltageRawSample(const uint8_t phase, const int16_t rawSample)
1000{
1001 processPolarity(phase, rawSample);
1002 confirmPolarity(phase);
1003
1004 processRawSamples(phase); // deals with aspects that only occur at particular stages of each mains cycle
1005
1006 processVoltage(phase);
1007
1008 if (phase == 0)
1009 {
1011 }
1012}
1013
1028{
1029 // display relevant settings for selected output mode
1030 DBUG(F("Output mode: "));
1032 {
1033 DBUGLN(F("normal"));
1034 }
1035 else
1036 {
1037 DBUGLN(F("anti-flicker"));
1038 DBUG(F("\toffsetOfEnergyThresholds = "));
1040 }
1041 DBUG(F("\tf_capacityOfEnergyBucket_main = "));
1043 DBUG(F("\tf_lowerEnergyThreshold = "));
1045 DBUG(F("\tf_upperEnergyThreshold = "));
1047}
1048
1079ISR(ADC_vect)
1080{
1081 static uint8_t sample_index{ 0 };
1082 int16_t rawSample;
1083
1084 switch (sample_index)
1085 {
1086 case 0:
1087 rawSample = ADC; // store the ADC value (this one is for Voltage L1)
1088 ADMUX = bit(REFS0) + sensorV[1]; // the conversion for I1 is already under way
1089 ++sample_index; // increment the control flag
1090 //
1091 processVoltageRawSample(0, rawSample);
1092 break;
1093 case 1:
1094 rawSample = ADC; // store the ADC value (this one is for Current L1)
1095 ADMUX = bit(REFS0) + sensorI[1]; // the conversion for V2 is already under way
1096 ++sample_index; // increment the control flag
1097 //
1098 processCurrentRawSample(0, rawSample);
1099 break;
1100 case 2:
1101 rawSample = ADC; // store the ADC value (this one is for Voltage L2)
1102 ADMUX = bit(REFS0) + sensorV[2]; // the conversion for I2 is already under way
1103 ++sample_index; // increment the control flag
1104 //
1105 processVoltageRawSample(1, rawSample);
1106 break;
1107 case 3:
1108 rawSample = ADC; // store the ADC value (this one is for Current L2)
1109 ADMUX = bit(REFS0) + sensorI[2]; // the conversion for V3 is already under way
1110 ++sample_index; // increment the control flag
1111 //
1112 processCurrentRawSample(1, rawSample);
1113 break;
1114 case 4:
1115 rawSample = ADC; // store the ADC value (this one is for Voltage L3)
1116 ADMUX = bit(REFS0) + sensorV[0]; // the conversion for I3 is already under way
1117 ++sample_index; // increment the control flag
1118 //
1119 processVoltageRawSample(2, rawSample);
1120 break;
1121 case 5:
1122 rawSample = ADC; // store the ADC value (this one is for Current L3)
1123 ADMUX = bit(REFS0) + sensorI[0]; // the conversion for V1 is already under way
1124 sample_index = 0; // reset the control flag
1125 //
1126 processCurrentRawSample(2, rawSample);
1127 break;
1128 default:
1129 sample_index = 0; // to prevent lockup (should never get here)
1130 }
1131} // end of ISR
Calibration values definition.
constexpr uint8_t loadPrioritiesAtStartup[NO_OF_DUMPLOADS]
Definition config.h:68
constexpr bool RELAY_DIVERSION
Definition config.h:40
constexpr bool OVERRIDE_PIN_PRESENT
Definition config.h:37
constexpr uint8_t dualTariffPin
Definition config.h:71
constexpr uint8_t forcePin
Definition config.h:74
constexpr RelayEngine relays
Definition config.h:77
constexpr uint8_t physicalLoadPin[NO_OF_DUMPLOADS]
Definition config.h:67
constexpr bool DUAL_TARIFF
Definition config.h:41
constexpr uint8_t diversionPin
Definition config.h:72
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:73
constexpr uint8_t watchDogPin
Definition config.h:75
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.
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.
volatile uint8_t copyOf_lowestNoOfSampleSetsPerMainsCycle
Definition processing.h:44
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
volatile bool b_reOrderLoads
Definition processing.h:34
constexpr uint8_t sensorV[NO_OF_PHASES]
Definition processing.h:18
constexpr uint8_t sensorI[NO_OF_PHASES]
Definition processing.h:19
volatile float copyOf_energyInBucket_main
Definition processing.h:43
volatile int32_t copyOf_sumP_atSupplyPoint[NO_OF_PHASES]
Definition processing.h:41
volatile int32_t copyOf_sum_Vsquared[NO_OF_PHASES]
Definition processing.h:42
volatile uint16_t copyOf_sampleSetsDuringThisDatalogPeriod
Definition processing.h:45
volatile bool b_overrideLoadOn[NO_OF_DUMPLOADS]
Definition processing.h:33
volatile bool b_newMainsCycle
Definition processing.h:32
volatile bool EDD_isIdle
Definition processing.h:36
volatile bool b_datalogEventPending
Definition processing.h:31
volatile bool b_diversionOff
Definition processing.h:35
constexpr uint16_t initialDelay
Definition processing.h:26
volatile uint16_t absenceOfDivertedEnergyCount
Definition processing.h:30
volatile uint16_t copyOf_countLoadON[NO_OF_DUMPLOADS]
Definition processing.h:46
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:216
void setPinsAsOutput(uint16_t pins)
Set the pins as OUTPUT.
Definition utils_pins.h:205
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