Skip to content

Commit

Permalink
update examples (#39)
Browse files Browse the repository at this point in the history
- add example **estimateMidPointAC.ino** #37
- update readme.md (sampling trick #38).
- minor edits.
  • Loading branch information
RobTillaart authored May 20, 2023
1 parent d7beb2d commit c56d3ce
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 20 deletions.
20 changes: 10 additions & 10 deletions ACS712.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: ACS712.cpp
// AUTHOR: Rob Tillaart, Pete Thompson
// VERSION: 0.3.6
// VERSION: 0.3.7
// DATE: 2020-08-02
// PURPOSE: ACS712 library - current measurement
// URL: https://github.com/RobTillaart/ACS712
Expand Down Expand Up @@ -133,7 +133,7 @@ float ACS712::mA_AC_sampling(float frequency, uint16_t cycles)
if (cycles == 0) cycles = 1;
float sum = 0;

// float noiseLevel = _noisemV/_mVperStep;
// float noiseLevel = _noisemV/_mVperStep;

for (uint16_t i = 0; i < cycles; i++)
{
Expand All @@ -151,11 +151,11 @@ float ACS712::mA_AC_sampling(float frequency, uint16_t cycles)
}
float current = value - _midPoint;
sumSquared += (current * current);
// not adding noise squared might be more correct for small currents.
// if (abs(current) > noiseLevel)
// {
// sumSquared += (current * current);
// }
// not adding noise squared might be more correct for small currents.
// if (abs(current) > noiseLevel)
// {
// sumSquared += (current * current);
// }
}
sum += sqrt(sumSquared / samples);
}
Expand Down Expand Up @@ -416,7 +416,7 @@ uint16_t ACS712::getMaximum(uint16_t milliSeconds)
{
uint16_t maximum = _analogRead(_pin);

// find minimum
// find maximum
uint32_t start = millis();
while (millis() - start < milliSeconds)
{
Expand Down Expand Up @@ -444,11 +444,11 @@ void ACS712::setADC(uint16_t (* f)(uint8_t), float volts, uint16_t maxADC)
//
uint16_t ACS712::_analogRead(uint8_t pin)
{
// if extern ADC is defined use it.
// if external ADC is defined use it.
if (_readADC != NULL) return _readADC(pin);
return analogRead(pin);
}


// -- END OF FILE --
// -- END OF FILE --

6 changes: 3 additions & 3 deletions ACS712.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: ACS712.h
// AUTHOR: Rob Tillaart, Pete Thompson
// VERSION: 0.3.6
// VERSION: 0.3.7
// DATE: 2020-08-02
// PURPOSE: ACS712 library - current measurement
// URL: https://github.com/RobTillaart/ACS712
Expand All @@ -13,7 +13,7 @@

#include "Arduino.h"

#define ACS712_LIB_VERSION (F("0.3.6"))
#define ACS712_LIB_VERSION (F("0.3.7"))


// ACS712_FF_SINUS == 1.0/sqrt(2) == 0.5 * sqrt(2)
Expand Down Expand Up @@ -133,5 +133,5 @@ class ACS712
};


// -- END OF FILE --
// -- END OF FILE --

7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.3.7] - 2023-05-20
- add example **estimateMidPointAC.ino** #37
- update readme.md (sampling trick #38).
- minor edits.


## [0.3.6] - 2023-04-19
- add **autoMidPointDC(cycles)** see issue #35
- add rounding to **autoMidPoint()**
- update README.md


## [0.3.5] - 2023-01-18
- fix #33 failing build => issue 345 created @ arduino-ci
- redo **setADC()**
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ Not tested, but looks compatible - same formula as above

## Interface

```cpp
#include ACS712.h
```


#### Base

- **ACS712(uint8_t analogPin, float volts = 5.0, uint16_t maxADC = 1023, float mVperAmpere = 100)** constructor.
Expand Down Expand Up @@ -141,6 +146,23 @@ A negative value indicates the current flows in the opposite direction.
- 0.2.8 the parameter samples allow to average over a number of samples.


#### 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.
Advantage is that the function only blocks for ~10 ms @ 50Hz (8.5 @ 60Hz).
The drawback is about 4x as many variation.
So only use if the performance (or less blocking) is needed.

In a similar way one can increase the accuracy (reducing the variation)
by setting the frequency a factor 2 lower (25 and 30 Hz).
Drawback is a far longer blocking time.

Use with care!

See - https://github.com/RobTillaart/ACS712/issues/38


#### Midpoint

The midpoint is the (raw) zero-reference for all current measurements.
Expand All @@ -153,7 +175,7 @@ Since 0.3.0 all midpoint functions return the actual midPoint.
Parameter must be between 0 and maxADC/2, otherwise midpoint is not changed.
- **uint16_t getMidPoint()** read the value set / determined.
- **uint16_t incMidPoint()** manual increase midpoint, e.g. useful in an interactive application.
Will not increase if midpoint equals macADC.
Will not increase if midpoint equals maxADC.
- **uint16_t decMidPoint()** manual decrease midpoint.
Will not decrease if midpoint equals 0.
- **uint16_t resetMidPoint()** resets the midpoint to the initial value of maxADC / 2 as in the constructor.
Expand Down
27 changes: 24 additions & 3 deletions examples/ACS712_20_AC/ACS712_20_AC.ino
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ ACS712 ACS(A0, 5.0, 1023, 100);
// ACS712 ACS(25, 3.3, 4095, 185);


uint32_t start, stop;


void setup()
{
Serial.begin(115200);
Expand All @@ -27,6 +30,10 @@ void setup()
Serial.print("ACS712_LIB_VERSION: ");
Serial.println(ACS712_LIB_VERSION);


// use simulation
ACS.setADC(signal, 5, 1024);

ACS.autoMidPoint();
Serial.print("MidPoint: ");
Serial.print(ACS.getMidPoint());
Expand All @@ -37,13 +44,27 @@ void setup()

void loop()
{
int mA = ACS.mA_AC();
delay(100);
start = micros();
// int mA = ACS.mA_AC();
int mA = ACS.mA_AC_sampling();
stop = micros();
Serial.print("mA: ");
Serial.print(mA);
Serial.print(". Form factor: ");
Serial.println(ACS.getFormFactor());
Serial.print(ACS.getFormFactor());
Serial.print(" time: ");
Serial.println(stop - start);
delay(5000);
}


// simulated 50 Hz signal
uint16_t signal(uint8_t p)
{
return 512 + 400 * sin((micros() % 1000000) * (TWO_PI * 50 / 1e6));
}


// -- END OF FILE --
// -- END OF FILE --

66 changes: 66 additions & 0 deletions examples/ACS712_20_AC_simulation/ACS712_20_AC_simulation.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// FILE: ACS712_20_AC_simulation.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo AC measurement with point to point
// 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, 5.0, 1023, 100);
// ESP 32 example (might requires resistors to step down the logic voltage)
// ACS712 ACS(25, 3.3, 4095, 185);


uint32_t start, stop;


void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.println(__FILE__);
Serial.print("ACS712_LIB_VERSION: ");
Serial.println(ACS712_LIB_VERSION);

// select simulated signal
ACS.setADC(signal, 5, 1024);

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


void loop()
{
delay(100);
start = micros();
// int mA = ACS.mA_AC();
int mA = ACS.mA_AC_sampling(50);
stop = micros();
Serial.print("mA: ");
Serial.print(mA);
Serial.print(" time: ");
Serial.println(stop - start);
delay(5000);
}


// simulation.
uint16_t signal(uint8_t p)
{
return round(512 + 400 * sin((micros() % 1000000) * (TWO_PI * 50 / 1e6)));
}


// -- END OF FILE --
89 changes: 89 additions & 0 deletions examples/estimateMidPointAC/estimateMidPointAC.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// FILE: estimateMidPointAC.ino
// AUTHOR: Rob Tillaart
// PURPOSE: experimental
// URL: https://github.com/RobTillaart/ACS712/issues/37
//
// Estimates the midpoint by taking many (short-blocking) samples
// instead of many samples in a long blocking period.
// The function adjusts the confidence (or quality) of the midpoint
// depending on the value read.
// This code is experimental and meant to investigate a non-blocking
// way to find the midPoint for the ACS712 when measuring AC currents.
//
// It will not be included in the library
//
// Use with care.


#include "Arduino.h"


uint32_t start, stop;
int _pin = A0;
uint32_t count = 0;
volatile uint16_t mp;
float conf = 0;


uint16_t estimateMidPointAC(float &confidence, bool reset = false)
{
static bool _firstCall = true;
static float _minimum, _maximum, _confidence;

int value = analogRead(_pin);
if (_firstCall || reset)
{
_firstCall = false;
_minimum = _maximum = value;
_confidence = 0;
confidence = _confidence;
return _minimum;
}
if (value > _maximum)
{
_maximum = value;
_confidence /= 2;
}
else if (value < _minimum)
{
_minimum = value;
_confidence /= 2;
}
else if (_confidence < 100)
{
_confidence += 1;
}
confidence = _confidence;
return (_minimum + _maximum) / 2;
}


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


void loop()
{
count++;
start = micros();
mp = estimateMidPointAC(conf, true);
stop = micros();
Serial.print(millis());
Serial.print("\t");
Serial.print(count);
Serial.print("\t");
Serial.print(conf);
Serial.print("\t");
Serial.print(mp);
Serial.print("\t");
Serial.print(stop - start);
Serial.println();
delay(random(100));
}


// -- END OF FILE --
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/ACS712.git"
},
"version": "0.3.6",
"version": "0.3.7",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ACS712
version=0.3.6
version=0.3.7
author=Rob Tillaart <[email protected]>, Pete Thompson <[email protected]>
maintainer=Rob Tillaart <[email protected]>
sentence=ACS712 library for Arduino.
Expand Down

0 comments on commit c56d3ce

Please sign in to comment.