From 3598a42f1d99ca9d81ccf4db54daba6e8774f5af Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Thu, 2 Dec 2021 19:29:13 +0100 Subject: [PATCH] 0.2.5 ACS712 --- libraries/ACS712/ACS712.cpp | 33 ++++++++++++++++------------- libraries/ACS712/ACS712.h | 8 +++---- libraries/ACS712/library.json | 2 +- libraries/ACS712/library.properties | 2 +- libraries/ACS712/readme.md | 8 +++---- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/libraries/ACS712/ACS712.cpp b/libraries/ACS712/ACS712.cpp index fdc1d3c6..cc49d2be 100644 --- a/libraries/ACS712/ACS712.cpp +++ b/libraries/ACS712/ACS712.cpp @@ -1,7 +1,7 @@ // // FILE: ACS712.cpp // AUTHOR: Rob Tillaart, Pete Thompson -// VERSION: 0.2.4 +// VERSION: 0.2.5 // DATE: 2020-08-02 // PURPOSE: ACS712 library - current measurement // @@ -16,7 +16,8 @@ // 0.2.2 2021-06-23 support for more frequencies. // 0.2.3 2021-10-15 changed frequencies to float, for optimal tuning. // updated build CI, readme.md -// 0.2.4 2021-11-22 add experimental detectFrequency +// 0.2.4 2021-11-22 add experimental detectFrequency() +// 0.2.5 2021-12-03 add timeout to detectFrequency() #include "ACS712.h" @@ -110,37 +111,39 @@ void ACS712::autoMidPoint(float freq) // Experimental frequency detection. // uses oversampling and averaging to minimize variation // blocks for substantial amount of time, depending on minimalFrequency -float ACS712::detectFrequency(float mininmalFrequency) +float ACS712::detectFrequency(float minimalFrequency) { - uint16_t maximum = 0; - uint16_t minimum = 0; + int maximum = 0; + int minimum = 0; maximum = minimum = analogRead(_pin); // determine maxima - uint32_t sampleTime = round(1000000.0 / mininmalFrequency); + uint32_t timeOut = round(1000000.0 / minimalFrequency); uint32_t start = micros(); - while (micros() - start < sampleTime) + while (micros() - start < timeOut) { - uint16_t value = analogRead(_pin); + int value = analogRead(_pin); if (value > maximum) maximum = value; if (value < minimum) minimum = value; } // calculate quarter points // using quarter points is less noise prone than using one single midpoint - uint16_t Q1 = (3 * minimum + maximum ) / 4; - uint16_t Q3 = (minimum + 3 * maximum ) / 4; + int Q1 = (3 * minimum + maximum ) / 4; + int Q3 = (minimum + 3 * maximum ) / 4; // 10x passing Quantile points // wait for the right moment to start - while (analogRead(_pin) > Q1); - while (analogRead(_pin) <= Q3); + // to prevent endless loop a timeout is checked. + timeOut *= 10; + start = micros(); + while ((analogRead(_pin) > Q1) && ((micros() - start) < timeOut)); + while ((analogRead(_pin) <= Q3) && ((micros() - start) < timeOut)); start = micros(); for (int i = 0; i < 10; i++) { - // note these loops can block forever. Need a timeout. - while (analogRead(_pin) > Q1); // here - while (analogRead(_pin) < Q3); // and here + while ((analogRead(_pin) > Q1) && ((micros() - start) < timeOut)); + while ((analogRead(_pin) <= Q3) && ((micros() - start) < timeOut)); } uint32_t stop = micros(); diff --git a/libraries/ACS712/ACS712.h b/libraries/ACS712/ACS712.h index 5e35d74b..876c8370 100644 --- a/libraries/ACS712/ACS712.h +++ b/libraries/ACS712/ACS712.h @@ -2,7 +2,7 @@ // // FILE: ACS712.h // AUTHOR: Rob Tillaart, Pete Thompson -// VERSION: 0.2.4 +// VERSION: 0.2.5 // DATE: 2020-08-02 // PURPOSE: ACS712 library - current measurement // @@ -12,7 +12,7 @@ #include "Arduino.h" -#define ACS712_LIB_VERSION (F("0.2.4")) +#define ACS712_LIB_VERSION (F("0.2.5")) // ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2) @@ -75,8 +75,8 @@ class ACS712 // Experimental frequency detection. // the minimal frequency determines the time to sample. - float detectFrequency(float mininmalFrequency = 40); - void setMicrosAdjust(float value = 1.0) { _microsAdjust = value; }; + float detectFrequency(float minimalFrequency = 40); + void setMicrosAdjust(float factor = 1.0) { _microsAdjust = factor; }; float getMicrosAdjust() { return _microsAdjust; }; diff --git a/libraries/ACS712/library.json b/libraries/ACS712/library.json index 708640d2..56a10519 100644 --- a/libraries/ACS712/library.json +++ b/libraries/ACS712/library.json @@ -21,7 +21,7 @@ "type": "git", "url": "https://github.com/RobTillaart/ACS712.git" }, - "version": "0.2.4", + "version": "0.2.5", "license": "MIT", "frameworks": "arduino", "platforms": "*", diff --git a/libraries/ACS712/library.properties b/libraries/ACS712/library.properties index 8f023ddf..7216624f 100644 --- a/libraries/ACS712/library.properties +++ b/libraries/ACS712/library.properties @@ -1,5 +1,5 @@ name=ACS712 -version=0.2.4 +version=0.2.5 author=Rob Tillaart , Pete Thompson maintainer=Rob Tillaart sentence=ACS712 library for Arduino. diff --git a/libraries/ACS712/readme.md b/libraries/ACS712/readme.md index bfe201ca..787a44c9 100644 --- a/libraries/ACS712/readme.md +++ b/libraries/ACS712/readme.md @@ -103,10 +103,10 @@ Typical values see constructor above. #### Experimental -- **float detectFrequency(float minFreq = 40)** Detect the frequency of the AC signal. -- **void setMicrosAdjust(float value = 1.0)** adjusts the timing of micros in **detectFrequency()**. +- **float detectFrequency(float minimalFrequency = 40)** Detect the frequency of the AC signal. +- **void setMicrosAdjust(float factor = 1.0)** adjusts the timing of micros in **detectFrequency()**. Values are typical around 1.0 ± 1% -- **float getMicrosAdjust()** returns the set value. +- **float getMicrosAdjust()** returns the set factor. The minimum frequency of 40 Hz is used to sample enough time to find the minimum and maximum for 50 and 60 Hz signals. Thereafter the signal is sampled 10 cycles to minimize the variation of the frequency. @@ -148,8 +148,8 @@ The examples show the basic working of the functions. - mA_AC blocks 20 ms so might affect task scheduling on a ESP32. This needs to be investigated. Probably need a separate thread that wakes up when new analogRead is available. +**detectFrequency** also blocks pretty long. - int point2point(float freq) function for AC. Is part of mA_AC() already. Needs extra global variables, which are slower than local ones Or just cache the last p2p value? -- improve robustness of the **detectFrequency()** function (timeout 2nd part) - external analogue read support? separate class?