robtillaart:
Yes, please post the code, you want to share, I'll comment (maybe others too
Here it is (I wanted to triple check it and test it before posting):
/* Breath Sensor and Moving average
By Luca Brigatti
Adapted from an algorithm by robtillaart
Calculates the derivative (difference) between two subsequent sensor readings
and calculates a moving average of the derivative signal
Optimized for a running average of 2^n elements ( 2, 4, 8 , 16 etc.)
Sensor used for testing is breath sensor by Modern Devices:
http://shop.moderndevice.com/products/wind-sensor
*/
const boolean DEBUG = true ; // true, to print data on the serial port. false to do something else
const int MAVSIZE = 16 ; // Elements (size) of the moving average
// Signal variables
int oldval ;
int newval ;
int derivative ; // will hold oldval - newval
// Moving Average variables
int MavValues [MAVSIZE] ; // Holds the last MAVSIZE values of the moving average
int mavtot = 0 ; // total of the moving average (before the division)
int mav = 0 ; // Moving average = mavtot / MAVSIZE
int mavindex = 0 ; // next value to use for the moving average
int sizemask ; // Mask to use for the index counter
void setup() {
Serial.begin(9600); // <--- Low speed: easier to collect data from the serial port, High Speed: smoother curve and tighter moving average
sizemask = MAVSIZE -1 ; // If MAVSIZE is B10000 (16), sizemask is B01111 (15)
setupmav (MAVSIZE) ; // Initialize the Moving Average with the first MAVSIZE values
if (DEBUG) Serial.println("Square breathing 0.1");
}
void loop() {
newval = analogRead(A2); // measure the wind
derivative = (newval - oldval); // first derivative of the signal
updatemav (MAVSIZE) ; // Updates the moving average, a new mav value is assigned.
if (DEBUG) serialdump() ;
else ; // Do something with mav , the moving average of the derivative or newval, the actual reading
oldval = newval ; // Remember previous value for next derivative
}
void serialdump () {
// OUTPUT CAN BE COPIED TO EXCEL
// Put here what you want to print
Serial.print(millis());
Serial.print(";");
Serial.print(oldval);
Serial.print(";");
Serial.print(newval);
Serial.print(";");
Serial.print(derivative);
Serial.print(";");
Serial.print(mav);
Serial.print(";");
// SQUARE OUTPUT (% as example)
if (derivative > 0 && newval > 40) Serial.println(100);
else Serial.println(0);
}
void setupmav(int mavsize) {
mav = 0 ;
mavtot = 0 ;
oldval = analogRead(A2) ; // Starting point, change with Pin actually used
for (int i = 0 ; i < mavsize; i++ ) {
newval = analogRead(A2); // measure the wind, change with pin used
derivative = (newval - oldval); // first derivative of the signal
MavValues [i] = derivative ; // Remember this value
mavtot += derivative; // Update the running total
oldval = newval ; // New Value is now old value
}
mav = mavtot / mavsize ; // First moving average
}
void updatemav (int mavsize) {
mavtot += derivative ; // Add latest value
mavtot -= MavValues [mavindex] ; // Subtract oldest value in the array
MavValues [mavindex] = derivative ; // Newest value in array, replaces oldest value
mav = mavtot / mavsize ; // New moving average
mavindex++ ; // Point to the next element in the array, now the oldest element.
mavindex &= sizemask ; // Circle back to 0 if reached size of the moving average (e.g. 10000 & 01111 (16 & 15) = 00000 (0) )
}
My algorithm is not as abstracted and nearly as useful as your library but it is optimized for a situation like the one at hand:
Putting the initial loading of the moving average array in setup and the main moving average calculation in the loop function eliminates the need for an "if" statement in the main loop to keep the count on how many values are in the array.
Also, this algorithm uses only integer math.
Finally
mavindex++ ; // Point to the next element in the array, now the oldest element.
mavindex &= sizemask ; // Circle back to 0 if reached size of the moving average (e.g. 10000 & 01111 (16 & 15) = 00000 (0) )
Replaces your modulus and my
if (mavindex=16) mavindex = 15 ;
As I feel it may be faster than both (but I really don't know).
Your comments are welcome.