This library provides a non-blocking way of processing the input from an analog input source, from a piezo/knock/vibration sensor.
Inspired by "knock" projects, and my work on the Door Knock Notifier, I decided to modularize this logic behind it into a library.
Connect your knock sensor module on Analog Pin 0, according to instructions here or here
Declare a callback method that will execute everytime a knock is detected.
void onKnockReceived(float, long);
Declare the two parameters lowThreshold and noiseThreshold
int lowThreshold = 10; // The lowest value a transient is permitted to have
int noiseThreshold = 3; // Used to filter out analogRead noise
Create an instance of KnockDetector
KnockDetector knockDetector(lowThreshold, noiseThreshold, callback);
Define your callback functionality:
void onKnockReceived(float knockIntensity, long pulseLength) {
// do something when a knock is received
// optionally do something with the two values
}
loop() Function:
void loop() {
knockDetector.loop(analogRead(A0)) // Or use another analog pin
}
#include <KnockDetector.h>
const int sensorInputPin = A0;
void callback(float, long);
KnockDetector knockDetector(20, 5, callback);
void callback(float knockIntensity, long pulseLength) {
Serial.println("Knock detected!");
Serial.print("Knock intensity: ");Serial.println(knockIntensity);
Serial.print("Knock Pulse length in microseconds: ");Serial.println(pulseLength);
}
void setup() {
Serial.begin(9600);
}
void loop() {
knockDetector.loop(analogRead(piezoInputPin));
}
By using states and timers, this algorithm will detect a transient (peak) input that will trigger a listener which will record the entire signal until there is an amount of silence. After a specified amount of silence, the listener times out, and the algorithm returns to its idle state, waiting for a new transient.
The advantages of this method is that instead of having raw values thrown out by the analogRead method, the algorithm returns a single value representing the entirety of a full knock event.
Simply reading the raw values does not provide context or continuity (e.g. we do not know whether a random set of values refers to the same physical knock or are parts of different signals).
Define proper single name to be used for Arduino Library manager, repository, etc- Get rid of arduino platform dependencies
- Write unit tests
- Decouple algorithm from the entrypoint module
- Define readable state machines
- Proper reassignment of _knockPulse object instead of having singleton
- Use JLED library as a golden sample for ci and config
- Exchange the "silence timeout" algorithm to a logic check
- where a value followed by a bigger value is treated as a separate signal
- Handle micros() reset to 0
- Handle AnalogRead sampling to avoid issues on ESP8266/NodeMCU (Check websockets probe)
- Add merge job on circle CI
- Add pull request job on circle CI
- Create build scripts
Publish library to Arduino Library ManagerAdd keywords.txt for highlighting on Arduino IDE- Add entry for platform.io
- Add example with two sensors at the same time (led array)
- Add drawings/schematics
- Provide a calculation of the peak amplitude based on mVolts
- Provide a "calibration" sequence
- Augment above calibration sequence with ML