From 9d338f04e6cd99115643ac0f7f21c7e66ee917de Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Wed, 20 Sep 2023 19:16:07 +0200 Subject: [PATCH] 0.2.1 A1301 --- libraries/A1301/A1301.cpp | 61 +++++++++++++++---- libraries/A1301/A1301.h | 16 +++-- libraries/A1301/CHANGELOG.md | 10 +++ libraries/A1301/README.md | 56 +++++++++++------ .../A1301_determineNoise.ino | 40 ++++++++++++ .../A1301/examples/A1301_test/A1301_test.ino | 6 ++ libraries/A1301/keywords.txt | 6 ++ libraries/A1301/library.json | 4 +- libraries/A1301/library.properties | 2 +- 9 files changed, 165 insertions(+), 36 deletions(-) create mode 100644 libraries/A1301/examples/A1301_determineNoise/A1301_determineNoise.ino diff --git a/libraries/A1301/A1301.cpp b/libraries/A1301/A1301.cpp index ee4e50ae..592cc0df 100644 --- a/libraries/A1301/A1301.cpp +++ b/libraries/A1301/A1301.cpp @@ -1,7 +1,7 @@ // // FILE: A1301.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.2.0 +// VERSION: 0.2.1 // DATE: 2010-07-22 // PURPOSE: Arduino library for A1301 A1302 magnetometer. // URL: https://github.com/RobTillaart/A1301 @@ -22,7 +22,7 @@ HALL::HALL(uint8_t pin) _midPoint = _maxADC * 0.5; // default middle _prevGauss = 0; _lastGauss = 0; - _mVGauss = 2.5; + _GaussmV = 1.0 / 2.5; _maxGauss = 500.0; } @@ -57,13 +57,13 @@ float HALL::getMidPoint() // void HALL::setSensitivity(float sensitivity) { - _mVGauss = sensitivity; + _GaussmV = 1.0 / sensitivity; } float HALL::getSensitivity() { - return _mVGauss; + return 1.0 / _GaussmV; } @@ -89,16 +89,31 @@ float HALL::read(uint8_t times) { float milliVolts = (raw(times) - _midPoint) * _mVStep; _prevGauss = _lastGauss; - _lastGauss = milliVolts / _mVGauss; + _lastGauss = milliVolts * _GaussmV; return _lastGauss; } +float HALL::determineNoise(uint8_t times) +{ + uint16_t ma = 0; + uint16_t mi = 65535; + if (times < 2) times = 2; + for (uint8_t i = 0; i < times; i++) + { + uint16_t r = analogRead(_pin); + if (r < mi) mi = r; + if (r > ma) ma = r; + } + return (ma - mi) * _mVStep * _GaussmV; +} + + float HALL::readExt(float raw) { float milliVolts = (raw - _midPoint) * _mVStep; _prevGauss = _lastGauss; - _lastGauss = milliVolts / _mVGauss; + _lastGauss = milliVolts * _GaussmV; return _lastGauss; } @@ -125,6 +140,18 @@ bool HALL::isSouth() } +bool HALL::isRising() +{ + return _lastGauss > _prevGauss; +} + + +bool HALL::isFalling() +{ + return _lastGauss < _prevGauss; +} + + float HALL::lastGauss() { return _lastGauss; @@ -137,6 +164,18 @@ float HALL::prevGauss() } +float HALL::deltaGauss() +{ + return _lastGauss - _prevGauss; +} + + +float HALL::angle() +{ + return atan2(_prevGauss, _lastGauss); +} + + ///////////////////////////////////////////////////////////////////////////// // // CONVERTORS @@ -193,27 +232,27 @@ float HALL::saturationLevel() // A1301::A1301(uint8_t pin) : HALL(pin) { - _mVGauss = 2.5; + _GaussmV = 1.0 / 2.5; } A1302::A1302(uint8_t pin) : HALL(pin) { - _mVGauss = 1.3; + _GaussmV = 1.0 / 1.3; } A1324::A1324(uint8_t pin) : HALL(pin) { - _mVGauss = 5.0; + _GaussmV = 1.0 / 5.0; } A1325::A1325(uint8_t pin) : HALL(pin) { - _mVGauss = 3.125; + _GaussmV = 1.0 / 3.125; } A1326::A1326(uint8_t pin) : HALL(pin) { - _mVGauss = 2.5; + _GaussmV = 1.0 / 2.5; } diff --git a/libraries/A1301/A1301.h b/libraries/A1301/A1301.h index 60c3993e..befc06fa 100644 --- a/libraries/A1301/A1301.h +++ b/libraries/A1301/A1301.h @@ -2,7 +2,7 @@ // // FILE: A1301.h // AUTHOR: Rob Tillaart -// VERSION: 0.2.0 +// VERSION: 0.2.1 // DATE: 2010-07-22 // PURPOSE: Arduino library for A1301 A1302 magnetometer. // URL: https://github.com/RobTillaart/A1301 @@ -18,7 +18,7 @@ #include "Arduino.h" -#define A1301_LIB_VERSION (F("0.2.0")) +#define A1301_LIB_VERSION (F("0.2.1")) class HALL @@ -43,6 +43,7 @@ public: // uses internal ADC float raw(uint8_t times = 1); // returns raw ADC float read(uint8_t times = 1); // returns Gauss + // for external ADC float readExt(float raw); @@ -51,8 +52,15 @@ public: bool isNull(); bool isNorth(); bool isSouth(); + bool isRising(); + bool isFalling(); + float lastGauss(); float prevGauss(); + float deltaGauss(); + float angle(); // == atan2(prevGauss, lastGauss); + float determineNoise(uint8_t times = 2); // in Gauss + // CONVERTERs @@ -74,10 +82,10 @@ protected: float _midPoint; float _prevGauss; float _lastGauss; - float _mVGauss; + float _GaussmV; // == 1.0 / mVGauss float _mVStep; uint16_t _maxADC; - + // Experimental float _maxGauss; }; diff --git a/libraries/A1301/CHANGELOG.md b/libraries/A1301/CHANGELOG.md index 616c10f1..ac838948 100644 --- a/libraries/A1301/CHANGELOG.md +++ b/libraries/A1301/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.2.1] - 2023-09-19 +- add **bool isRising()** and **bool isFalling()** +- add **float deltaGauss()** +- add **float determineNoise(uint8_t times = 2)** +- add **angle()** experimental. +- add / update examples. +- replaced internal mVGauss by GaussmV to improve math performance. +- update readme.md + + ## [0.2.0] - 2023-04-24 - add **isNull()** is no magnetic field is detected. - add **saturationLevel()** returns 0..100% diff --git a/libraries/A1301/README.md b/libraries/A1301/README.md index c6ccbde2..24843b12 100644 --- a/libraries/A1301/README.md +++ b/libraries/A1301/README.md @@ -2,8 +2,11 @@ [![Arduino CI](https://github.com/RobTillaart/A1301/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) [![Arduino-lint](https://github.com/RobTillaart/A1301/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/A1301/actions/workflows/arduino-lint.yml) [![JSON check](https://github.com/RobTillaart/A1301/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/A1301/actions/workflows/jsoncheck.yml) +[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/A1301.svg)](https://github.com/RobTillaart/A1301/issues) + [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/A1301/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/RobTillaart/A1301.svg?maxAge=3600)](https://github.com/RobTillaart/A1301/releases) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/A1301.svg)](https://registry.platformio.org/libraries/robtillaart/A1301) # A1301 @@ -76,6 +79,7 @@ pin is the analogPin to read from. - **void begin(float voltage, uint16_t steps)** Sets the parameters voltage and number of steps of the internal ADC. Note this allows to update the voltage runtime. +Steps must be larger than zero. - **void setMidPoint(float midPoint)** the value of midPoint depends on the internal ADC. It is the value where there is no (zero) magnetic field. Note it does not need to be a whole value. @@ -83,7 +87,7 @@ This allows quite precise tuning. - **float getMidPoint()** returns the current midPoint. - **void setSensitivity(float sensitivity)** overrule default sensitivity. Use with care. -- **float getSensitivity()** return current sensitivity. +- **float getSensitivity()** return the set / current sensitivity. #### Read @@ -101,10 +105,23 @@ Can also be used for testing, e.g. replay of a series of data. #### Analyse -- **bool isNorth()** idem. -- **bool isSouth()** idem. +- **bool isNull()** last read is zero. +- **bool isNorth()** last read is above than zero. +- **bool isSouth()** last read is below zero. +- **bool isRising()** trend (last 2 reads) is upward. +- **bool isFalling()** trend (last 2 reads) is downward. - **float lastGauss()** returns last measurement in Gauss. - **float prevGauss()** returns previous measurement in Gauss. +- **float deltaGauss()** returns last - previous measurement. + +Experimental. + +- **float determineNoise(uint8_t times = 2)** estimates noise level +around measurements. **times** will be forced to be at least 2. +Does not affect lastGauss or prevGauss values. +- **float angle()** returns atan2(prevGauss, lastGauss). +Indicator of change. +Returns angle in radians. For degrees multiply by 180/PI. #### Saturation. @@ -115,7 +132,7 @@ Experimental saturation level. If maxGauss < 0 the absolute value is set. - **float getMaxGauss()** returns the set saturation level. - **bool isSaturated()** true when ADC (lastRead) seems to max out. -- **float saturationLevel()** returns value between 0..100%. +- **float saturationLevel()** returns value between 0..100%, or beyond! #### Tesla @@ -145,15 +162,14 @@ The examples show the basic working of the functions. - unit tests - test **isSaturated()** + **saturationLevel()** - limits might be sensor dependant. -- optimize math - - multiplications instead of divisions. - - other constants needed? +- investigate **atan2(prevGauss, lastGauss)** + - angle indicates relative delta compared to magnitude and direction. + - 45 & 315 degrees is no change. #### Could - **float findZero()** how exactly => ACS712 **autoMidPoint()** -- investigate **float determineNoise()** (set/get) - add examples. - performance read() - Possible compatible @@ -167,16 +183,6 @@ The examples show the basic working of the functions. (thinking out loud section) - isEast() and isWest() meaning? - - **isEast()** field strength is "rising" ==> lastGauss > prevGauss - - **isWest()** field strength is "sinking" ==> lastGauss < prevGauss - - should that be absolute or not? or just **bool isRising()** -- **float readDelta(uint8_t times = 1)** returns the relative change. -- atan2(prevGauss, lastGauss)? - - angle indicates relative delta compared to magnitude and direction. - - 45 135 degrees is no change. -- can the strength of the signal be converted to distance? - - for a given magnet - - repeatability + noise. - influence of angle of the field-lines? - defaults for parameters of some functions? @@ -185,3 +191,17 @@ The examples show the basic working of the functions. - printable interface - does not add much. + +- can the strength of the signal be converted to distance? + - for a given magnet maybe + - repeatability + noise is a problem. + + +## Support + +If you appreciate my libraries, you can support the development and maintenance. +Improve the quality of the libraries by providing issues and Pull Requests, or +donate through PayPal or GitHub sponsors. + +Thank you, + diff --git a/libraries/A1301/examples/A1301_determineNoise/A1301_determineNoise.ino b/libraries/A1301/examples/A1301_determineNoise/A1301_determineNoise.ino new file mode 100644 index 00000000..4bb9aef3 --- /dev/null +++ b/libraries/A1301/examples/A1301_determineNoise/A1301_determineNoise.ino @@ -0,0 +1,40 @@ +// +// FILE: A1301_determineNoise.ino +// AUTHOR: Rob Tillaart +// PURPOSE: demo A1301 A1302 magnetometer. + + +#include "Arduino.h" +#include "A1301.h" + +A1301 mm(A0); + +uint32_t lastTime = 0; + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("A1301_LIB_VERSION: "); + Serial.println(A1301_LIB_VERSION); + + mm.begin(5000, 1023); + + for (int t = 2; t < 20; t++) + { + Serial.print(t); + Serial.print("\t"); + Serial.println(mm.determineNoise(t), 4); + } + Serial.println("\ndone..."); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/A1301/examples/A1301_test/A1301_test.ino b/libraries/A1301/examples/A1301_test/A1301_test.ino index decd08c5..cfb8ea1c 100644 --- a/libraries/A1301/examples/A1301_test/A1301_test.ino +++ b/libraries/A1301/examples/A1301_test/A1301_test.ino @@ -47,12 +47,18 @@ void test(float raw) Serial.print("\t"); Serial.print(mm.isSouth()); Serial.print("\t"); + Serial.print(mm.isRising()); + Serial.print("\t"); + Serial.print(mm.isFalling()); + Serial.print("\t"); Serial.print(mm.isSaturated()); Serial.print("\t"); Serial.print(mm.prevGauss()); Serial.print("\t"); Serial.print(mm.lastGauss()); Serial.print("\t"); + Serial.print(mm.deltaGauss()); + Serial.print("\t"); Serial.print(mm.saturationLevel()); Serial.print("\n"); } diff --git a/libraries/A1301/keywords.txt b/libraries/A1301/keywords.txt index 03bbc340..b9553a29 100644 --- a/libraries/A1301/keywords.txt +++ b/libraries/A1301/keywords.txt @@ -25,8 +25,14 @@ readExt KEYWORD2 isNull KEYWORD2 isNorth KEYWORD2 isSouth KEYWORD2 +isRising KEYWORD2 +isFalling KEYWORD2 + lastGauss KEYWORD2 prevGauss KEYWORD2 +deltaGauss KEYWORD2 +angle KEYWORD2 +determineNoise KEYWORD2 Tesla KEYWORD2 mTesla KEYWORD2 diff --git a/libraries/A1301/library.json b/libraries/A1301/library.json index 2e666b95..98ff2116 100644 --- a/libraries/A1301/library.json +++ b/libraries/A1301/library.json @@ -15,9 +15,9 @@ "type": "git", "url": "https://github.com/RobTillaart/A1301.git" }, - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", - "frameworks": "arduino", + "frameworks": "*", "platforms": "*", "headers": "A1301.h" } diff --git a/libraries/A1301/library.properties b/libraries/A1301/library.properties index bd7d28d0..8ff5ed6c 100644 --- a/libraries/A1301/library.properties +++ b/libraries/A1301/library.properties @@ -1,5 +1,5 @@ name=A1301 -version=0.2.0 +version=0.2.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for A1301 et al magnetometer.