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//
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"
4653ACS712::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
192224uint16_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
207237uint16_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
217244uint16_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
258290void 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
286332void 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
0 commit comments