Skip to content

Commit f5094d7

Browse files
committed
Merge branch 'master' of https://github.com/RobTillaart/ACS712
2 parents 702ad81 + fd01481 commit f5094d7

File tree

8 files changed

+147
-41
lines changed

8 files changed

+147
-41
lines changed

ACS712.cpp

Lines changed: 44 additions & 27 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.3
4+
// VERSION: 0.3.4
55
// DATE: 2020-08-02
66
// PURPOSE: ACS712 library - current measurement
77
// URL: https://github.com/RobTillaart/ACS712
@@ -14,13 +14,19 @@
1414
ACS712::ACS712(uint8_t analogPin, float volts, uint16_t maxADC, float mVperAmpere)
1515
{
1616
_pin = analogPin;
17+
_mVperAmpere = mVperAmpere;
18+
_formFactor = ACS712_FF_SINUS;
19+
_noisemV = ACS712_DEFAULT_NOISE; // 21mV according to datasheet
20+
21+
// set in setADC()
22+
// keep it here until after experimental.
1723
_maxADC = maxADC;
1824
_mVperStep = 1000.0 * volts / maxADC; // 1x 1000 for V -> mV
19-
_mVperAmpere = mVperAmpere;
2025
_mAPerStep = 1000.0 * _mVperStep / _mVperAmpere;
21-
_formFactor = ACS712_FF_SINUS;
2226
_midPoint = maxADC / 2;
23-
_noisemV = ACS712_DEFAULT_NOISE; // 21mV according to datasheet
27+
28+
// default ADC is internal.
29+
setADC(_internalAnalog, volts, maxADC);
2430
}
2531

2632

@@ -36,16 +42,16 @@ float ACS712::mA_peak2peak(float frequency, uint16_t cycles)
3642
{
3743
int minimum, maximum;
3844
// Better than using midPoint
39-
minimum = maximum = analogRead(_pin);
45+
minimum = maximum = _readADC(_pin);
4046

4147
// find minimum and maximum
4248
uint32_t start = micros();
43-
while (micros() - start < period) // UNO ~180 samples...
49+
while (micros() - start < period) // UNO ~180 samples...
4450
{
45-
int value = analogRead(_pin);
51+
int value = _readADC(_pin);
4652
if (_suppresNoise) // average 2 samples.
4753
{
48-
value = (value + analogRead(_pin))/2;
54+
value = (value + _readADC(_pin))/2;
4955
}
5056
// determine extremes
5157
if (value < minimum) minimum = value;
@@ -76,17 +82,17 @@ float ACS712::mA_AC(float frequency, uint16_t cycles)
7682
uint16_t zeros = 0;
7783

7884
int _min, _max;
79-
_min = _max = analogRead(_pin);
85+
_min = _max = _readADC(_pin);
8086

8187
// find minimum and maximum and count the zero-level "percentage"
8288
uint32_t start = micros();
8389
while (micros() - start < period) // UNO ~180 samples...
8490
{
8591
samples++;
86-
int value = analogRead(_pin);
92+
int value = _readADC(_pin);
8793
if (_suppresNoise) // average 2 samples.
8894
{
89-
value = (value + analogRead(_pin))/2;
95+
value = (value + _readADC(_pin))/2;
9096
}
9197
// determine extremes
9298
if (value < _min) _min = value;
@@ -138,10 +144,10 @@ float ACS712::mA_AC_sampling(float frequency, uint16_t cycles)
138144
while (micros() - start < period)
139145
{
140146
samples++;
141-
int value = analogRead(_pin);
147+
int value = _readADC(_pin);
142148
if (_suppresNoise) // average 2 samples.
143149
{
144-
value = (value + analogRead(_pin))/2;
150+
value = (value + _readADC(_pin))/2;
145151
}
146152
float current = value - _midPoint;
147153
sumSquared += (current * current);
@@ -163,15 +169,15 @@ float ACS712::mA_AC_sampling(float frequency, uint16_t cycles)
163169
float ACS712::mA_DC(uint16_t cycles)
164170
{
165171
// read at least twice to stabilize the ADC
166-
analogRead(_pin);
172+
_readADC(_pin);
167173
if (cycles == 0) cycles = 1;
168174
float sum = 0;
169175
for (uint16_t i = 0; i < cycles; i++)
170176
{
171-
int value = analogRead(_pin);
177+
int value = _readADC(_pin);
172178
if (_suppresNoise) // average 2 samples.
173179
{
174-
value = (value + analogRead(_pin))/2;
180+
value = (value + _readADC(_pin))/2;
175181
}
176182
sum += (value - _midPoint);
177183
}
@@ -227,7 +233,7 @@ uint16_t ACS712::autoMidPoint(float frequency, uint16_t cycles)
227233
uint32_t start = micros();
228234
while (micros() - start < twoPeriods)
229235
{
230-
uint16_t reading = analogRead(_pin);
236+
uint16_t reading = _readADC(_pin);
231237
subTotal += reading;
232238
samples++;
233239
// Delaying prevents overflow
@@ -323,14 +329,14 @@ float ACS712::detectFrequency(float minimalFrequency)
323329
{
324330
int maximum = 0;
325331
int minimum = 0;
326-
maximum = minimum = analogRead(_pin);
332+
maximum = minimum = _readADC(_pin);
327333

328334
// determine maxima
329335
uint32_t timeOut = round(1000000.0 / minimalFrequency);
330336
uint32_t start = micros();
331337
while (micros() - start < timeOut)
332338
{
333-
int value = analogRead(_pin);
339+
int value = _readADC(_pin);
334340
if (value > maximum) maximum = value;
335341
if (value < minimum) minimum = value;
336342
}
@@ -346,13 +352,13 @@ float ACS712::detectFrequency(float minimalFrequency)
346352
timeOut *= 10;
347353
start = micros();
348354
// casting to int to keep compiler happy.
349-
while ((int(analogRead(_pin)) > Q1) && ((micros() - start) < timeOut));
350-
while ((int(analogRead(_pin)) <= Q3) && ((micros() - start) < timeOut));
355+
while ((int(_readADC(_pin)) > Q1) && ((micros() - start) < timeOut));
356+
while ((int(_readADC(_pin)) <= Q3) && ((micros() - start) < timeOut));
351357
start = micros();
352358
for (int i = 0; i < 10; i++)
353359
{
354-
while ((int(analogRead(_pin)) > Q1) && ((micros() - start) < timeOut));
355-
while ((int(analogRead(_pin)) <= Q3) && ((micros() - start) < timeOut));
360+
while ((int(_readADC(_pin)) > Q1) && ((micros() - start) < timeOut));
361+
while ((int(_readADC(_pin)) <= Q3) && ((micros() - start) < timeOut));
356362
}
357363
uint32_t stop = micros();
358364

@@ -380,13 +386,13 @@ float ACS712::getMicrosAdjust()
380386
// DEBUG
381387
uint16_t ACS712::getMinimum(uint16_t milliSeconds)
382388
{
383-
uint16_t minimum = analogRead(_pin);
389+
uint16_t minimum = _readADC(_pin);
384390

385391
// find minimum
386392
uint32_t start = millis();
387393
while (millis() - start < milliSeconds)
388394
{
389-
uint16_t value = analogRead(_pin);
395+
uint16_t value = _readADC(_pin);
390396
if (value < minimum) minimum = value;
391397
}
392398
return minimum;
@@ -395,18 +401,29 @@ uint16_t ACS712::getMinimum(uint16_t milliSeconds)
395401

396402
uint16_t ACS712::getMaximum(uint16_t milliSeconds)
397403
{
398-
uint16_t maximum = analogRead(_pin);
404+
uint16_t maximum = _readADC(_pin);
399405

400406
// find minimum
401407
uint32_t start = millis();
402408
while (millis() - start < milliSeconds)
403409
{
404-
uint16_t value = analogRead(_pin);
410+
uint16_t value = _readADC(_pin);
405411
if (value > maximum) maximum = value;
406412
}
407413
return maximum;
408414
}
409415

410416

417+
void ACS712::setADC(uint16_t (* f)(uint8_t), float volts, uint16_t maxADC)
418+
{
419+
_readADC = f;
420+
421+
_maxADC = maxADC;
422+
_mVperStep = 1000.0 * volts / maxADC; // 1x 1000 for V -> mV
423+
_mAPerStep = 1000.0 * _mVperStep / _mVperAmpere;
424+
_midPoint = maxADC / 2;
425+
}
426+
427+
411428
// -- END OF FILE --
412429

ACS712.h

Lines changed: 16 additions & 9 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.3
5+
// VERSION: 0.3.4
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.3"))
16+
#define ACS712_LIB_VERSION (F("0.3.4"))
1717

1818

1919
// ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2)
@@ -105,6 +105,9 @@ class ACS712
105105
uint16_t getMaximum(uint16_t milliSeconds = 20);
106106

107107

108+
// EXPERIMENTAL 0.3.4
109+
void setADC(uint16_t (*)(uint8_t), float volts, uint16_t maxADC);
110+
108111
private:
109112
uint8_t _pin;
110113
uint16_t _maxADC;
@@ -116,16 +119,20 @@ class ACS712
116119
uint8_t _noisemV;
117120
float _microsAdjust = 1.0; // 0.9986
118121
bool _suppresNoise = false;
122+
123+
// EXPERIMENTAL 0.3.4
124+
// supports up to 16 bits ADC.
125+
uint16_t (* _readADC)(uint8_t);
119126
};
120127

121128

122-
// simulate analogRead() - develop only -
123-
// static int aRead(uint8_t pin)
124-
// {
125-
// float t = micros();
126-
// float value = 515 + 50 * sin(t * PI / 180.0);
127-
// return value;
128-
// }
129+
// wrapper for internal analogRead()
130+
// solves platform specific casting.
131+
static uint16_t _internalAnalog(uint8_t pin)
132+
{
133+
return analogRead(pin);
134+
}
135+
129136

130137
// -- END OF FILE --
131138

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ 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.3] - 2023-03-01
9+
## [0.3.4] - 2023-01-14
10+
- experimental
11+
- add **void setADC()** to use an external ADC for measurements.
12+
- add **static uint16_t internalAnalog(uint8_t p)** wrapping analogRead() - solves casting.
13+
- add example ACS712_20_DC_external_ADC.ino
14+
15+
16+
## [0.3.3] - 2023-01-03
1017
- update GitHub actions
1118
- update license
1219
- add example
1320
- add URL in .h .cpp
1421

15-
1622
## [0.3.2] - 2022-11-18
1723
- fix #26 revert data type \_midPoint to int
1824
- Add CHANGELOG.md

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ float formFactor = 2.0 * mA_AC_sampling() / ACS.mA_peak2peak();
218218
See - ACS712_20_determine_form_factor.ino
219219

220220

221-
222221
#### Noise
223222

224223
Default = 21 mV (datasheet)
@@ -274,6 +273,23 @@ Testing with my UNO I got a factor 0.9986.
274273
Current version is experimental and not performance optimized.
275274

276275

276+
#### setADC (experimental 0.3.4)
277+
278+
- **void setADC(uint16_t (\*)(uint8_t), float volts, uint16_t maxADC)** sets the ADC function and its parameters.
279+
Defaults the internal **analogRead()** by this wrapper in ACS712.h:
280+
```cpp
281+
static uint16_t _internalAnalog(uint8_t pin)
282+
{
283+
return analogRead(pin);
284+
}
285+
```
286+
287+
Be sure to set the parameters of the constructor correctly.
288+
289+
- example ACS712_20_DC_external_ADC.ino
290+
- https://github.com/RobTillaart/ACS712/issues/31
291+
292+
277293
## Voltage divider
278294
279295
As per issue #15 in which an ACS712 was connected via a voltage divider to the ADC of an ESP32.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// FILE: ACS712_20_DC_external_ADC.ino
3+
// AUTHOR: Rob Tillaart
4+
// PURPOSE: demo to measure mA DC with external ADC
5+
// URL: https://github.com/RobTillaart/ACS712
6+
7+
// use with Arduino Serial Plotter
8+
9+
#include "ACS712.h"
10+
11+
12+
// Arduino UNO has 5.0 volt with a max ADC value of 1023 steps
13+
// ACS712 5A uses 185 mV per A
14+
// ACS712 20A uses 100 mV per A
15+
// ACS712 30A uses 66 mV per A
16+
17+
18+
ACS712 ACS(A0, 5.0, 1023, 100);
19+
// ESP 32 example (might requires resistors to step down the logic voltage)
20+
// ACS712 ACS(25, 3.3, 4095, 185);
21+
22+
23+
void setup()
24+
{
25+
Serial.begin(115200);
26+
while (!Serial);
27+
Serial.println(__FILE__);
28+
Serial.print("ACS712_LIB_VERSION: ");
29+
Serial.println(ACS712_LIB_VERSION);
30+
31+
ACS.setADC(testADC, 10, 1023);
32+
33+
// ACS.autoMidPoint();
34+
// Serial.println(ACS.getMidPoint());
35+
}
36+
37+
38+
void loop()
39+
{
40+
int mA = ACS.mA_DC();
41+
Serial.println(mA);
42+
delay(1000);
43+
}
44+
45+
// wrapper needed for external analogRead()
46+
// as casting behavior is undefined between different function signatures.
47+
uint16_t testADC(uint8_t p)
48+
{
49+
// simulation
50+
return 600 + p;
51+
// replace with an external ADC call.
52+
// return ADS.readADC(p);
53+
// return analogRead(p + 1); // use another internal ADC
54+
}
55+
56+
57+
// -- END OF FILE --

keywords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@ getMicrosAdjust KEYWORD2
3636
getMinimum KEYWORD2
3737
getMaximum KEYWORD2
3838

39+
setADC KEYWORD2
40+
3941

4042
# Constants (LITERAL1)
4143
ACS712_LIB_VERSION LITERAL1
44+
4245
ACS712_FF_SINUS LITERAL1
4346
ACS712_FF_SQUARE LITERAL1
4447
ACS712_FF_TRIANGLE LITERAL1

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.3",
24+
"version": "0.3.4",
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.3
2+
version=0.3.4
33
author=Rob Tillaart <[email protected]>, Pete Thompson <[email protected]>
44
maintainer=Rob Tillaart <[email protected]>
55
sentence=ACS712 library for Arduino.

0 commit comments

Comments
 (0)