top of page
  • Writer's picturePuriphico

update: auditory sensor calibration system in Puriphico device

Updated: Jun 15, 2021

As I make progress with the development of the prototype, I plan to keep a log here, in the blog, under the "Updates" category. Subscribe to be alerted whenever a new update has been developed! (Also, if you are looking to implement more technical improvements in your Arduino programs, these examples can serve as a framework, so I suggest reading fully and analyzing the code. That said, when you spot an improvement to be made in my codes, PLEASE let me know ASAP - I'm looking for feedback!)

Update type: Incorporation of a calibration system for the auditory sensor in the Puriphico prototype.

Background Information: To provide some context for the calibration system: in my prior codes, such as the one shown in the Bluetooth incorporation update, I use a range to identify handwashing frequencies. Given that I have recorded distinctions in frequency patterns between running water, background noise, and handwashing, I was able to isolate this range of frequencies as being attributed to (for the most part) handwashing. However, since different sinks have different characteristics, such as different depths and materials, the range of frequencies that characterize handwashing are not the same across the board, hence why, were I to test the device in a sink different to my own, it would likely not work since it would not be able to identify handwashing frequencies. Yes, it will recognize handwashing visually through the PIR sensor; however, both sensors - the auditory and visual - must be in agreement before the timer can start. To account for these disparities, I have introduced the calibration system of the auditory sensor.

Brief description: The calibration system is fairly simple: the user presses a button to initialize it. Subsequently, the timer will start and one of the two available LED's will illuminate. While this LED remains illuminated, the user must keep water running. This LED will stay illuminated for 10 seconds (the timer is subject to change), until it will turn off and a different-colored LED will illuminate to indicate the following 10 seconds. In the following 10 seconds, the user should wash their hands as they normally would. After the 20 seconds is completed, the device will analyze the different frequencies from each set of 10 seconds, respectively, and calculate the average percent difference between them, as illustrated in the code below. After all this has occurred, the user will be able to use the Puriphico device. (It is important to note that the device can be re-calibrated if re-located to a different sink.) When turned on, the device will compare the audio frequencies it collects while running to the handwashing standard established in the second, 10-second subset of the calibration. Then, it will establish another percent difference between these samples, which will be compared to the original percent difference. If the second percent difference is smaller than the first (which identified, once again, the difference in audio frequencies between running water and handwashing), the device will consider it handwashing, and, if in agreement with the PIR, it will initialize the 20-second timer.

include image of calibration code and image of serial monitor as it progresses

it has not been incorporated in actual code - when it is incorporated in bluetooth in the all_encompassing code, I will notify through the blog section


  • The below code demonstrates the calibration system, as described above.

  • Note: this code has not yet been combined with the Bluetooth program, and, at the moment, is an independent program.


#include <PDM.h>

#include <arduinoFFT.h> //for the Fourier transform

arduinoFFT FFT = arduinoFFT();

#define SAMPLES 256 //Must be a power of 2


short sampleBuffer[SAMPLES];

volatile int samplesRead;

double vReal[SAMPLES];

double vImag[SAMPLES];

// void onPDMdata(void);

int buttonPin = 12;

int LEDPin = 6;

int buttonRead;

int forceState = 0;

int timer = 0;

int counter = 0;

float waterav = 0;

float watertotal = 0;

float washhandsav = 0;

float washhandstotal = 0;

float pdifference = 0;

void setup() {

// put your setup code here, to run once:


// initialize the LED pin as an output:

pinMode(LEDPin, OUTPUT);

// initialize the pushbutton pin as an input:

pinMode(buttonPin, INPUT);



if (!PDM.begin(1, 16000)) {

Serial.println("Failed to start PDM!");

while (1);



void onPDMdata() {

int bytesAvailable = PDM.available();, bytesAvailable);

samplesRead = bytesAvailable / 2;


void loop() {

buttonRead = digitalRead(buttonPin);

if (buttonRead == 0) {

forceState = 1;


if (forceState == 1) {

timer = timer + 1;


digitalWrite(LEDPin, HIGH);

if (timer < 10) {

if (samplesRead) {

for (int i = 50; i < 150; i++) {

watertotal = watertotal + sampleBuffer[i];



} if (10 < timer < 20) {

if (samplesRead) {

for (int i = 50; i < 150; i++) {

washhandstotal = washhandstotal + sampleBuffer[i];



} if (timer == 20) {

counter = counter + 1;

forceState = 0;

Serial.println("Calibration completed");


digitalWrite(LEDPin, LOW);

timer = 0;

washhandsav = washhandstotal/100;

Serial.println("Washhandsav: ");


waterav = watertotal/100;

Serial.println("Waterav: ");


pdifference = pdifference + (((washhandsav - waterav) / ((washhandsav + waterav)/2))*100);

Serial.println("Percent difference: ");


} delay(1000);



  • The following video illustrates what the computer displays as the code runs.

  • When I press the button (to initialize the calibration), the computer displays the timer (how many seconds have passed) and, after 20 seconds of audio sampling, the evaluated data. In this video, I calibrate the device twice, hence why there are two cycles of the described pattern.

  • Note: the final percent difference and audio samples shown are not from handwashing.

84 views0 comments

Recent Posts

See All


bottom of page