diff --git a/ACS712.cpp b/ACS712.cpp index 1273a60..a887cab 100644 --- a/ACS712.cpp +++ b/ACS712.cpp @@ -1,7 +1,7 @@ // // FILE: ACS712.cpp // AUTHOR: Rob Tillaart, Pete Thompson -// VERSION: 0.3.9 +// VERSION: 0.3.10 // DATE: 2020-08-02 // PURPOSE: ACS712 library - current measurement // URL: https://github.com/RobTillaart/ACS712 @@ -18,10 +18,10 @@ ACS712::ACS712(uint8_t analogPin, float volts, uint16_t maxADC, float mVperAmper _formFactor = ACS712_FF_SINUS; _noisemV = ACS712_DEFAULT_NOISE; // 21mV according to datasheet - // set in setADC() + // set in setADC() // keep it here until after experimental. _maxADC = maxADC; - _mVperStep = 1000.0 * volts / maxADC; // 1x 1000 for V -> mV + _mVperStep = 1000.0 * volts / maxADC; // 1x 1000.0 for V -> mV _mAPerStep = 1000.0 * _mVperStep / _mVperAmpere; _midPoint = maxADC / 2; diff --git a/ACS712.h b/ACS712.h index 9cb824b..0e17725 100644 --- a/ACS712.h +++ b/ACS712.h @@ -2,7 +2,7 @@ // // FILE: ACS712.h // AUTHOR: Rob Tillaart, Pete Thompson -// VERSION: 0.3.9 +// VERSION: 0.3.10 // DATE: 2020-08-02 // PURPOSE: ACS712 library - current measurement // URL: https://github.com/RobTillaart/ACS712 @@ -14,18 +14,18 @@ #include "Arduino.h" -#define ACS712_LIB_VERSION (F("0.3.9")) +#define ACS712_LIB_VERSION (F("0.3.10")) // ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2) // should be smaller in practice 0.5 ? -#define ACS712_FF_SINUS (1.0/sqrt(2)) -#define ACS712_FF_SQUARE (1.0) -#define ACS712_FF_TRIANGLE (1.0/sqrt(3)) -#define ACS712_FF_SAWTOOTH (1.0/sqrt(3)) +#define ACS712_FF_SINUS (1.0/sqrt(2)) +#define ACS712_FF_SQUARE (1.0) +#define ACS712_FF_TRIANGLE (1.0/sqrt(3)) +#define ACS712_FF_SAWTOOTH (1.0/sqrt(3)) -#define ACS712_DEFAULT_FREQ 50 -#define ACS712_DEFAULT_NOISE 21 +#define ACS712_DEFAULT_FREQ 50 +#define ACS712_DEFAULT_NOISE 21 class ACS712 @@ -138,7 +138,7 @@ class ACS712 // supports up to 16 bits ADC. uint16_t (* _readADC)(uint8_t); uint16_t _analogRead(uint8_t pin); - + }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 43597ac..813069d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.3.10] - 2024-10-20 +- update readme.md, ESPHome #51, kudos to uTZFu +- add debug example. + ## [0.3.9] - 2024-01-11 - add yield() to improve the behaviour under RTOS - update readme.md (add compatibility table). - minor edits - ## [0.3.8] - 2023-09-19 - add badges to readme.md - minor edits diff --git a/README.md b/README.md index 03f1bf3..9ccca61 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ the processor should be as stable as possible. That improves the stability of the midpoint and minimizes the noise. -#### Resolution +### Resolution | Sensor | mVperA | LSB 10bit | LSB 12bit | LSB 16bit | |:---------|:--------:|:-----------:|:-----------:|:-----------:| @@ -71,7 +71,7 @@ could be obtained with such an ADC. It triggered the experimental supporting of external ADC's with this library. -#### Calibration and accuracy +### Calibration and accuracy The library has no means to calibrate the output or use an offset. However sort of calibrating can relatively easy be done by using @@ -81,7 +81,7 @@ MultiMap approaches a non-linear mapping by multiple linear mappings. See https://github.com/RobTillaart/MultiMap. -#### Tests +### Tests The library is at least confirmed to work with the following boards: @@ -124,7 +124,7 @@ If you have tested a compatible sensor, please share your experiences. (can be done by opening an issue to update documentation) -#### Resolution ACS758 +### Resolution ACS758 Not tested, but looks compatible - same formula as above @@ -147,7 +147,7 @@ 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. It defaults a 20 A type sensor, which is defined by the default value of mVperAmpere. See table below. @@ -177,7 +177,7 @@ A negative value indicates the current flows in the opposite direction. - 0.3.9 calls yield() every 2nd iteration to improve behaviour under RTOS. -#### mA_AC_sampling performance trick. +### mA_AC_sampling performance trick. A trick to sample faster is to set the frequency to 2 times the actual frequency so to 100 or 120 Hz. This results in sampling only half a period and the same current will be measured. @@ -194,7 +194,7 @@ Use with care! See - https://github.com/RobTillaart/ACS712/issues/38 -#### Midpoint +### Midpoint 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 @@ -244,7 +244,7 @@ So **autoMidPoint()** can help to detect voltage deviations for the ACS712. The library does not support this yet. -#### Form factor +### Form factor The form factor is also known as the **crest factor**. It is only used for signals measured with **mA_AC()**. @@ -277,7 +277,7 @@ float formFactor = 2.0 * mA_AC_sampling() / ACS.mA_peak2peak(); See - ACS712_20_determine_form_factor.ino -#### Noise +### Noise Default = 21 mV (datasheet) @@ -299,7 +299,7 @@ software noise detection and suppression is needed. - **void suppressNoise(bool flag)** experimental noise suppression. -#### mV per Ampere +### mV per Ampere Used for both for AC and DC measurements. Its value is defined in the constructor and depends on type sensor used. @@ -311,7 +311,7 @@ These functions allow to adjust this setting run-time. Typical values see "Resolution" section above, and the "voltage divider" section below. -#### Frequency detection +### Frequency detection Experimental functionality for AC signal only! @@ -332,7 +332,7 @@ Testing with my UNO I got a factor 0.9986. 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 the parameters of the used ADC. The library uses the internal **analogRead()** as default. @@ -395,6 +395,7 @@ These ADC's are perfect both **mA-DC()** and **mA-AC()**. ## Voltage divider As per issue #15 in which an ACS712 was connected via a voltage divider to the ADC of an ESP32. +Idem issue #43 with an ACS712 (5A) to a bare ESP8266 (1V ADC!). Schema ``` @@ -411,18 +412,44 @@ By adjusting the mV per Ampere with **setmVperAmp(float mva)** the readings can for this "voltage divider effect". -#### Examples: +### Examples: + + +For a 5 A type sensor, 185 mV/A would be the normal value. +After using a voltage divider one need to adjust the mVperAmp. + +| R1 (ACS) | R2 (GND) | voltage factor | mVperAmp corrected | notes | +|---------:|----------:|--------------------------------:|:-----------------------:|:--------| +| 10200 | 4745 | 4745 / (10200 + 4745) = 0.3175 | 185 \* 0.3175 = 31.75 | +| 4745 | 10200 | 10200 / (10200 + 4745) = 0.6825 | 185 \* 0.6825 = 68.25 | +| 10200 | 9800 | 9800 / (10200 + 9800) = 0.4900 | 185 \* 0.4900 = 49.00 | +| 1000 | 2200 | 2200 / (1000 + 2200) = 0.6875 | 185 \* 0.6875 = 127.19 | 5V -> 3V3 ADC +| 300 | 75 | 75 / (300 + 75) = 0.2000 | 185 \* 0.2000 = 37.00 | 5V -> 1V ADC + 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. -| R1 (ACS) | R2 (GND) | voltage factor | mVperAmp corrected | -|:--------:|:---------:|:-------------------------------:|:-----------------------:| -| 10200 | 4745 | 4745 / (10200 + 4745) = 0.3175 | 100 \* 0.3175 = 31.75 | -| 4745 | 10200 | 10200 / (10200 + 4745) = 0.6825 | 100 \* 0.6825 = 68.25 | -| 10200 | 9800 | 9800 / (10200 + 9800) = 0.4900 | 100 \* 0.4900 = 49.00 | +| R1 (ACS) | R2 (GND) | voltage factor | mVperAmp corrected | notes | +|---------:|----------:|--------------------------------:|:-----------------------:|:--------| +| 10200 | 4745 | 4745 / (10200 + 4745) = 0.3175 | 100 \* 0.3175 = 31.75 | +| 4745 | 10200 | 10200 / (10200 + 4745) = 0.6825 | 100 \* 0.6825 = 68.25 | +| 10200 | 9800 | 9800 / (10200 + 9800) = 0.4900 | 100 \* 0.4900 = 49.00 | +| 1000 | 2200 | 2200 / (1000 + 2200) = 0.6875 | 100 \* 0.6875 = 68.75 | 5V -> 3V3 ADC +| 300 | 75 | 75 / (300 + 75) = 0.2000 | 100 \* 0.2000 = 20.00 | 5V -> 1V ADC +For a 30 A type sensor, 66 mV/A would be the normal value. +After using a voltage divider one need to adjust the mVperAmp. + +| R1 (ACS) | R2 (GND) | voltage factor | mVperAmp corrected | notes | +|---------:|----------:|--------------------------------:|:-----------------------:|:--------| +| 10200 | 4745 | 4745 / (10200 + 4745) = 0.3175 | 66 \* 0.3175 = 31.75 | +| 4745 | 10200 | 10200 / (10200 + 4745) = 0.6825 | 66 \* 0.6825 = 68.25 | +| 10200 | 9800 | 9800 / (10200 + 9800) = 0.4900 | 66 \* 0.4900 = 49.00 | +| 1000 | 2200 | 2200 / (1000 + 2200) = 0.6875 | 66 \* 0.6875 = 45.38 | 5V -> 3V3 ADC +| 300 | 75 | 75 / (300 + 75) = 0.2000 | 66 \* 0.2000 = 13.20 | 5V -> 1V ADC + **Note:** setting the midPoint correctly is also needed when using a voltage divider. @@ -472,11 +499,14 @@ There is no RTOS example. If you have and willing to share you are welcome. For people who want to use this library for ESPhome, there exists a wrapper class for this ACS712 library. + - https://github.com/marianomd/acs712-esphome As I do not have ESPhome know how, please share your experiences. This can be done by an issue. +- https://github.com/RobTillaart/ACS712/issues/51 + ## Operation diff --git a/examples/ACS712_debug/ACS712_debug.ino b/examples/ACS712_debug/ACS712_debug.ino new file mode 100644 index 0000000..73235b9 --- /dev/null +++ b/examples/ACS712_debug/ACS712_debug.ino @@ -0,0 +1,69 @@ +// +// FILE: ACS712_debug.ino +// AUTHOR: Rob Tillaart +// PURPOSE: analyse effects of settings e.g. voltage divider +// URL: https://github.com/RobTillaart/ACS712 + + +#include "ACS712.h" + + +// Arduino UNO has 5.0 volt with a max ADC value of 1023 steps +// ACS712 5A uses 185 mV per A +// ACS712 20A uses 100 mV per A +// ACS712 30A uses 66 mV per A + + +ACS712 ACS(A0, 3.3, 1023, 185); +ACS712 ACS2(A0, 1, 1023, 32); +ACS712 ACS3(A0, 3.3, 1023, 37); +ACS712 ACS4(A0, 1, 1023, 92.5); +// ESP 32 example (might requires resistors to step down the logic voltage) +// ACS712 ACS(25, 3.3, 4095, 185); + + +float voltageDividerFactor(float R_ACS, float R_GND) +{ + return R_GND / (R_ACS + R_GND); +} + + +void dumpACS(ACS712 acs) +{ + Serial.print("MIDPOINT: "); + Serial.println(acs.getMidPoint()); + Serial.print("NOISE mV: "); + Serial.println(acs.getNoisemV()); + Serial.print("mV / AMP: "); + Serial.println(acs.getmVperAmp()); + Serial.print("mA/step : "); + Serial.println(acs.getmAPerStep()); + Serial.println(); +} + + +void setup() +{ + Serial.begin(115200); + while (!Serial); + Serial.println(__FILE__); + Serial.print("ACS712_LIB_VERSION: "); + Serial.println(ACS712_LIB_VERSION); + + dumpACS(ACS); + dumpACS(ACS2); + dumpACS(ACS3); + dumpACS(ACS4); + + // just examples + Serial.println(voltageDividerFactor(300, 75), 4); + Serial.println(voltageDividerFactor(315, 70), 4); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/library.json b/library.json index 6380823..97ec257 100644 --- a/library.json +++ b/library.json @@ -21,7 +21,7 @@ "type": "git", "url": "https://github.com/RobTillaart/ACS712.git" }, - "version": "0.3.9", + "version": "0.3.10", "license": "MIT", "frameworks": "*", "platforms": "*", diff --git a/library.properties b/library.properties index aebbd43..c9b1159 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ACS712 -version=0.3.9 +version=0.3.10 author=Rob Tillaart , Pete Thompson maintainer=Rob Tillaart sentence=ACS712 library for Arduino.