Skip to content

Commit d7beb2d

Browse files
authored
add autoMidPointDC() (#36)
- add **autoMidPointDC(cycles)** see issue #35 - add rounding to **autoMidPoint()** - update README.md
1 parent 2a6eaee commit d7beb2d

File tree

9 files changed

+113
-18
lines changed

9 files changed

+113
-18
lines changed

ACS712.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// FILE: ACS712.cpp
33
// AUTHOR: Rob Tillaart, Pete Thompson
4-
// VERSION: 0.3.5
4+
// VERSION: 0.3.6
55
// DATE: 2020-08-02
66
// PURPOSE: ACS712 library - current measurement
77
// URL: https://github.com/RobTillaart/ACS712
@@ -242,7 +242,20 @@ uint16_t ACS712::autoMidPoint(float frequency, uint16_t cycles)
242242
}
243243
total += (subTotal / samples);
244244
}
245-
_midPoint = total / cycles;
245+
_midPoint = (total + (cycles/2))/ cycles; // rounding.
246+
return _midPoint;
247+
}
248+
249+
250+
uint16_t ACS712::autoMidPointDC(uint16_t cycles)
251+
{
252+
if (cycles == 0) cycles = 1;
253+
uint32_t total = 0;
254+
for (uint16_t i = 0; i < cycles; i++)
255+
{
256+
total += analogRead(_pin);
257+
}
258+
_midPoint = (total + (cycles/2))/ cycles; // rounding.
246259
return _midPoint;
247260
}
248261

ACS712.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// FILE: ACS712.h
44
// AUTHOR: Rob Tillaart, Pete Thompson
5-
// VERSION: 0.3.5
5+
// VERSION: 0.3.6
66
// DATE: 2020-08-02
77
// PURPOSE: ACS712 library - current measurement
88
// URL: https://github.com/RobTillaart/ACS712
@@ -13,7 +13,7 @@
1313

1414
#include "Arduino.h"
1515

16-
#define ACS712_LIB_VERSION (F("0.3.5"))
16+
#define ACS712_LIB_VERSION (F("0.3.6"))
1717

1818

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

@@ -106,8 +109,10 @@ class ACS712
106109

107110

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

115+
111116
private:
112117
uint8_t _pin;
113118
uint16_t _maxADC;

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88

9+
## [0.3.6] - 2023-04-19
10+
- add **autoMidPointDC(cycles)** see issue #35
11+
- add rounding to **autoMidPoint()**
12+
- update README.md
13+
14+
915
## [0.3.5] - 2023-01-18
1016
- fix #33 failing build => issue 345 created @ arduino-ci
1117
- redo **setADC()**
1218
- allows reset to internal **analogRead()** too now.
1319
- update README.md
1420

15-
1621
## [0.3.4] - 2023-01-14
1722
- experimental
1823
- add **void setADC()** to use an external ADC for measurements.

README.md

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,21 +151,27 @@ Since 0.3.0 all midpoint functions return the actual midPoint.
151151

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

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

394400
#### Must
395401

402+
- test more
403+
- other than the 20A module
404+
- 5, 10, 30, 50 ...
405+
- need to buy extra hardware
406+
396407

397408
#### Should - 0.3.x
398409

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

407421

408422
#### Could
409423

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

414431

415432
#### Won't (unless requested)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// FILE: ACS712_autoMidPointDC.ino
3+
// AUTHOR: Rob Tillaart
4+
// PURPOSE: demo detect DC midpoint.
5+
// URL: https://github.com/RobTillaart/ACS712
6+
7+
8+
#include "ACS712.h"
9+
10+
11+
// Arduino UNO has 5.0 volt with a max ADC value of 1023 steps
12+
// ACS712 5A uses 185 mV per A
13+
// ACS712 20A uses 100 mV per A
14+
// ACS712 30A uses 66 mV per A
15+
ACS712 ACS(A0, 5.0, 1023, 100);
16+
// ESP 32 example (might requires resistors to step down the logic voltage)
17+
// ACS712 ACS(25, 3.3, 4095, 185);
18+
19+
20+
uint32_t start, stop;
21+
22+
uint16_t midPoint = 0;
23+
24+
void setup()
25+
{
26+
Serial.begin(115200);
27+
while (!Serial);
28+
Serial.println(__FILE__);
29+
Serial.print("ACS712_LIB_VERSION: ");
30+
Serial.println(ACS712_LIB_VERSION);
31+
delay(10);
32+
33+
// might be different 1 cycle or 100.
34+
start = micros();
35+
midPoint = ACS.autoMidPointDC(1);
36+
stop = micros();
37+
Serial.println("ACS.autoMidPointDC()");
38+
Serial.print("us:\t");
39+
Serial.println(stop - start);
40+
Serial.print("MP 1:\t");
41+
Serial.println(midPoint);
42+
43+
midPoint = ACS.autoMidPointDC(100);
44+
Serial.print("MP 100:\t");
45+
Serial.println(midPoint);
46+
}
47+
48+
49+
void loop()
50+
{
51+
}
52+
53+
54+
// -- END OF FILE --

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ incMidPoint KEYWORD2
1515
decMidPoint KEYWORD2
1616
resetMidPoint KEYWORD2
1717
autoMidPoint KEYWORD2
18+
autoMidPointDC KEYWORD2
1819

1920
setFormFactor KEYWORD2
2021
getFormFactor KEYWORD2

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"type": "git",
2222
"url": "https://github.com/RobTillaart/ACS712.git"
2323
},
24-
"version": "0.3.5",
24+
"version": "0.3.6",
2525
"license": "MIT",
2626
"frameworks": "arduino",
2727
"platforms": "*",

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ACS712
2-
version=0.3.5
2+
version=0.3.6
33
author=Rob Tillaart <rob.tillaart@gmail.com>, Pete Thompson <pete.thompson@yahoo.com>
44
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
55
sentence=ACS712 library for Arduino.

test/unit_test_001.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,4 @@ unittest(test_AmperePerStep)
212212
unittest_main()
213213

214214

215-
// -- END OF FILE --
215+
// -- END OF FILE --

0 commit comments

Comments
 (0)