Inspiration

We were inspired to undertake this project given the current pandemic of COVID-19 on our hands. Especially during this time, it is important not to neglect the importance of personal hygiene, and amidst the bustle of our daily lives, we can sometimes forget to do even the small things properly. Our initiative, therefore, is to help out and do our part by creating a handwashing assistant that could aid in the proper timing of disinfection.

How it was built and what it does

We combined a PIR-sensory, ultrasound sensor, and a piezo to fashion a makeshift handwashing timer. The technological premise behind the project was that upon detection of motion, a timer for 20 seconds would start. The device would display a green light and play a song for those 20 seconds. Upon termination of the interval, the piezo would make a noise and your handwashing is complete!

Challenges we faced

We had some difficulties incorporating the piezo smoothly into the body of the code, as it was difficult to align the timings and function of all these moving pieces.

Code

#define PIN 6
#include <LiquidCrystal.h>
#define taskLampPin 13
#define breakLampPin 8
#define triggerPin 7
// TONES  ==========================================
// Relationship between 
//      note, period, &  frequency. 
#define  c     3830    // 261 Hz 
#define  d     3400    // 294 Hz 
#define  e     3038    // 329 Hz 
#define  f     2864    // 349 Hz 
#define  g     2550    // 392 Hz 
#define  a     2272    // 440 Hz 
#define  b     2028    // 493 Hz 
#define  C     1912    // 523 Hz 
// Define a special note, 'R', to represent a rest
#define  R     0

/*
 * Library used to write on the LCD display
 */
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

/*
 * Critical level, at which the siren will be turned on
 */
float CRITICAL_LEVEL = 7;

int PIN_LEVEL = A0;
unsigned int PIN_BUZZER = 10;

int message = 0;
// the following variables are longs because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
unsigned long TASK_TIME = 30000; // for testing: 30 seconds
unsigned long BREAK_TIME = 5000; // for testing: 5 seconds
unsigned long taskDelayStart = 0; // the time the delay started
unsigned long breakDelayStart = 0; // the time the delay started
bool taskDelayRunning = false; // true if still waiting for delay to finish
bool breakDelayRunning = false; // true if still waiting for delay to finish
bool taskLightOn = false; // keep track of the lamp state
int sensorState = 0;
void setup() {

  pinMode(triggerPin, INPUT_PULLUP); //set up switch pin with internal pullup resistor
  pinMode(taskLampPin, OUTPUT);        
  digitalWrite(taskLampPin, LOW);
  pinMode(7, INPUT);
  pinMode(breakLampPin, OUTPUT);        
  digitalWrite(breakLampPin, LOW);

  pinMode(PIN_LEVEL, INPUT);
  pinMode(PIN_BUZZER, OUTPUT);

    /*
     * Initializes Serial at 9600
     */
    Serial.begin(9600);
    lcd.begin(16, 2);
}

void loop() {
   // read the state of the sensor/digital input
  sensorState = digitalRead(7);
  // check if sensor pin is HIGH. if it is, set the
  // LED on.
  if (sensorState == HIGH) {
    digitalWrite(13, HIGH);
    lcd.setCursor(0, 0);
    lcd.print("Washing hands!");
    Serial.println("Sensor activated!");
    digitalWrite(13, HIGH); //Turn green light on
    //Start timer
        if (!taskLightOn && !taskDelayRunning & !breakDelayRunning){ // if the lamp is off and neither timer has started yet
      taskDelayStart = millis(); //start delay
      taskDelayRunning = true;   //start the task timer
      digitalWrite(taskLampPin, HIGH);         //turns on the light
      taskLightOn = true;
    }
    //Start music
    launchSiren();    
    lcd.clear();
    digitalWrite(8, HIGH);
    lcd.print("Done!")
    ;delay(4500);
    lcd.clear();
    digitalWrite(8, LOW);
    lcd.print("Waiting...");

  } 
  delay(100); // Delay a little bit to improve simulation performance

}

// MELODY and TIMING  =======================================
//  melody[] is an array of notes, accompanied by beats[], 
//  which sets each note's relative length (higher #, longer note) 
int melody[] = {  C,  b,  g,  C,  b,   e,  R,  C,  c,  g, a, C };
int beats[]  = { 16, 16, 16,  8,  8,  16, 32, 16, 16, 16, 8, 8 }; 
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.

// Set overall tempo
long tempo = 40000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 50; //<-BLETCHEROUS HACK; See NOTES

// Initialize core variables
int tone_ = 0;
int beat = 0;
long duration  = 0;

// PLAY TONE  ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
  long elapsed_time = 0;
  if (tone_ > 0) { // if this isn't a Rest beat, while the tone has 
    //  played less long than 'duration', pulse speaker HIGH and LOW
    while (elapsed_time < duration) {
      digitalWrite(PIN_BUZZER,HIGH);
      delayMicroseconds(tone_ / 1.8);

      // DOWN      
      digitalWrite(PIN_BUZZER, LOW);
      delayMicroseconds(tone_ / 2);

      // Keep track of how long we pulsed
      elapsed_time += (tone_);
    } 
  }
  else { // Rest beat; loop times delay
    for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
      delayMicroseconds(duration);  
    }                                
  }                                 
}

/*
 *@desc Triggers the siren / buzzer when the level is above the configured critical level
 *@param level - current level, according to the potentiometer
 */
void launchSiren() {
// Set up a counter to pull from melody[] and beats[]
  for (int j=0; j<3; j++) {
  for (int i=0; i<MAX_COUNT; i++) {
    tone_ = melody[i];
    beat = beats[i];

    duration = beat * tempo; // Set up timing
    playTone();
    // A pause between notes...
    delayMicroseconds(pause);
  }
  }

}

Built With

Share this project:

Updates