Skip to content

Commit e9d55d0

Browse files
authored
Develop (#25)
* add float mVNoiseLevel(frequency, cycles) * add void suppressNoise(bool flag) - experimental suppression by averaging two samples. * add resetMidPoint() * improve midPoint functions * add RP2040 pico in build-ci * update readme.md / comments * add I2C_display + suppressNoise() example
1 parent f61dd5f commit e9d55d0

File tree

12 files changed

+419
-70
lines changed

12 files changed

+419
-70
lines changed

.arduino-ci.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
platforms:
2+
rpipico:
3+
board: rp2040:rp2040:rpipico
4+
package: rp2040:rp2040
5+
gcc:
6+
features:
7+
defines:
8+
- ARDUINO_ARCH_RP2040
9+
warnings:
10+
flags:
11+
12+
packages:
13+
rp2040:rp2040:
14+
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
15+
116
compile:
217
# Choosing to run compilation tests on 2 different Arduino platforms
318
platforms:
@@ -8,4 +23,5 @@ compile:
823
- m4
924
- esp32
1025
- esp8266
11-
# - mega2560
26+
# - mega2560
27+
- rpipico

ACS712.cpp

Lines changed: 81 additions & 34 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.0
4+
// VERSION: 0.3.1
55
// DATE: 2020-08-02
66
// PURPOSE: ACS712 library - current measurement
77
//
@@ -37,6 +37,13 @@
3737
// add float mA_peak2peak(freq, cycles)
3838
// add debug getMinimum(), getmaximum();
3939
// update Readme.md
40+
// 0.3.1 2022-09-xx add float mVNoiseLevel(frequency, cycles)
41+
// add void suppressNoise(bool flag)
42+
// experimental suppression by averaging two samples.
43+
// update readme.md
44+
// improve midPoint functions
45+
// add resetMidPoint()
46+
// add RP2040 pico in build-ci
4047

4148

4249
#include "ACS712.h"
@@ -46,6 +53,7 @@
4653
ACS712::ACS712(uint8_t analogPin, float volts, uint16_t maxADC, float mVperAmpere)
4754
{
4855
_pin = analogPin;
56+
_maxADC = maxADC;
4957
_mVperStep = 1000.0 * volts / maxADC; // 1x 1000 for V -> mV
5058
_mVperAmpere = mVperAmpere;
5159
_mAPerStep = 1000.0 * _mVperStep / _mVperAmpere;
@@ -62,25 +70,30 @@ float ACS712::mA_peak2peak(float frequency, uint16_t cycles)
6270

6371
if (cycles == 0) cycles = 1;
6472
float sum = 0;
65-
73+
6674
for (uint16_t i = 0; i < cycles; i++)
6775
{
6876
int minimum, maximum;
6977
// Better than using midPoint
70-
minimum = maximum = analogRead(_pin);
78+
minimum = maximum = analogRead(_pin);
7179

7280
// find minimum and maximum
7381
uint32_t start = micros();
7482
while (micros() - start < period) // UNO ~180 samples...
7583
{
76-
int val = analogRead(_pin);
84+
int value = analogRead(_pin);
85+
if (_suppresNoise) // average 2 samples.
86+
{
87+
value = (value + analogRead(_pin))/2;
88+
}
7789
// determine extremes
78-
if (val < minimum) minimum = val;
79-
else if (val > maximum) maximum = val;
90+
if (value < minimum) minimum = value;
91+
else if (value > maximum) maximum = value;
8092
}
8193
sum += (maximum - minimum);
8294
}
83-
float peak2peak = sum * _mAPerStep / cycles;
95+
float peak2peak = sum * _mAPerStep;
96+
if (cycles > 1) peak2peak /= cycles;
8497

8598
return peak2peak;
8699
}
@@ -109,12 +122,16 @@ float ACS712::mA_AC(float frequency, uint16_t cycles)
109122
while (micros() - start < period) // UNO ~180 samples...
110123
{
111124
samples++;
112-
int val = analogRead(_pin);
125+
int value = analogRead(_pin);
126+
if (_suppresNoise) // average 2 samples.
127+
{
128+
value = (value + analogRead(_pin))/2;
129+
}
113130
// determine extremes
114-
if (val < _min) _min = val;
115-
else if (val > _max) _max = val;
131+
if (value < _min) _min = value;
132+
else if (value > _max) _max = value;
116133
// count zeros
117-
if (abs(val - _midPoint) <= zeroLevel ) zeros++;
134+
if (abs(value - _midPoint) <= zeroLevel ) zeros++;
118135
}
119136
int peak2peak = _max - _min;
120137

@@ -135,7 +152,8 @@ float ACS712::mA_AC(float frequency, uint16_t cycles)
135152
// return 1000.0 * 0.5 * peak2peak * _mVperStep * _formFactor / _mVperAmpere);
136153
sum += peak2peak * FF;
137154
}
138-
float mA = 0.5 * sum * _mAPerStep / cycles;
155+
float mA = 0.5 * sum * _mAPerStep;
156+
if (cycles > 1) mA /= cycles;
139157

140158
return mA;
141159
}
@@ -159,16 +177,23 @@ float ACS712::mA_AC_sampling(float frequency, uint16_t cycles)
159177
while (micros() - start < period)
160178
{
161179
samples++;
162-
float current = analogRead(_pin) - _midPoint;
180+
int value = analogRead(_pin);
181+
if (_suppresNoise) // average 2 samples.
182+
{
183+
value = (value + analogRead(_pin))/2;
184+
}
185+
float current = value - _midPoint;
163186
sumSquared += (current * current);
164187
// if (abs(current) > noiseLevel)
165-
// {
188+
// {
166189
// sumSquared += (current * current);
167190
// }
168191
}
169192
sum += sqrt(sumSquared / samples);
170193
}
171-
float mA = sum * _mAPerStep / cycles;
194+
float mA = sum * _mAPerStep;
195+
if (cycles > 1) mA /= cycles;
196+
172197
return mA;
173198
}
174199

@@ -181,19 +206,24 @@ float ACS712::mA_DC(uint16_t cycles)
181206
float sum = 0;
182207
for (uint16_t i = 0; i < cycles; i++)
183208
{
184-
sum += (analogRead(_pin) - _midPoint);
209+
int value = analogRead(_pin);
210+
if (_suppresNoise) // average 2 samples.
211+
{
212+
value = (value + analogRead(_pin))/2;
213+
}
214+
sum += (value - _midPoint);
185215
}
186-
float mA = sum * _mAPerStep / cycles;
216+
float mA = sum * _mAPerStep;
217+
if (cycles > 1) mA /= cycles;
218+
187219
return mA;
188220
}
189221

190222

191223
// CALIBRATION MIDPOINT
192224
uint16_t ACS712::setMidPoint(uint16_t midPoint)
193225
{
194-
// TODO - check valid value?
195-
// if (midPoint > _maxADC) return 0xFFFF;
196-
_midPoint = midPoint;
226+
if (midPoint <= _maxADC) _midPoint = midPoint;
197227
return _midPoint;
198228
};
199229

@@ -206,20 +236,14 @@ uint16_t ACS712::getMidPoint()
206236

207237
uint16_t ACS712::incMidPoint()
208238
{
209-
// TODO - check valid value?
210-
// if ((midPoint + 1) > _maxADC) return 0xFFFF;
211-
// needs MAXADC which is not kept
212-
_midPoint += 1;
239+
if (_midPoint < _maxADC) _midPoint += 1;
213240
return _midPoint;
214241
};
215242

216243

217244
uint16_t ACS712::decMidPoint()
218245
{
219-
// TODO - check valid value?
220-
// if ((midPoint == 0) return 0xFFFF; #define ACS712_ERR_INVALID_MIDPOINT 0xFFFF
221-
// needs MAXADC which is not kept
222-
_midPoint -= 1;
246+
if (_midPoint > 0) _midPoint -= 1;
223247
return _midPoint;
224248
};
225249

@@ -244,16 +268,24 @@ uint16_t ACS712::autoMidPoint(float frequency, uint16_t cycles)
244268
uint16_t reading = analogRead(_pin);
245269
subTotal += reading;
246270
samples++;
247-
// Delaying ensures we won't overflow since we'll perform a maximum of 40,000 reads @ 50 Hz.
271+
// Delaying prevents overflow
272+
// since we'll perform a maximum of 40,000 reads @ 50 Hz.
248273
delayMicroseconds(1);
249274
}
250-
total += (subTotal/samples);
275+
total += (subTotal / samples);
251276
}
252277
_midPoint = total / cycles;
253278
return _midPoint;
254279
}
255280

256281

282+
uint16_t ACS712::resetMidPoint()
283+
{
284+
_midPoint = _maxADC / 2;
285+
return _midPoint;
286+
};
287+
288+
257289
// CALIBRATION FORM FACTOR
258290
void ACS712::setFormFactor(float formFactor)
259291
{
@@ -281,6 +313,20 @@ uint8_t ACS712::getNoisemV()
281313
};
282314

283315

316+
float ACS712::mVNoiseLevel(float frequency, uint16_t cycles)
317+
{
318+
float mA = mA_peak2peak(frequency, cycles);
319+
// divide by 2 as the level is half of the peak to peak range
320+
return mA * _mVperAmpere * 0.001 / 2;
321+
}
322+
323+
324+
void ACS712::suppressNoise(bool flag)
325+
{
326+
_suppresNoise = flag;
327+
}
328+
329+
284330
// CALIBRATION mV PER AMP
285331
// Adjusting resolution AC and DC
286332
void ACS712::setmVperAmp(float mVperAmpere)
@@ -337,13 +383,14 @@ float ACS712::detectFrequency(float minimalFrequency)
337383
// to prevent endless loop a timeout is checked.
338384
timeOut *= 10;
339385
start = micros();
340-
while ((analogRead(_pin) > Q1) && ((micros() - start) < timeOut));
341-
while ((analogRead(_pin) <= Q3) && ((micros() - start) < timeOut));
386+
// casting to int to keep compiler happy.
387+
while ((int(analogRead(_pin)) > Q1) && ((micros() - start) < timeOut));
388+
while ((int(analogRead(_pin)) <= Q3) && ((micros() - start) < timeOut));
342389
start = micros();
343390
for (int i = 0; i < 10; i++)
344391
{
345-
while ((analogRead(_pin) > Q1) && ((micros() - start) < timeOut));
346-
while ((analogRead(_pin) <= Q3) && ((micros() - start) < timeOut));
392+
while ((int(analogRead(_pin)) > Q1) && ((micros() - start) < timeOut));
393+
while ((int(analogRead(_pin)) <= Q3) && ((micros() - start) < timeOut));
347394
}
348395
uint32_t stop = micros();
349396

ACS712.h

Lines changed: 11 additions & 4 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.0
5+
// VERSION: 0.3.1
66
// DATE: 2020-08-02
77
// PURPOSE: ACS712 library - current measurement
88
//
@@ -12,7 +12,7 @@
1212

1313
#include "Arduino.h"
1414

15-
#define ACS712_LIB_VERSION (F("0.3.0"))
15+
#define ACS712_LIB_VERSION (F("0.3.1"))
1616

1717

1818
// ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2)
@@ -68,6 +68,8 @@ class ACS712
6868
uint16_t decMidPoint();
6969
// Auto midPoint, assuming zero DC current or any AC current
7070
uint16_t autoMidPoint(float frequency = ACS712_DEFAULT_FREQ, uint16_t cycles = 1);
71+
// resets to half maxADC
72+
uint16_t resetMidPoint();
7173

7274

7375
// Form Factor is also known as crest factor;
@@ -79,6 +81,9 @@ class ACS712
7981
// noise defaults 21 datasheet
8082
void setNoisemV(uint8_t noisemV = ACS712_DEFAULT_NOISE);
8183
uint8_t getNoisemV();
84+
// enable/disable noiseSuppression for this measurement as needed.
85+
float mVNoiseLevel(float frequency = ACS712_DEFAULT_FREQ, uint16_t cycles = 1); // uses mA_peak2peak()
86+
void suppressNoise(bool flag);
8287

8388

8489
// Adjusting resolution AC and DC
@@ -101,13 +106,15 @@ class ACS712
101106

102107
private:
103108
uint8_t _pin;
109+
uint16_t _maxADC;
104110
float _mVperStep;
105111
float _formFactor; // peak2peak -> RMS
106112
float _mVperAmpere;
107113
float _mAPerStep;
108-
int _midPoint;
114+
uint16_t _midPoint;
109115
uint8_t _noisemV;
110-
float _microsAdjust = 1.0; // 0.9986
116+
float _microsAdjust = 1.0; // 0.9986
117+
bool _suppresNoise = false;
111118
};
112119

113120

0 commit comments

Comments
 (0)