Skip to content

Commit

Permalink
add autoMidPointDC() (#36)
Browse files Browse the repository at this point in the history
- add **autoMidPointDC(cycles)** see issue #35
- add rounding to **autoMidPoint()**
- update README.md
  • Loading branch information
RobTillaart authored Apr 20, 2023
1 parent 2a6eaee commit d7beb2d
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 18 deletions.
17 changes: 15 additions & 2 deletions ACS712.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: ACS712.cpp
// AUTHOR: Rob Tillaart, Pete Thompson
// VERSION: 0.3.5
// VERSION: 0.3.6
// DATE: 2020-08-02
// PURPOSE: ACS712 library - current measurement
// URL: https://github.com/RobTillaart/ACS712
Expand Down Expand Up @@ -242,7 +242,20 @@ uint16_t ACS712::autoMidPoint(float frequency, uint16_t cycles)
}
total += (subTotal / samples);
}
_midPoint = total / cycles;
_midPoint = (total + (cycles/2))/ cycles; // rounding.
return _midPoint;
}


uint16_t ACS712::autoMidPointDC(uint16_t cycles)
{
if (cycles == 0) cycles = 1;
uint32_t total = 0;
for (uint16_t i = 0; i < cycles; i++)
{
total += analogRead(_pin);
}
_midPoint = (total + (cycles/2))/ cycles; // rounding.
return _midPoint;
}

Expand Down
9 changes: 7 additions & 2 deletions ACS712.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: ACS712.h
// AUTHOR: Rob Tillaart, Pete Thompson
// VERSION: 0.3.5
// VERSION: 0.3.6
// DATE: 2020-08-02
// PURPOSE: ACS712 library - current measurement
// URL: https://github.com/RobTillaart/ACS712
Expand All @@ -13,7 +13,7 @@

#include "Arduino.h"

#define ACS712_LIB_VERSION (F("0.3.5"))
#define ACS712_LIB_VERSION (F("0.3.6"))


// ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2)
Expand Down Expand Up @@ -68,7 +68,10 @@ class ACS712
uint16_t incMidPoint();
uint16_t decMidPoint();
// Auto midPoint, assuming zero DC current or any AC current
// For DC current set the frequency to 1000 or so to reduce blocking.
uint16_t autoMidPoint(float frequency = ACS712_DEFAULT_FREQ, uint16_t cycles = 1);
// Auto midPoint, dedicated for zero DC current (much faster ==> less blocking)
uint16_t autoMidPointDC(uint16_t cycles = 1);
// resets to half maxADC
uint16_t resetMidPoint();

Expand Down Expand Up @@ -106,8 +109,10 @@ class ACS712


// EXPERIMENTAL 0.3.4
// function returning 16 bit max, with pin or channel as parameter
void setADC(uint16_t (*)(uint8_t), float volts, uint16_t maxADC);


private:
uint8_t _pin;
uint16_t _maxADC;
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.3.6] - 2023-04-19
- add **autoMidPointDC(cycles)** see issue #35
- add rounding to **autoMidPoint()**
- update README.md


## [0.3.5] - 2023-01-18
- fix #33 failing build => issue 345 created @ arduino-ci
- redo **setADC()**
- allows reset to internal **analogRead()** too now.
- update README.md


## [0.3.4] - 2023-01-14
- experimental
- add **void setADC()** to use an external ADC for measurements.
Expand Down
37 changes: 27 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,21 +151,27 @@ Since 0.3.0 all midpoint functions return the actual midPoint.

- **uint16_t setMidPoint(uint16_t midPoint)** sets midpoint for the ADC conversion.
Parameter must be between 0 and maxADC/2, otherwise midpoint is not changed.
- **uint16_t autoMidPoint(float frequency = 50, uint16_t cycles = 1)** Auto midPoint,
assuming zero DC current or any AC current.
The function takes the average of many measurements during one or more full cycles.
Note the function therefore blocks for at least 2 periods.
By increasing the number of cycles the function averages even more measurements,
possibly resulting in a better midPoint. Idea is that noise will average out.
This function is mandatory for measuring AC.
- 0.2.2 frequencies other than 50 and 60 are supported.
- 0.2.8 the parameter cycles allow to average over a number of cycles.
- **uint16_t getMidPoint()** read the value set / determined.
- **uint16_t incMidPoint()** manual increase midpoint, e.g. useful in an interactive application.
Will not increase if midpoint equals macADC.
- **uint16_t decMidPoint()** manual decrease midpoint.
Will not decrease if midpoint equals 0.
- **uint16_t resetMidPoint()** resets the midpoint to the initial value of maxADC / 2 as in the constructor.
- **uint16_t autoMidPointDC(uint16_t cycles = 1)** Auto midPoint for DC only.
Assuming zero DC current. To reduce the noise cycles must be increased even up to 100.
This method is typically much faster for DC than the **autoMidPoint(freq, cycles)**
for the same number of cycles. (See issue #35)
- **uint16_t autoMidPoint(float frequency = 50, uint16_t cycles = 1)** Auto midPoint, for any AC current or zero DC current.
For DC one can use a high frequency e.g. 1000 Hz to reduce the time blocking.
The function takes the average of many measurements during one or more full cycles.
Note the function therefore blocks for at least 2 periods which is about
40 ms for 50 Hz.
By increasing the number of cycles the function averages even more measurements,
possibly resulting in a better midPoint. Idea is that noise will average out.
This function is mandatory for measuring AC.
- 0.2.2 frequencies other than 50 and 60 are supported.
- 0.2.8 the parameter cycles allow to average over a number of cycles.


Since version 0.3.0 there is another way to determine the midPoint.
One can use the two debug functions.
Expand Down Expand Up @@ -393,23 +399,34 @@ The examples show the basic working of the functions.

#### Must

- test more
- other than the 20A module
- 5, 10, 30, 50 ...
- need to buy extra hardware


#### Should - 0.3.x

- investigate **estimateMidPoint(confidence)** See issue #35
- is less blocking by spreading the sampling over many calls.
returning a confidence level.
- investigate noise suppression #21 (0.3.1 and later)
- investigate blocking calls:
- **mA_AC()** blocks for about 20 ms at 50 Hz.
This might affect task scheduling on a ESP32. Needs to be investigated.
Probably need a separate thread that wakes up when new analogRead is available?
- RTOS specific class?
- **detectFrequency(float)** blocks pretty long.
- investigate **detectFrequency(float)** blocks pretty long.


#### Could

- merge **mA_AC()** and **mA_AC_sampling()** into one. (0.4.0)
- or remove - depreciate - the worst one
- add range check to (all) set functions?
- add unit test for **autoMidPointDC()** (needed?)
- **setMidPoint()**
- Q: could midpoint be set beyond maxADC? is there any use case?


#### Won't (unless requested)
Expand Down
54 changes: 54 additions & 0 deletions examples/ACS712_autoMidPointDC/ACS712_autoMidPointDC.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// FILE: ACS712_autoMidPointDC.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo detect DC midpoint.
// URL: https://github.com/RobTillaart/ACS712


#include "ACS712.h"


// Arduino UNO has 5.0 volt with a max ADC value of 1023 steps
// ACS712 5A uses 185 mV per A
// ACS712 20A uses 100 mV per A
// ACS712 30A uses 66 mV per A
ACS712 ACS(A0, 5.0, 1023, 100);
// ESP 32 example (might requires resistors to step down the logic voltage)
// ACS712 ACS(25, 3.3, 4095, 185);


uint32_t start, stop;

uint16_t midPoint = 0;

void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.println(__FILE__);
Serial.print("ACS712_LIB_VERSION: ");
Serial.println(ACS712_LIB_VERSION);
delay(10);

// might be different 1 cycle or 100.
start = micros();
midPoint = ACS.autoMidPointDC(1);
stop = micros();
Serial.println("ACS.autoMidPointDC()");
Serial.print("us:\t");
Serial.println(stop - start);
Serial.print("MP 1:\t");
Serial.println(midPoint);

midPoint = ACS.autoMidPointDC(100);
Serial.print("MP 100:\t");
Serial.println(midPoint);
}


void loop()
{
}


// -- END OF FILE --
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ incMidPoint KEYWORD2
decMidPoint KEYWORD2
resetMidPoint KEYWORD2
autoMidPoint KEYWORD2
autoMidPointDC KEYWORD2

setFormFactor KEYWORD2
getFormFactor KEYWORD2
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/ACS712.git"
},
"version": "0.3.5",
"version": "0.3.6",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ACS712
version=0.3.5
version=0.3.6
author=Rob Tillaart <[email protected]>, Pete Thompson <[email protected]>
maintainer=Rob Tillaart <[email protected]>
sentence=ACS712 library for Arduino.
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test_001.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,4 @@ unittest(test_AmperePerStep)
unittest_main()


// -- END OF FILE --
// -- END OF FILE --

0 comments on commit d7beb2d

Please sign in to comment.