Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit eac769e
Author: Frédéric Metrich <[email protected]>
Date:   Thu Feb 15 21:29:47 2024 +0100

    Update Readme.md (#82)

commit 82d84ee
Author: Frédéric Metrich <[email protected]>
Date:   Tue Feb 13 14:37:48 2024 +0100

    Added Thermostat_tri_HC.pdf

commit fad5e19
Author: Frédéric Metrich <[email protected]>
Date:   Tue Feb 13 14:36:53 2024 +0100

    Update Thermostat_tri_HC.drawio

commit f03b4ca
Author: Frédéric Metrich <[email protected]>
Date:   Mon Feb 12 11:07:04 2024 +0100

    WIP: 1772479 Fix mvAvg

commit 5e5646a
Author: Frédéric Metrich <[email protected]>
Date:   Mon Feb 5 00:04:30 2024 +0100

    Update CodeQL

commit 4684e01
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:35:01 2024 +0100

    Upt readme

commit d957494
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:32:24 2024 +0100

    Try again

commit 46884f3
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:30:21 2024 +0100

    Try fix

commit c7db21e
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:28:09 2024 +0100

    Fix readme

commit 248a89a
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:23:14 2024 +0100

    Reorganize readmes

commit fff68e0
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:11:19 2024 +0100

    Fix branch name

commit 656308b
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:10:39 2024 +0100

    Fix filenames

commit b911d8d
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:08:55 2024 +0100

    Fix links

commit 83d5591
Author: Frédéric Metrich <[email protected]>
Date:   Sun Feb 4 23:07:18 2024 +0100

    Multilinugal readme + more details

commit 1772479
Author: Frédéric Metrich <[email protected]>
Date:   Fri Feb 2 11:39:13 2024 +0100

    Fix mvAvg

commit 90204aa
Author: Frédéric Metrich <[email protected]>
Date:   Mon Jan 22 22:02:08 2024 +0100

    Fix relay template

commit eef84ea
Author: Frédéric Metrich <[email protected]>
Date:   Mon Jan 22 16:36:28 2024 +0100

    Enhanced sliding average...
  • Loading branch information
FredM67 committed Feb 16, 2024
1 parent e23f5a3 commit 4049b2e
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 99 deletions.
61 changes: 57 additions & 4 deletions Mk2_3phase_RFdatalog_temp/movingAvg.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,61 @@

#include "type_traits.hpp"

/**
* @brief Helper compile-time function to retrieve the previous power of 2 of the given number (120 => 64 => 6)
*
* @param v The input number
* @return constexpr uint8_t The next power of two
*/
constexpr uint8_t round_up_to_power_of_2(uint16_t v)
{
if (__builtin_popcount(v) == 1) { return __builtin_ctz(v) - 1; }

uint8_t next_pow_of_2{ 0 };

while (v)
{
v >>= 1;
++next_pow_of_2;
}

return --next_pow_of_2;
}

/**
* @brief Exponentially Weighted Moving Average
*
* @details The smoothing factor is the approximate amount of values taken to calculate the average.
* Since the Arduino is very slow and does not provide any dedicated math co-processor,
* the smoothing factor will be rounded to the previous power of 2. Ie 120 will be rounded to 64.
* This allows to perform all the calculations with integer math, which is much faster !
*
* @note Because of the 'sign extension', the sign is copied into lower bits.
*
* @tparam A Smoothing factor
* @param input Input value
* @return long Output value
*/
template< uint8_t A = 10 >
class EWMA_average
{
public:
void addValue(int32_t input)
{
w = w - x + input;
x = w >> round_up_to_power_of_2(A);
}

auto getAverage() const
{
return x;
}

private:
int32_t w{ 0 };
int32_t x{ 0 };
};

/**
* @brief Template class for implementing a sliding average
*
Expand Down Expand Up @@ -52,12 +107,10 @@ class movingAvg
if constexpr (is_floating_point< T >::value)
{
_sum = 0.0F;
_sub_sum = 0.0F;
}
else
{
_sum = 0;
_sub_sum = 0;
}

uint8_t i{ DURATION_IN_MINUTES };
Expand All @@ -66,14 +119,14 @@ class movingAvg
if constexpr (is_floating_point< T >::value)
{
_ar[i] = 0.0F;
_sub_ar[i] = 0.0F;
}
else
{
_ar[i] = 0;
_sub_ar[i] = 0;
}
} while (i);

_clear_sub();
}

/**
Expand Down
10 changes: 5 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ In a balanced situation, you don't need any neutral wire. To switch off the devi

For that, I've "recycled" a peak/off peak 3-phase relay but you can use any 3-phase relay. It doesn't matter on which phase the command coil is connected, but it must be permanent (not through the router).

![Heater with mechanical thermostat](../../img/Heater_mechanical.png)
![Heater with mechanical thermostat](img/Heater_mechanical.png)
*Figure: Wiring diagram*

## Heater with ACI single phase thermostat

Check failure on line 183 in Readme.md

View workflow job for this annotation

GitHub Actions / spellcheck

ACI ==> ACPI
Expand All @@ -186,7 +186,7 @@ In this case, it's somehow the same situation as before.
You don't need to buy a 3-phase kit to convert your single phase heater.
The ACI pcb must be connected to a permanent phase. It will then control any 3-phase relay.

Check failure on line 187 in Readme.md

View workflow job for this annotation

GitHub Actions / spellcheck

ACI ==> ACPI

![Heater with ACI single phase thermostat](../../img/Heater_ACI_Mono.png)
![Heater with ACI single phase thermostat](img/Heater_ACI_Mono.png)

Check failure on line 189 in Readme.md

View workflow job for this annotation

GitHub Actions / spellcheck

ACI ==> ACPI
*Figure: Wiring diagram*

## Heater with ACI 3-phase thermostat (without neutral wire)

Check failure on line 192 in Readme.md

View workflow job for this annotation

GitHub Actions / spellcheck

ACI ==> ACPI
Expand All @@ -205,7 +205,7 @@ The remaining connected phase is the one in the middle of the power connector.

The ACI pcb must be connected to 3 permanent phases.

![Heater with ACI 3-phase thermostat](../../img/Heater_ACI_Tri.png)
![Heater with ACI 3-phase thermostat](img/Heater_ACI_Tri.png)
*Figure: Wiring diagram*

## Alternatives WITHOUT neutral wire
Expand All @@ -230,12 +230,12 @@ In **red**, security switch (see the 'S' on each pole) : all 3 phases are switch

In **green**, only 2 phases are switched off, L2 et L3. ***It is IMPORTANT that the phase L1, not switched by the thermostat, DOES NOT pass through the triac***.

![Mechanical thermostat](../../img/Thermostat.png)
![Mechanical thermostat](img/Thermostat.png)
*Figure: An example of a thermostat*

---

![Heater with mechanical thermostat](../../img/Heater_mechanical-No_neutral.png)
![Heater with mechanical thermostat](img/Heater_mechanical-No_neutral.png)
*Figure: Wiring diagram*

## Support
Expand Down
60 changes: 49 additions & 11 deletions dev/MathPerfTests/MathPerfTests.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#include "movingAvg.h"

const int nb_of_interation_per_pass = 30000;
const int nb_of_pass = 100;
const int nb_of_interation_per_pass = 500;
const int nb_of_pass = 10;

unsigned long initial_time = 0;
unsigned long final_time = 0;
Expand All @@ -23,7 +23,7 @@ volatile float float_1 = 0;
volatile float float_2 = 0;
volatile float float_3 = 0;

volatile long long_1 = 0;
long long_1 = 0;
volatile long long_2 = 0;
volatile long long_3 = 0;

Expand All @@ -39,11 +39,43 @@ volatile boolean bool_1 = 0;
volatile boolean bool_2 = 0;
volatile boolean bool_3 = 0;

movingAvg< int32_t, 1, 12 > sliding_Average;
constexpr uint8_t round_up_to_power_of_2(uint16_t v) {
if (__builtin_popcount(v) == 1) { return __builtin_ctz(v) - 1; }

uint8_t next_pow_of_2{ 0 };

while (v) {
v >>= 1;
++next_pow_of_2;
}

return --next_pow_of_2;
}

template< uint8_t A = 10 >
class EWMA_average {
public:
void addValue(int32_t input) {
w = w - x + input;
x = w >> round_up_to_power_of_2(A);
}

auto getAverage() const {
return x;
}

private:
int32_t w{ 0 };
int32_t x{ 0 };
};

movingAvg< int32_t, 10, 12 > sliding_Average;
EWMA_average<120> ewma_average;

void setup() {

Serial.begin(115200);
Serial.println("Setup ***");
}

void loop() {
Expand All @@ -67,10 +99,12 @@ void loop() {
initial_time = micros();
for (int i = 0; i < nb_of_interation_per_pass; i++) {
dummy++; // The dummy instruction is also performed here so that we can remove the effect of the dummy FOR loop accurately.
// **************** PUT YOUR COMMAND TO TEST HERE ********************
sliding_Average.addValue(i);
// **************** PUT YOUR COMMAND TO TEST HERE ********************
long_1 = sin(i) * 1000;

sliding_Average.addValue(long_1);
ewma_average.addValue(long_1);

long_3 = sliding_Average.getAverage();
// **************** PUT YOUR COMMAND TO TEST HERE ********************
}
final_time = micros();
Expand All @@ -82,20 +116,24 @@ void loop() {

Serial.print(sliding_Average.getAverage());
Serial.print(" - ");
Serial.print(ewma_average.getAverage());
Serial.print(" - ");
Serial.print(j);
Serial.print(". ");
print_result(duration);

sliding_Average.clear();
}

Serial.println();
Serial.println("********* FINAL AVERAGED VALUE *********** ");
print_result(duration_sum / nb_of_pass);
Serial.println("****************************************** ");
Serial.println();
for (uint8_t idx = 0; idx < sliding_Average.getSize(); ++idx) {
Serial.println(sliding_Average.getElement(idx));
}
Serial.println();
//for (uint8_t idx = 0; idx < sliding_Average.getSize(); ++idx) {
// Serial.println(sliding_Average.getElement(idx));
//}
//Serial.println();
duration_sum = 0;
delay(2000);
}
Expand Down
3 changes: 0 additions & 3 deletions dev/MathPerfTests/movingAvg.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,14 @@ class movingAvg
void clear()
{
_idx = 0;
_sub_idx = 0;

if constexpr (is_floating_point< T >::value)
{
_sum = 0.0F;
_sub_sum = 0.0F;
}
else
{
_sum = 0;
_sub_sum = 0;
}

uint8_t i{ DURATION_IN_MINUTES };
Expand Down
Loading

0 comments on commit 4049b2e

Please sign in to comment.