#ResponsiveAnalogRead http://damienclarke.me/code/responsive-analog-read
ResponsiveAnalogRead is an Arduino library for eliminating noise in analogRead inputs without decreasing responsiveness. It sets out to achieve the following:
- Be able to reduce large amounts of noise when reading a signal. So if a voltage is unchanging aside from noise, the values returned should never change due to noise alone.
- Be extremely responsive (i.e. not sluggish) when the voltage changes quickly.
- Have the option to be responsive when a voltage stops changing - when enabled the values returned must stop changing almost immediately after.
- The returned values must avoid 'jumping' up several numbers at once, especially when the input signal changes very slowly. It's better to transition smoothly as long as that smooth transition is short.
You can preview the way the algorithm works with sleep enabled (minimising the time spend transitioning between values) and with sleep disabled (transitioning responsively but smooth).
An article discussing the design of the algorithm can be found here.
###Impending version bump Written 14/07/2016
Improvements to the sleep algorithm will be pushed as a minor version upgrade soon. Special thanks to /u/brontide for the assistance.
##How to install
In the Arduino IDE, go to Sketch > Include libraries > Manage libraries, and search for ResponsiveAnalogInput. You can also just use the files directly from the src folder.
Look at the example in the examples folder for an idea on how to use it in your own projects. The source files are also heavily commented, so check those out if you want fine control of the library's behaviour.
##How to use
Here's a basic example:
// include the ResponsiveAnalogRead library
#include <ResponsiveAnalogRead.h>
// define the pin you want to use
const int ANALOG_PIN = A0;
// make a ResponsiveAnalogRead object, pass in the pin, and either true or false depending on if you want sleep enabled
// enabling sleep will cause values to take less time to stop changing and potentially stop changing more abruptly,
// where as disabling sleep will cause values to ease into their correct position smoothly
ResponsiveAnalogRead analog(ANALOG_PIN, true);
// the next optional argument is snapMultiplier, which is set to 0.01 by default
// you can pass it a value from 0 to 1 that controls the amount of easing
// increase this to lessen the amount of easing (such as 0.1) and make the responsive values more responsive
// but doing so may cause more noise to seep through if sleep is not enabled
void setup() {
// begin serial so we can see analog read values through the serial monitor
Serial.begin(9600);
}
void loop() {
// update the ResponsiveAnalogRead object every loop
analog.update();
Serial.print(analog.getRawValue());
Serial.print("\t");
Serial.print(analog.getValue());
// if the repsonsive value has change, print out 'changed'
if(analog.hasChanged()) {
Serial.print("\tchanged");
}
Serial.println("");
delay(20);
}
##Constructor arguments
pin- int, the pin to read (e.g. A0)sleepEnable- boolean, sets whether sleep is enabled. Defaults to true. Enabling sleep will cause values to take less time to stop changing and potentially stop changing more abruptly, where as disabling sleep will cause values to ease into their correct position smoothly.snapMultiplier- float, a value from 0 to 1 that controls the amount of easing. Defaults to 0.01. Increase this to lessen the amount of easing (such as 0.1) and make the responsive values more responsive, but doing so may cause more noise to seep through if sleep is not enabled.
##Basic methods
int getValue() // get the responsive value from last updateint getRawValue() // get the raw analogRead() value from last updatebool hasChanged() // returns true if the responsive value has changed during the last updatevoid update(); // updates the value by performing an analogRead() and calculating a responsive value based off it
##Other methods (settings)
###Sleep
void enableSleep()void disableSleep()
Sleep allows you to minimise the amount of responsive value changes over time. Increasingly small changes in the output value to be ignored, so instead of having the responsiveValue slide into position over a couple of seconds, it stops when it's "close enough". It's enabled by default. Here's a summary of how it works:
- "Sleep" is when the output value decides to ignore increasingly small changes.
- When it sleeps, it is less likely to start moving again, but a large enough nudge will wake it up and begin responding as normal.
- It classifies changes in the input voltage as being "active" or not, so it can set a timer and tell when it hasn't been sufficiently active for a while. That lack of activity can tell it to sleep.
- It requires different thresholds of movement for both sleep and awake states, which defines just how much movement needs to occur to count as being "active".
It's behaviour can be modified with the following methods:
void enableEdgeSnap() // edge snap ensures that values at the edges of the spectrum (0 and 1023) can be easily reached when sleep is enabledvoid setSleepDelay(unsigned int ms) // sets the amount of time before sleepingvoid setSleepActivityThreshold(unsigned int newThreshold) // the amount of movement that must take place while asleep for it to register as activity and start moving the output value. Defaults to 20.void setAwakeActivityThreshold(unsigned int newThreshold) // the amount of movement that must take place while awake for it to register as activity, and reset the timer before sleep occurs. Defaults to 5.
###Snap multiplier
void setSnapMultiplier(float newMultiplier)
SnapMultiplier is a value from 0 to 1 that controls the amount of easing. Increase this to lessen the amount of easing (such as 0.1) and make the responsive values more responsive, but doing so may cause more noise to seep through when sleep is not enabled.
###Analog resolution
void setAnalogResolution(unsigned int resolution)
If your ADC is something other than 10bit (1024), set that using this.
Damien Clarke, 2016