Skip to content

Commit

Permalink
Merge pull request #2 from pete-thompson/master
Browse files Browse the repository at this point in the history
Add autoConfigure
  • Loading branch information
RobTillaart authored Aug 7, 2020
2 parents 331e67b + ebfca02 commit 5da7057
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 29 deletions.
30 changes: 24 additions & 6 deletions ACS712.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//
// FILE: ACS712.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// DATE: 2020-03-17
// AUTHOR: Rob Tillaart, Pete Thompson
// VERSION: 0.2.0
// DATE: 2020-08-02
// PURPOSE: ACS712 library - current measurement
//
// HISTORY:
Expand All @@ -11,7 +11,7 @@
// 0.1.2 2020-03-21 automatic formfactor test
// 0.1.3 2020-05-27 fix library.json
// 0.1.4 2020-08-02 Allow for faster processors
//
// 0.2.0 2020-08-02 Add autoMidPoint

#include "ACS712.h"

Expand All @@ -23,7 +23,7 @@ ACS712::ACS712(uint8_t analogPin, float volts, uint16_t maxADC, uint8_t mVperA)
_mVperAmpere = mVperA;
_formFactor = 0.70710678119; // 0.5 * sqrt(2); TODO: should be smaller in practice 0.5 ?
_midPoint = maxADC / 2;
_noise = 0.021 * (maxADC / volts); // Noise is 21mV according to datasheet
_noisemV = 21; // Noise is 21mV according to datasheet
}

int ACS712::mA_AC(uint8_t freq)
Expand All @@ -40,7 +40,7 @@ int ACS712::mA_AC(uint8_t freq)
int val = analogRead(_pin);
if (val < _min) _min = val;
if (val > _max) _max = val;
if (abs(val - _midPoint) < _noise) zeros++; // Noise max 4 during test
if (abs(val - _midPoint) <= (_noisemV/_mVpstep)) zeros++;
}
int p2p = (_max - _min);

Expand Down Expand Up @@ -71,4 +71,22 @@ int ACS712::mA_DC()
return 1000.0 * steps * _mVpstep / _mVperAmpere;
}

// configure by sampling for 2 cycles of AC
// Also works for DC as long as no current flowing
void ACS712::autoMidPoint(uint8_t freq)
{
uint32_t start = micros();
uint16_t twoPeriods = ((freq == 60) ? 16670 : 20000) * 2;
uint32_t total = 0;
uint32_t samples = 0;
while (micros() - start < twoPeriods) {
uint16_t reading = analogRead(_pin);
total += reading;
samples ++;
// Delaying ensures we won't overflow since we'll perform a maximum of 40,000 reads
delayMicroseconds(1);
}
_midPoint = total / samples;
}

// END OF FILE
12 changes: 7 additions & 5 deletions ACS712.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//
// FILE: ACS712.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// DATE: 2020-03-17
// VERSION: 0.2.0
// DATE: 2020-08-02
// PURPOSE: ACS712 library - current measurement
//
// Tested with a RobotDyn ACS712 20A breakout + UNO.
Expand Down Expand Up @@ -41,14 +41,16 @@ class ACS712
inline uint16_t getMidPoint() { return _midPoint; };
inline void incMidPoint() { _midPoint++; };
inline void decMidPoint() { _midPoint--; };
// Auto midPoint, assuming zero DC current or any AC current
void autoMidPoint(uint8_t freq = 50);

// also known as crest factor; affects AC only
inline void setFormFactor(float ff) { _formFactor = ff; };
inline float getFormFactor() { return _formFactor; };

// noise
inline void setNoise(uint8_t noise) { _noise = noise; };
inline uint8_t getNoise() { return _noise; };
inline void setNoisemV(uint8_t noisemV) { _noisemV = noisemV; };
inline uint8_t getNoisemV() { return _noisemV; };

// AC and DC
inline void setmVperAmp(uint8_t mva) { _mVperAmpere = mva; };
Expand All @@ -60,7 +62,7 @@ class ACS712
float _formFactor; // P2P -> RMS
uint8_t _mVperAmpere;
uint16_t _midPoint;
uint8_t _noise;
uint8_t _noisemV;
};

// END OF FILE
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ Current Sensor - 5A, 20A, 30A

## Description

The ACS712 is a chip to measure current, both AC or DC. The chip has an
analog output that provides a voltage that is lineair with the current.
The ACS712 is a chip to measure current, both AC or DC. The chip has an
analog output that provides a voltage that is lineair with the current.
The ACS712 library supports only a built in ADC by means of analogRead().
There are 2 core functions:

* **int mA_DC()**
* **int mA_AC()**

To measure DC current a single analogRead() with some conversion math is sufficient to get
To measure DC current a single analogRead() with some conversion math is sufficient to get
a value. To stabilize the signal analogRead() is called twice.

To measure AC current **a blocking loop for 20 millis** is run to determine the
peak to peak value which is converted to the RMS value. To convert the peak2peak
value to RMS one need the so called crest or form factor. This factor depends heavily
To measure AC current **a blocking loop for 20 millis** is run to determine the
peak to peak value which is converted to the RMS value. To convert the peak2peak
value to RMS one need the so called crest or form factor. This factor depends heavily
on the signal form. For a perfect sinus the value is sqrt(2)/2.

## Test
Expand All @@ -26,16 +26,18 @@ The library is tested with the RobotDyn ACS712 20A breakout and an Arduino UNO.

## Operation

With the constructor the parameters **volts** and **maxADC (steps)** of the ADC are set
together with the **milliVolt per Ampere** value. The last parameter can be adjusted
afterwards, e.g. to callibrate this value runtime. Note this parameter affects both
With the constructor the parameters **volts** and **maxADC (steps)** of the ADC are set
together with the **milliVolt per Ampere** value. The last parameter can be adjusted
afterwards, e.g. to callibrate this value runtime. Note this parameter affects both
AC and DC measurements.

To callibrate the zero level for DC measurements, 4 functions are available to
To callibrate the zero level for DC measurements, 5 functions are available to
adjust the midPoint.

To callibrate the RMS value for AC measurements, 2 functions are available to
To callibrate the RMS value for AC measurements, 2 functions are available to
get and set the formFactor.

The examples show the basic working of the functions.
To callibrate the noise level (used for AC measurements), 2 functions are available to
get and set the noise in mV.

The examples show the basic working of the functions.
13 changes: 12 additions & 1 deletion examples/ACS712_20_AC/ACS712_20_AC.ino
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,28 @@
// ACS712 30A uses 66 mV per A

ACS712 ACS(A0, 5.0, 1023, 100);
// ESP 32 example (requires resistors to step down the logic voltage)
//ACS712 ACS(25, 5.0, 4095, 185);

void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);

ACS.autoMidPoint();
Serial.print("MidPoint: ");
Serial.print(ACS.getMidPoint());
Serial.print(". Noise mV: ");
Serial.println(ACS.getNoisemV());
}

void loop()
{
int mA = ACS.mA_AC();
Serial.println(mA);
Serial.print("mA: ");
Serial.print(mA);
Serial.print(". Form factor: ");
Serial.println(ACS.getFormFactor());
}

// END OF FILE
3 changes: 3 additions & 0 deletions examples/ACS712_20_AC_DEMO/ACS712_20_AC_DEMO.ino
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
// ACS712 30A uses 66 mV per A

ACS712 ACS(A0, 5.0, 1023, 100);
// ESP 32 example (requires resistors to step down the logic voltage)
//ACS712 ACS(25, 5.0, 4095, 185);

void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
ACS.autoMidPoint();
}

void loop()
Expand Down
3 changes: 3 additions & 0 deletions examples/ACS712_20_DC/ACS712_20_DC.ino
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
// ACS712 30A uses 66 mV per A

ACS712 ACS(A0, 5.0, 1023, 100);
// ESP 32 example (requires resistors to step down the logic voltage)
//ACS712 ACS(25, 5.0, 4095, 185);

void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
ACS.autoMidPoint();
}

void loop()
Expand Down
3 changes: 3 additions & 0 deletions examples/ACS712_20_DC_DEMO/ACS712_20_DC_DEMO.ino
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
// ACS712 30A uses 66 mV per A

ACS712 ACS(A0, 5.0, 1023, 100);
// ESP 32 example (requires resistors to step down the logic voltage)
//ACS712 ACS(25, 5.0, 4095, 185);

void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
ACS.autoMidPoint();
}

void loop()
Expand Down
8 changes: 7 additions & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@
"name": "Rob Tillaart",
"email": "[email protected]",
"maintainer": true
},
{
"name": "Pete Thompson",
"email": "[email protected]",
"maintainer": false
}

],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/ACS712"
},
"version":"0.1.3",
"version":"0.2.0",
"frameworks": "arduino",
"platforms": "*"
}
8 changes: 4 additions & 4 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name=ACS712
version=0.1.3
author=Rob Tillaart <[email protected]>
version=0.2.0
author=Rob Tillaart <[email protected]>, Pete Thompson <[email protected]>
maintainer=Rob Tillaart <[email protected]>
sentence=ACS712 library for Arduino.
sentence=ACS712 library for Arduino.
paragraph=Current measurement, tested with RobotDyn ACDC 20A Module.
category=Signal Input/Output
url=https://github.com/RobTillaart/ACS712
architectures=*
includes=ACS712.h
depends=
depends=

0 comments on commit 5da7057

Please sign in to comment.