mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.3.5 ACS712
This commit is contained in:
parent
cac33b7d86
commit
aceae77552
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// FILE: ACS712.cpp
|
// FILE: ACS712.cpp
|
||||||
// AUTHOR: Rob Tillaart, Pete Thompson
|
// AUTHOR: Rob Tillaart, Pete Thompson
|
||||||
// VERSION: 0.3.4
|
// VERSION: 0.3.5
|
||||||
// DATE: 2020-08-02
|
// DATE: 2020-08-02
|
||||||
// PURPOSE: ACS712 library - current measurement
|
// PURPOSE: ACS712 library - current measurement
|
||||||
// URL: https://github.com/RobTillaart/ACS712
|
// URL: https://github.com/RobTillaart/ACS712
|
||||||
@ -26,7 +26,7 @@ ACS712::ACS712(uint8_t analogPin, float volts, uint16_t maxADC, float mVperAmper
|
|||||||
_midPoint = maxADC / 2;
|
_midPoint = maxADC / 2;
|
||||||
|
|
||||||
// default ADC is internal.
|
// default ADC is internal.
|
||||||
setADC(_internalAnalog, volts, maxADC);
|
setADC(NULL, volts, maxADC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -42,16 +42,16 @@ float ACS712::mA_peak2peak(float frequency, uint16_t cycles)
|
|||||||
{
|
{
|
||||||
int minimum, maximum;
|
int minimum, maximum;
|
||||||
// Better than using midPoint
|
// Better than using midPoint
|
||||||
minimum = maximum = _readADC(_pin);
|
minimum = maximum = _analogRead(_pin);
|
||||||
|
|
||||||
// find minimum and maximum
|
// find minimum and maximum
|
||||||
uint32_t start = micros();
|
uint32_t start = micros();
|
||||||
while (micros() - start < period) // UNO ~180 samples...
|
while (micros() - start < period) // UNO ~180 samples...
|
||||||
{
|
{
|
||||||
int value = _readADC(_pin);
|
int value = _analogRead(_pin);
|
||||||
if (_suppresNoise) // average 2 samples.
|
if (_suppresNoise) // average 2 samples.
|
||||||
{
|
{
|
||||||
value = (value + _readADC(_pin))/2;
|
value = (value + _analogRead(_pin))/2;
|
||||||
}
|
}
|
||||||
// determine extremes
|
// determine extremes
|
||||||
if (value < minimum) minimum = value;
|
if (value < minimum) minimum = value;
|
||||||
@ -82,17 +82,17 @@ float ACS712::mA_AC(float frequency, uint16_t cycles)
|
|||||||
uint16_t zeros = 0;
|
uint16_t zeros = 0;
|
||||||
|
|
||||||
int _min, _max;
|
int _min, _max;
|
||||||
_min = _max = _readADC(_pin);
|
_min = _max = _analogRead(_pin);
|
||||||
|
|
||||||
// find minimum and maximum and count the zero-level "percentage"
|
// find minimum and maximum and count the zero-level "percentage"
|
||||||
uint32_t start = micros();
|
uint32_t start = micros();
|
||||||
while (micros() - start < period) // UNO ~180 samples...
|
while (micros() - start < period) // UNO ~180 samples...
|
||||||
{
|
{
|
||||||
samples++;
|
samples++;
|
||||||
int value = _readADC(_pin);
|
int value = _analogRead(_pin);
|
||||||
if (_suppresNoise) // average 2 samples.
|
if (_suppresNoise) // average 2 samples.
|
||||||
{
|
{
|
||||||
value = (value + _readADC(_pin))/2;
|
value = (value + _analogRead(_pin))/2;
|
||||||
}
|
}
|
||||||
// determine extremes
|
// determine extremes
|
||||||
if (value < _min) _min = value;
|
if (value < _min) _min = value;
|
||||||
@ -144,10 +144,10 @@ float ACS712::mA_AC_sampling(float frequency, uint16_t cycles)
|
|||||||
while (micros() - start < period)
|
while (micros() - start < period)
|
||||||
{
|
{
|
||||||
samples++;
|
samples++;
|
||||||
int value = _readADC(_pin);
|
int value = _analogRead(_pin);
|
||||||
if (_suppresNoise) // average 2 samples.
|
if (_suppresNoise) // average 2 samples.
|
||||||
{
|
{
|
||||||
value = (value + _readADC(_pin))/2;
|
value = (value + _analogRead(_pin))/2;
|
||||||
}
|
}
|
||||||
float current = value - _midPoint;
|
float current = value - _midPoint;
|
||||||
sumSquared += (current * current);
|
sumSquared += (current * current);
|
||||||
@ -169,15 +169,15 @@ float ACS712::mA_AC_sampling(float frequency, uint16_t cycles)
|
|||||||
float ACS712::mA_DC(uint16_t cycles)
|
float ACS712::mA_DC(uint16_t cycles)
|
||||||
{
|
{
|
||||||
// read at least twice to stabilize the ADC
|
// read at least twice to stabilize the ADC
|
||||||
_readADC(_pin);
|
_analogRead(_pin);
|
||||||
if (cycles == 0) cycles = 1;
|
if (cycles == 0) cycles = 1;
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
for (uint16_t i = 0; i < cycles; i++)
|
for (uint16_t i = 0; i < cycles; i++)
|
||||||
{
|
{
|
||||||
int value = _readADC(_pin);
|
int value = _analogRead(_pin);
|
||||||
if (_suppresNoise) // average 2 samples.
|
if (_suppresNoise) // average 2 samples.
|
||||||
{
|
{
|
||||||
value = (value + _readADC(_pin))/2;
|
value = (value + _analogRead(_pin))/2;
|
||||||
}
|
}
|
||||||
sum += (value - _midPoint);
|
sum += (value - _midPoint);
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ uint16_t ACS712::autoMidPoint(float frequency, uint16_t cycles)
|
|||||||
uint32_t start = micros();
|
uint32_t start = micros();
|
||||||
while (micros() - start < twoPeriods)
|
while (micros() - start < twoPeriods)
|
||||||
{
|
{
|
||||||
uint16_t reading = _readADC(_pin);
|
uint16_t reading = _analogRead(_pin);
|
||||||
subTotal += reading;
|
subTotal += reading;
|
||||||
samples++;
|
samples++;
|
||||||
// Delaying prevents overflow
|
// Delaying prevents overflow
|
||||||
@ -329,14 +329,14 @@ float ACS712::detectFrequency(float minimalFrequency)
|
|||||||
{
|
{
|
||||||
int maximum = 0;
|
int maximum = 0;
|
||||||
int minimum = 0;
|
int minimum = 0;
|
||||||
maximum = minimum = _readADC(_pin);
|
maximum = minimum = _analogRead(_pin);
|
||||||
|
|
||||||
// determine maxima
|
// determine maxima
|
||||||
uint32_t timeOut = round(1000000.0 / minimalFrequency);
|
uint32_t timeOut = round(1000000.0 / minimalFrequency);
|
||||||
uint32_t start = micros();
|
uint32_t start = micros();
|
||||||
while (micros() - start < timeOut)
|
while (micros() - start < timeOut)
|
||||||
{
|
{
|
||||||
int value = _readADC(_pin);
|
int value = _analogRead(_pin);
|
||||||
if (value > maximum) maximum = value;
|
if (value > maximum) maximum = value;
|
||||||
if (value < minimum) minimum = value;
|
if (value < minimum) minimum = value;
|
||||||
}
|
}
|
||||||
@ -352,13 +352,13 @@ float ACS712::detectFrequency(float minimalFrequency)
|
|||||||
timeOut *= 10;
|
timeOut *= 10;
|
||||||
start = micros();
|
start = micros();
|
||||||
// casting to int to keep compiler happy.
|
// casting to int to keep compiler happy.
|
||||||
while ((int(_readADC(_pin)) > Q1) && ((micros() - start) < timeOut));
|
while ((int(_analogRead(_pin)) > Q1) && ((micros() - start) < timeOut));
|
||||||
while ((int(_readADC(_pin)) <= Q3) && ((micros() - start) < timeOut));
|
while ((int(_analogRead(_pin)) <= Q3) && ((micros() - start) < timeOut));
|
||||||
start = micros();
|
start = micros();
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
while ((int(_readADC(_pin)) > Q1) && ((micros() - start) < timeOut));
|
while ((int(_analogRead(_pin)) > Q1) && ((micros() - start) < timeOut));
|
||||||
while ((int(_readADC(_pin)) <= Q3) && ((micros() - start) < timeOut));
|
while ((int(_analogRead(_pin)) <= Q3) && ((micros() - start) < timeOut));
|
||||||
}
|
}
|
||||||
uint32_t stop = micros();
|
uint32_t stop = micros();
|
||||||
|
|
||||||
@ -386,13 +386,13 @@ float ACS712::getMicrosAdjust()
|
|||||||
// DEBUG
|
// DEBUG
|
||||||
uint16_t ACS712::getMinimum(uint16_t milliSeconds)
|
uint16_t ACS712::getMinimum(uint16_t milliSeconds)
|
||||||
{
|
{
|
||||||
uint16_t minimum = _readADC(_pin);
|
uint16_t minimum = _analogRead(_pin);
|
||||||
|
|
||||||
// find minimum
|
// find minimum
|
||||||
uint32_t start = millis();
|
uint32_t start = millis();
|
||||||
while (millis() - start < milliSeconds)
|
while (millis() - start < milliSeconds)
|
||||||
{
|
{
|
||||||
uint16_t value = _readADC(_pin);
|
uint16_t value = _analogRead(_pin);
|
||||||
if (value < minimum) minimum = value;
|
if (value < minimum) minimum = value;
|
||||||
}
|
}
|
||||||
return minimum;
|
return minimum;
|
||||||
@ -401,13 +401,13 @@ uint16_t ACS712::getMinimum(uint16_t milliSeconds)
|
|||||||
|
|
||||||
uint16_t ACS712::getMaximum(uint16_t milliSeconds)
|
uint16_t ACS712::getMaximum(uint16_t milliSeconds)
|
||||||
{
|
{
|
||||||
uint16_t maximum = _readADC(_pin);
|
uint16_t maximum = _analogRead(_pin);
|
||||||
|
|
||||||
// find minimum
|
// find minimum
|
||||||
uint32_t start = millis();
|
uint32_t start = millis();
|
||||||
while (millis() - start < milliSeconds)
|
while (millis() - start < milliSeconds)
|
||||||
{
|
{
|
||||||
uint16_t value = _readADC(_pin);
|
uint16_t value = _analogRead(_pin);
|
||||||
if (value > maximum) maximum = value;
|
if (value > maximum) maximum = value;
|
||||||
}
|
}
|
||||||
return maximum;
|
return maximum;
|
||||||
@ -425,5 +425,17 @@ void ACS712::setADC(uint16_t (* f)(uint8_t), float volts, uint16_t maxADC)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PRIVATE
|
||||||
|
//
|
||||||
|
uint16_t ACS712::_analogRead(uint8_t pin)
|
||||||
|
{
|
||||||
|
// if extern ADC is defined use it.
|
||||||
|
if (_readADC != NULL) return _readADC(pin);
|
||||||
|
return analogRead(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -- END OF FILE --
|
// -- END OF FILE --
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// FILE: ACS712.h
|
// FILE: ACS712.h
|
||||||
// AUTHOR: Rob Tillaart, Pete Thompson
|
// AUTHOR: Rob Tillaart, Pete Thompson
|
||||||
// VERSION: 0.3.4
|
// VERSION: 0.3.5
|
||||||
// DATE: 2020-08-02
|
// DATE: 2020-08-02
|
||||||
// PURPOSE: ACS712 library - current measurement
|
// PURPOSE: ACS712 library - current measurement
|
||||||
// URL: https://github.com/RobTillaart/ACS712
|
// URL: https://github.com/RobTillaart/ACS712
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
#define ACS712_LIB_VERSION (F("0.3.4"))
|
#define ACS712_LIB_VERSION (F("0.3.5"))
|
||||||
|
|
||||||
|
|
||||||
// ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2)
|
// ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2)
|
||||||
@ -123,16 +123,10 @@ class ACS712
|
|||||||
// EXPERIMENTAL 0.3.4
|
// EXPERIMENTAL 0.3.4
|
||||||
// supports up to 16 bits ADC.
|
// supports up to 16 bits ADC.
|
||||||
uint16_t (* _readADC)(uint8_t);
|
uint16_t (* _readADC)(uint8_t);
|
||||||
|
uint16_t _analogRead(uint8_t pin);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// wrapper for internal analogRead()
|
|
||||||
// solves platform specific casting.
|
|
||||||
static uint16_t _internalAnalog(uint8_t pin)
|
|
||||||
{
|
|
||||||
return analogRead(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -- END OF FILE --
|
// -- END OF FILE --
|
||||||
|
|
||||||
|
@ -6,13 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|||||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
|
||||||
|
## [0.3.5] - 2023-01-18
|
||||||
|
- fix #33 failing build => issue 345 created @ arduino-ci
|
||||||
|
- redo **setADC()**
|
||||||
|
- allows reset to internal **analogRead()** too now.
|
||||||
|
- update README.md
|
||||||
|
|
||||||
|
|
||||||
## [0.3.4] - 2023-01-14
|
## [0.3.4] - 2023-01-14
|
||||||
- experimental
|
- experimental
|
||||||
- add **void setADC()** to use an external ADC for measurements.
|
- add **void setADC()** to use an external ADC for measurements.
|
||||||
- add **static uint16_t internalAnalog(uint8_t p)** wrapping analogRead() - solves casting.
|
- add **static uint16_t internalAnalog(uint8_t p)** wrapping analogRead() - solves casting.
|
||||||
- add example ACS712_20_DC_external_ADC.ino
|
- add example ACS712_20_DC_external_ADC.ino
|
||||||
|
|
||||||
|
|
||||||
## [0.3.3] - 2023-01-03
|
## [0.3.3] - 2023-01-03
|
||||||
- update GitHub actions
|
- update GitHub actions
|
||||||
- update license
|
- update license
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/RobTillaart/ACS712.git"
|
"url": "https://github.com/RobTillaart/ACS712.git"
|
||||||
},
|
},
|
||||||
"version": "0.3.4",
|
"version": "0.3.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "*",
|
"platforms": "*",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=ACS712
|
name=ACS712
|
||||||
version=0.3.4
|
version=0.3.5
|
||||||
author=Rob Tillaart <rob.tillaart@gmail.com>, Pete Thompson <pete.thompson@yahoo.com>
|
author=Rob Tillaart <rob.tillaart@gmail.com>, Pete Thompson <pete.thompson@yahoo.com>
|
||||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||||
sentence=ACS712 library for Arduino.
|
sentence=ACS712 library for Arduino.
|
||||||
|
@ -21,17 +21,17 @@ There are 4 core functions:
|
|||||||
- **float mA_peak2peak(frequency = 50, cycles = 1)**
|
- **float mA_peak2peak(frequency = 50, cycles = 1)**
|
||||||
- **float mA_DC(cycles = 1)**
|
- **float mA_DC(cycles = 1)**
|
||||||
- **float mA_AC(frequency = 50, cycles = 1)**
|
- **float mA_AC(frequency = 50, cycles = 1)**
|
||||||
- **float mA_AC_sampling(frequency = 50, cycles = 1)**
|
- **float mA_AC_sampling(frequency = 50, cycles = 1)**
|
||||||
|
|
||||||
The parameter cycles is used to do measure multiple cycles and average them.
|
The parameter cycles is used to do measure multiple cycles and average them.
|
||||||
|
|
||||||
To measure DC current a single **analogRead()** with conversion math is
|
To measure DC current a single **analogRead()** with conversion math is
|
||||||
sufficient to get a value.
|
sufficient to get a value.
|
||||||
To stabilize the signal **analogRead()** is called at least twice.
|
To stabilize the signal **analogRead()** is called at least twice.
|
||||||
|
|
||||||
To measure AC current **a blocking loop for 20 milliseconds** (50 Hz, 1 cycle)
|
To measure AC current **a blocking loop for 20 milliseconds** (50 Hz, 1 cycle)
|
||||||
is run to determine the peak to peak value which is converted to the RMS value.
|
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.
|
To convert the peak2peak value to RMS one need the so called crest or form factor.
|
||||||
This factor depends heavily on the signal form, hence its name.
|
This factor depends heavily on the signal form, hence its name.
|
||||||
For a perfect sinus the value is sqrt(2)/2 == 1/sqrt(2).
|
For a perfect sinus the value is sqrt(2)/2 == 1/sqrt(2).
|
||||||
See **Form factor** below.
|
See **Form factor** below.
|
||||||
@ -40,7 +40,7 @@ The **mA_AC_sampling()** calculates the average of the sumSquared of many measur
|
|||||||
It should be used when the form factor is not known.
|
It should be used when the form factor is not known.
|
||||||
|
|
||||||
Note to make precise measurements, the power supply of both the ACS712 and the ADC of
|
Note to make precise measurements, the power supply of both the ACS712 and the ADC of
|
||||||
the processor should be as stable as possible.
|
the processor should be as stable as possible.
|
||||||
That improves the stability of the midpoint and minimizes the noise.
|
That improves the stability of the midpoint and minimizes the noise.
|
||||||
|
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ mA LSB = (5000 mV / maxADC) / mVperA * 1000.0;
|
|||||||
mA LSB = (1000 * 5000 mV) / (maxADC * mVperA);
|
mA LSB = (1000 * 5000 mV) / (maxADC * mVperA);
|
||||||
```
|
```
|
||||||
|
|
||||||
Although no 16 bit ADC built in are known, it indicates what resolution
|
Although no 16 bit ADC built in are known, it indicates what resolution
|
||||||
could be obtained with such an ADC. It triggered the thought for supporting
|
could be obtained with such an ADC. It triggered the thought for supporting
|
||||||
external ADC's with this library or a derived version. See future.
|
external ADC's with this library or a derived version. See future.
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ The library is at least confirmed to work with the following boards:
|
|||||||
| Arduino UNO | 5.0V | 1024 | tested with Open-Smart ACS712 5 A breakout.
|
| Arduino UNO | 5.0V | 1024 | tested with Open-Smart ACS712 5 A breakout.
|
||||||
| Arduino NANO | 5.0V | 1024 | #18
|
| Arduino NANO | 5.0V | 1024 | #18
|
||||||
| ESP32 | 3.3V | 4096 | #15
|
| ESP32 | 3.3V | 4096 | #15
|
||||||
| Promicro | 5.0V | 1024 | #15
|
| Promicro | 5.0V | 1024 | #15
|
||||||
|
|
||||||
Please let me know of other working platforms / processors.
|
Please let me know of other working platforms / processors.
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ Robodyn has a breakout for the ACS758 - 50 A. - See resolution below.
|
|||||||
This sensor has versions up to 200 Amps, so use with care!
|
This sensor has versions up to 200 Amps, so use with care!
|
||||||
|
|
||||||
Allegromicro offers a lot of different current sensors, that might be compatible.
|
Allegromicro offers a lot of different current sensors, that might be compatible.
|
||||||
These include bidirectional and unidirectional.
|
These include bidirectional and unidirectional.
|
||||||
The unidirectional seem to be for DC only.
|
The unidirectional seem to be for DC only.
|
||||||
|
|
||||||
https://www.allegromicro.com/en/products/sense/current-sensor-ics/current-sensors-innovations
|
https://www.allegromicro.com/en/products/sense/current-sensor-ics/current-sensors-innovations
|
||||||
@ -114,16 +114,16 @@ Not tested, but looks compatible - same formula as above
|
|||||||
|
|
||||||
#### Base
|
#### Base
|
||||||
|
|
||||||
- **ACS712(uint8_t analogPin, float volts = 5.0, uint16_t maxADC = 1023, float mVperAmpere = 100)** constructor.
|
- **ACS712(uint8_t analogPin, float volts = 5.0, uint16_t maxADC = 1023, float mVperAmpere = 100)** constructor.
|
||||||
It defaults a 20 A type sensor, which is defined by the default value of mVperAmpere. See table below.
|
It defaults a 20 A type sensor, which is defined by the default value of mVperAmpere. See table below.
|
||||||
Volts is the voltage used by the (Arduino) internal ADC. maxADC is the maximum output of the internal ADC.
|
Volts is the voltage used by the (Arduino) internal ADC. maxADC is the maximum output of the internal ADC.
|
||||||
The defaults are based upon an Arduino UNO, 10 bits ADC.
|
The defaults are based upon an Arduino UNO, 10 bits ADC.
|
||||||
These two ADC parameters are needed to calculate the voltage output of the ACS712 sensor.
|
These two ADC parameters are needed to calculate the voltage output of the ACS712 sensor.
|
||||||
- **float mA_peak2peak(float frequency = 50, uint16_t cycles = 1)** blocks ~21 ms to sample a whole 50 or 60 Hz period.
|
- **float mA_peak2peak(float frequency = 50, uint16_t cycles = 1)** blocks ~21 ms to sample a whole 50 or 60 Hz period.
|
||||||
Returns the peak to peak current, can be used to determine form factor.
|
Returns the peak to peak current, can be used to determine form factor.
|
||||||
The **mA_peak2peak()** can also be used to measure on a zero current line
|
The **mA_peak2peak()** can also be used to measure on a zero current line
|
||||||
to get an indication of the lowest detectable current.
|
to get an indication of the lowest detectable current.
|
||||||
Finally this function is used internally to detect the noiseLevel in mV on a zero current line.
|
Finally this function is used internally to detect the noiseLevel in mV on a zero current line.
|
||||||
- **float mA_AC(float frequency = 50, uint16_t cycles = 1)** blocks ~21 ms to sample a whole 50 or 60 Hz period.
|
- **float mA_AC(float frequency = 50, uint16_t cycles = 1)** blocks ~21 ms to sample a whole 50 or 60 Hz period.
|
||||||
Note that a lower frequency, or more cycles, will increase the blocking period.
|
Note that a lower frequency, or more cycles, will increase the blocking period.
|
||||||
The function returns the AC current in mA.
|
The function returns the AC current in mA.
|
||||||
@ -144,19 +144,19 @@ A negative value indicates the current flows in the opposite direction.
|
|||||||
#### Midpoint
|
#### Midpoint
|
||||||
|
|
||||||
The midpoint is the (raw) zero-reference for all current measurements.
|
The midpoint is the (raw) zero-reference for all current measurements.
|
||||||
It is defined in steps of the ADC and is typical around half the **maxADC** value defined
|
It is defined in steps of the ADC and is typical around half the **maxADC** value defined
|
||||||
in the constructor. So for a 10 bit ADC a number between 500..525 is most likely.
|
in the constructor. So for a 10 bit ADC a number between 500..525 is most likely.
|
||||||
|
|
||||||
Since 0.3.0 all midpoint functions return the actual midPoint.
|
Since 0.3.0 all midpoint functions return the actual midPoint.
|
||||||
|
|
||||||
- **uint16_t setMidPoint(uint16_t midPoint)** sets midpoint for the ADC conversion.
|
- **uint16_t setMidPoint(uint16_t midPoint)** sets midpoint for the ADC conversion.
|
||||||
Parameter must be between 0 and maxADC/2, otherwise midpoint is not changed.
|
Parameter must be between 0 and maxADC/2, otherwise midpoint is not changed.
|
||||||
- **uint16_t autoMidPoint(float frequency = 50, uint16_t cycles = 1)** Auto midPoint,
|
- **uint16_t autoMidPoint(float frequency = 50, uint16_t cycles = 1)** Auto midPoint,
|
||||||
assuming zero DC current or any AC current.
|
assuming zero DC current or any AC current.
|
||||||
The function takes the average of many measurements during one or more full cycles.
|
The function takes the average of many measurements during one or more full cycles.
|
||||||
Note the function therefore blocks for at least 2 periods.
|
Note the function therefore blocks for at least 2 periods.
|
||||||
By increasing the number of cycles the function averages even more measurements,
|
By increasing the number of cycles the function averages even more measurements,
|
||||||
possibly resulting in a better midPoint. Idea is that noise will average out.
|
possibly resulting in a better midPoint. Idea is that noise will average out.
|
||||||
This function is mandatory for measuring AC.
|
This function is mandatory for measuring AC.
|
||||||
- 0.2.2 frequencies other than 50 and 60 are supported.
|
- 0.2.2 frequencies other than 50 and 60 are supported.
|
||||||
- 0.2.8 the parameter cycles allow to average over a number of cycles.
|
- 0.2.8 the parameter cycles allow to average over a number of cycles.
|
||||||
@ -168,7 +168,7 @@ Will not decrease if midpoint equals 0.
|
|||||||
- **uint16_t resetMidPoint()** resets the midpoint to the initial value of maxADC / 2 as in the constructor.
|
- **uint16_t resetMidPoint()** resets the midpoint to the initial value of maxADC / 2 as in the constructor.
|
||||||
|
|
||||||
Since version 0.3.0 there is another way to determine the midPoint.
|
Since version 0.3.0 there is another way to determine the midPoint.
|
||||||
One can use the two debug functions.
|
One can use the two debug functions.
|
||||||
(milliseconds > 20 to get at least a full cycle)
|
(milliseconds > 20 to get at least a full cycle)
|
||||||
- **uint16_t getMinimum(uint16_t milliSeconds = 20)**
|
- **uint16_t getMinimum(uint16_t milliSeconds = 20)**
|
||||||
- **uint16_t getMaximum(uint16_t milliSeconds = 20)**
|
- **uint16_t getMaximum(uint16_t milliSeconds = 20)**
|
||||||
@ -180,19 +180,19 @@ uint16_t midpoint = ACS.setMidPoint(ACS.getMinimum(20)/2 + ACS.getMaximum(20)/ 2
|
|||||||
```
|
```
|
||||||
See - ACS712_20_AC_midPoint_compare.ino
|
See - ACS712_20_AC_midPoint_compare.ino
|
||||||
|
|
||||||
The ACS712 has a midPoint level that is specified as 0.5 \* VCC.
|
The ACS712 has a midPoint level that is specified as 0.5 \* VCC.
|
||||||
So **autoMidPoint()** can help to detect voltage deviations for the ACS712.
|
So **autoMidPoint()** can help to detect voltage deviations for the ACS712.
|
||||||
The library does not support this yet.
|
The library does not support this yet.
|
||||||
|
|
||||||
|
|
||||||
#### Form factor
|
#### Form factor
|
||||||
|
|
||||||
The form factor is also known as the crest factor.
|
The form factor is also known as the crest factor.
|
||||||
It is only used for signals measured with **mA_AC()**.
|
It is only used for signals measured with **mA_AC()**.
|
||||||
|
|
||||||
- **void setFormFactor(float formFactor = ACS712_FF_SINUS)** manually sets the form factor.
|
- **void setFormFactor(float formFactor = ACS712_FF_SINUS)** manually sets the form factor.
|
||||||
Must typical be between 0.0 and 1.0, see constants below.
|
Must typical be between 0.0 and 1.0, see constants below.
|
||||||
- **float getFormFactor()** returns current form factor.
|
- **float getFormFactor()** returns current form factor.
|
||||||
|
|
||||||
The library has a number of predefined form factors:
|
The library has a number of predefined form factors:
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ The library has a number of predefined form factors:
|
|||||||
| ACS712_FF_SAWTOOTH | 1.0 / sqrt(3) | 0.577 | |
|
| ACS712_FF_SAWTOOTH | 1.0 / sqrt(3) | 0.577 | |
|
||||||
|
|
||||||
It is important to measure the current with a calibrated multimeter
|
It is important to measure the current with a calibrated multimeter
|
||||||
and determine / verify the form factor of the signal.
|
and determine / verify the form factor of the signal.
|
||||||
This can help to improve the quality of your measurements.
|
This can help to improve the quality of your measurements.
|
||||||
|
|
||||||
Please let me know if other crest factors need to be added.
|
Please let me know if other crest factors need to be added.
|
||||||
@ -222,15 +222,15 @@ See - ACS712_20_determine_form_factor.ino
|
|||||||
|
|
||||||
Default = 21 mV (datasheet)
|
Default = 21 mV (datasheet)
|
||||||
|
|
||||||
- **void setNoisemV(uint8_t noisemV = 21)** sets the noise level,
|
- **void setNoisemV(uint8_t noisemV = 21)** sets the noise level,
|
||||||
is used to determine zero level e.g. in the AC measurements with **mA_AC()**.
|
is used to determine zero level e.g. in the AC measurements with **mA_AC()**.
|
||||||
- **uint8_t getNoisemV()** returns the set value.
|
- **uint8_t getNoisemV()** returns the set value.
|
||||||
- **float mVNoiseLevel(float frequency, uint16_t cycles)** determines the mV of noise.
|
- **float mVNoiseLevel(float frequency, uint16_t cycles)** determines the mV of noise.
|
||||||
Measurement should be taken when there is no AC/DC current or a constant DC current.
|
Measurement should be taken when there is no AC/DC current or a constant DC current.
|
||||||
The level will give a (not quantified yet) indication of the accuracy of the measurements.
|
The level will give a (not quantified yet) indication of the accuracy of the measurements.
|
||||||
A first order indication can be made by comparing it to voltage / 2 of the constructor.
|
A first order indication can be made by comparing it to voltage / 2 of the constructor.
|
||||||
|
|
||||||
Noise on the signal can be reduced by using a low pass (RC) filter.
|
Noise on the signal can be reduced by using a low pass (RC) filter.
|
||||||
Version 0.3.1 includes experimental code to take two sample and average them.
|
Version 0.3.1 includes experimental code to take two sample and average them.
|
||||||
The idea is that ```((3 + 5)/2)^2 < (3^2 + 5^2)/2```
|
The idea is that ```((3 + 5)/2)^2 < (3^2 + 5^2)/2```
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ software noise detection and suppression is needed.
|
|||||||
|
|
||||||
#### mV per Ampere
|
#### mV per Ampere
|
||||||
|
|
||||||
Used for both for AC and DC measurements.
|
Used for both for AC and DC measurements.
|
||||||
Its value is defined in the constructor and depends on type sensor used.
|
Its value is defined in the constructor and depends on type sensor used.
|
||||||
These functions allow to adjust this setting run-time.
|
These functions allow to adjust this setting run-time.
|
||||||
|
|
||||||
@ -259,37 +259,71 @@ Experimental functionality for AC signal only!
|
|||||||
- **float detectFrequency(float minimalFrequency = 40)** Detect the frequency of the AC signal.
|
- **float detectFrequency(float minimalFrequency = 40)** Detect the frequency of the AC signal.
|
||||||
- **void setMicrosAdjust(float factor = 1.0)** adjusts the timing of micros in **detectFrequency()**.
|
- **void setMicrosAdjust(float factor = 1.0)** adjusts the timing of micros in **detectFrequency()**.
|
||||||
Values are typical around 1.0 ± 1%
|
Values are typical around 1.0 ± 1%
|
||||||
- **float getMicrosAdjust()** returns the set factor.
|
- **float getMicrosAdjust()** returns the set factor.
|
||||||
|
|
||||||
The minimum frequency of 40 Hz is used to sample for enough time to find the minimum and maximum
|
The minimum frequency of 40 Hz is used to sample for enough time to find the minimum and maximum
|
||||||
for 50 and 60 Hz signals.
|
for 50 and 60 Hz signals.
|
||||||
Thereafter the signal is sampled 10 cycles to minimize the variation of the frequency.
|
Thereafter the signal is sampled 10 cycles to minimize the variation of the frequency.
|
||||||
|
|
||||||
The **microsAdjust()** is to adjust the timing of **micros()**.
|
The **microsAdjust()** is to adjust the timing of **micros()**.
|
||||||
This function is only useful if one has a good reference source like a calibrated function generator
|
This function is only useful if one has a good reference source like a calibrated function generator
|
||||||
to find the factor to adjust.
|
to find the factor to adjust.
|
||||||
Testing with my UNO I got a factor 0.9986.
|
Testing with my UNO I got a factor 0.9986.
|
||||||
|
|
||||||
Current version is experimental and not performance optimized.
|
Current version is experimental and not performance optimized.
|
||||||
|
|
||||||
|
|
||||||
#### setADC (experimental 0.3.4)
|
#### setADC (experimental 0.3.4)
|
||||||
|
|
||||||
- **void setADC(uint16_t (\*)(uint8_t), float volts, uint16_t maxADC)** sets the ADC function and its parameters.
|
- **void setADC(uint16_t (\*)(uint8_t), float volts, uint16_t maxADC)** sets the ADC function and the parameters of the used ADC.
|
||||||
Defaults the internal **analogRead()** by this wrapper in ACS712.h:
|
The library uses the internal **analogRead()** as default.
|
||||||
|
Be sure to set the parameters of the ADC correctly.
|
||||||
|
|
||||||
|
The easiest way to implement an external ADC is to make a wrapper function as casting for
|
||||||
|
function pointer is a no go area.
|
||||||
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
static uint16_t _internalAnalog(uint8_t pin)
|
// set to external ADC - 5 volts 12 bits
|
||||||
|
ACS.setADC(myAnalogRead, 5.0, 4096);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
uint16_t myAnalogRead(uint8_t pin)
|
||||||
{
|
{
|
||||||
return analogRead(pin);
|
return MCP.read(pin); // assuming MCP is ADC object.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Be sure to set the parameters of the constructor correctly.
|
|
||||||
|
To reset to the internal ADC use **NULL** as function pointer.
|
||||||
|
Be sure to set the parameters of the ADC correctly.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// reset to internal ADC - 5 volts 10 bits
|
||||||
|
ACS.setADC(NULL, 5.0, 1023);
|
||||||
|
```
|
||||||
|
|
||||||
- example ACS712_20_DC_external_ADC.ino
|
- example ACS712_20_DC_external_ADC.ino
|
||||||
- https://github.com/RobTillaart/ACS712/issues/31
|
- https://github.com/RobTillaart/ACS712/issues/31
|
||||||
|
|
||||||
|
|
||||||
|
Note that the use of an external ADC should meet certain performance requirements,
|
||||||
|
especially for measuring **ma-AC()**.
|
||||||
|
To 'catch' the peaks well enough one needs at least 2 samples per millisecond
|
||||||
|
for a 60 Hz signal.
|
||||||
|
|
||||||
|
The 16 bit I2C **ADS1115** in continuous mode gives max 0.8 samples per millisecond.
|
||||||
|
This will work perfect for high resolution **mA-DC()** but is not fast enough for
|
||||||
|
doing **mA-AC()**.
|
||||||
|
|
||||||
|
The SPI based **MCP3202** ao can do up to 100 samples per millisecond at 12 bit.
|
||||||
|
These ADC's are perfect both **mA-DC()** and **mA-AC()**.
|
||||||
|
|
||||||
|
- https://github.com/RobTillaart/ADS1X15
|
||||||
|
- https://github.com/RobTillaart/MCP_ADC
|
||||||
|
|
||||||
|
|
||||||
## Voltage divider
|
## Voltage divider
|
||||||
|
|
||||||
As per issue #15 in which an ACS712 was connected via a voltage divider to the ADC of an ESP32.
|
As per issue #15 in which an ACS712 was connected via a voltage divider to the ADC of an ESP32.
|
||||||
@ -302,16 +336,16 @@ ACS712 ----[ R1 ]----o----[ R2 ]---- GND
|
|||||||
ADC of processor
|
ADC of processor
|
||||||
```
|
```
|
||||||
|
|
||||||
The voltage divider gave an error of about a factor 2 as all voltages were divided,
|
The voltage divider gave an error of about a factor 2 as all voltages were divided,
|
||||||
including the "offset" from the **midPoint** zero current level.
|
including the "offset" from the **midPoint** zero current level.
|
||||||
|
|
||||||
By adjusting the mV per Ampere with **setmVperAmp(float mva)** the readings can be corrected
|
By adjusting the mV per Ampere with **setmVperAmp(float mva)** the readings can be corrected
|
||||||
for this "voltage divider effect".
|
for this "voltage divider effect".
|
||||||
|
|
||||||
|
|
||||||
#### Examples:
|
#### Examples:
|
||||||
|
|
||||||
For a 20 A type sensor, 100 mV/A would be the normal value.
|
For a 20 A type sensor, 100 mV/A would be the normal value.
|
||||||
After using a voltage divider one need to adjust the mVperAmp.
|
After using a voltage divider one need to adjust the mVperAmp.
|
||||||
|
|
||||||
| R1 (ACS) | R2 (GND) | voltage factor | mVperAmp corrected |
|
| R1 (ACS) | R2 (GND) | voltage factor | mVperAmp corrected |
|
||||||
@ -328,11 +362,12 @@ After using a voltage divider one need to adjust the mVperAmp.
|
|||||||
|
|
||||||
(to be tested)
|
(to be tested)
|
||||||
|
|
||||||
To detect that the ACS712 is disconnected from the ADC one could connect the
|
To detect that the ACS712 is disconnected from the ADC one could connect the
|
||||||
analog pin via a pull-down to GND. A pull-up to VCC is also possible.
|
analog pin via a pull-down to GND. A pull-up to VCC is also possible.
|
||||||
Choose the solution that fits your project best. (Think safety).
|
Choose the solution that fits your project best. (Think safety).
|
||||||
|
|
||||||
**mA_DC()** and **mA_AC_sampling()** will report HIGH values (Out of range) when the ACS712 is disconnected.
|
**mA_DC()** and **mA_AC_sampling()** will report HIGH values (Out of range) when
|
||||||
|
the ACS712 is disconnected.
|
||||||
The other - peak2peak based functions - will see this as zero current (min == max).
|
The other - peak2peak based functions - will see this as zero current (min == max).
|
||||||
|
|
||||||
Schema with PULL-UP.
|
Schema with PULL-UP.
|
||||||
@ -362,35 +397,26 @@ The examples show the basic working of the functions.
|
|||||||
#### Should - 0.3.x
|
#### Should - 0.3.x
|
||||||
|
|
||||||
- investigate noise suppression #21 (0.3.1 and later)
|
- investigate noise suppression #21 (0.3.1 and later)
|
||||||
|
- investigate blocking calls:
|
||||||
|
- **mA_AC()** blocks for about 20 ms at 50 Hz.
|
||||||
|
This might affect task scheduling on a ESP32. Needs to be investigated.
|
||||||
|
Probably need a separate thread that wakes up when new analogRead is available?
|
||||||
|
- RTOS specific class?
|
||||||
|
- **detectFrequency(float)** blocks pretty long.
|
||||||
|
|
||||||
|
|
||||||
#### Could
|
#### Could
|
||||||
|
|
||||||
- merge **mA_AC()** and **mA_AC_sampling()** into one. (0.4.0)
|
- merge **mA_AC()** and **mA_AC_sampling()** into one. (0.4.0)
|
||||||
- or remove - depreciate - the worst one
|
- or remove - depreciate - the worst one
|
||||||
- investigate blocking calls:
|
- add range check to (all) set functions?
|
||||||
- **mA_AC()** blocks for about 20 ms at 50 Hz.
|
|
||||||
This might affect task scheduling on a ESP32. Needs to be investigated.
|
|
||||||
Probably need a separate thread that wakes up when new analogRead is available?
|
|
||||||
- RTOS specific class?
|
|
||||||
- **detectFrequency(float)** blocks pretty long.
|
|
||||||
- other set functions also a range check?
|
|
||||||
- split the readme.md in multiple documents?
|
|
||||||
- which?
|
|
||||||
|
|
||||||
|
|
||||||
#### Won't
|
#### Won't (unless requested)
|
||||||
|
|
||||||
- external analogue read support? separate class!
|
|
||||||
- after this one stabilized.
|
|
||||||
- ACS712X class with external ADC ( 16 or even 24 bit)
|
|
||||||
- keep interface alike?
|
|
||||||
- are these fast enough for e.g. 60 Hz (100 samples in 16 millis?)
|
|
||||||
- **ADS1115** in continuous mode ==> 0.8 samples per millisecond at 16 bit Ideal for **mA-DC()**
|
|
||||||
- **MCP3202** SPI interface ==> up to 100 samples per millisecond !! at 12 bit. Perfect.
|
|
||||||
- investigate support for micro-Amperes. **ACS.uA_DC()**
|
- investigate support for micro-Amperes. **ACS.uA_DC()**
|
||||||
- need a very stable voltage
|
- need a very stable voltage
|
||||||
- needs a 24 bit ADC
|
- needs a 24 bit ADC
|
||||||
- default noise is already ~21mV...
|
- default noise is already ~21mV...
|
||||||
- => not feasible in normal setup.
|
- => not feasible in normal setup.
|
||||||
- Should the FormFactor not be just a parameter of **mA_AC()**
|
- Should the FormFactor not be just a parameter of **mA_AC()**
|
||||||
@ -400,4 +426,8 @@ The examples show the basic working of the functions.
|
|||||||
- midPoint can be a float so it can be set more exact.
|
- midPoint can be a float so it can be set more exact.
|
||||||
- extra precision is max half bit = smaller than noise?
|
- extra precision is max half bit = smaller than noise?
|
||||||
- math will be slower during sampling (UNO)
|
- math will be slower during sampling (UNO)
|
||||||
|
- split the readme.md in multiple documents?
|
||||||
|
- which?
|
||||||
|
- setADC() to support > 16 bit?
|
||||||
|
- uint32_t performance penalty?
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user