Dental Routine Timer:

The assistive device made is a device that times and keeps the user on track with three steps of a typical dental routine: Brushing their teeth, using mouthwash, and flossing.

Images:

Process Images and Review:

One major decision in the process of making my device was whether to include a floss dispenser that could be operated by the user, or not. I had initially thought that the floss dispenser was going to be more straightforward, but as I worked on this component, it proved tougher than expected. The fact that the floss strands were stuck together when on the spool meant that the device would also need some minimum amount of force to pull the floss off the main body of floss on the spool, or alternatively, some sort of separating, sharp edge. However, the prototypes I built and modified were not functioning well, and at this point in the project, I had decided to scrap this component in favor of spending more time on other aspects of the project, such as construction. By doing so, I was able to free up more space on my Arduino boards for other parts, such as RFID readers.

Testing of Sensors Prior to RFID Readers

Setting Up of RFID Sensors

Another decision point in this project was the type of sensors I wanted to use to confirm the presence of the toothbrush, mouthwash, and floss. I had first considered IR break beam sensors and ultrasonic ranger, but I was concerned about how they would fit with the mini-shelves I had planned as well as the ultrasonic ranger not giving consistent readings with the mouthwash cup, as the sides of the cup was slightly slanted. In the end, I decided to go with RFID readers, as I thought the rectangular shape would fit well with the mini-shelves, and it would make the device harder to fool in a sense: with other sensors, you could put in any other object to be detected, but with the RFID readers, you need to use the floss and mouthwash cup with the corresponding sticker labels on them. By using RFID readers, I had to be certain in my final design, as they took up a substantial amount of pins on the Arduino board, and had to create multiple portions of my laser-cut design around the RFID readers, such as the mini-shelves and the overall spacing of components due to wiring.

Device without Front Panel

Discussion:

Overall, I feel satisfied with the outcome with the project, given the time crunch I experienced near the final deadline. However, there are some critiques I would like to address. Firstly, one commentator has said, “The aesthetics are very cool, but don’t seem fit for a bathroom“. I also agree with the comment on the size of the device. While carrying it around, it is not very comfortable to carry around, and is quite bulky to move around, but that is secondary to the main issue that it takes up a lot space for what could be a more compressed device. By making the device smaller, I believe it would make the device more easier to set up and use. Because of the device’s size and weight, it could be broken up into two parts: a hub for the electronics and wiring, and then a secondary hub for the placement and detection of the the brush, wash cup, and floss, as suggested by the people during the in-class critique. I also see this as a very good construction for the device, as it would help address the size issue, as well as improve the accessibility of the object. Another comment posted is on the clear acrylic used for the sides of the device: “Love the black acrylic +1 and the clear side view to check mouthwash levels too!“. Funnily enough, it was not intentional to use clear acrylic in the first place, but only because I had run out of black acrylic to use, which had been all spent for the front and back of the device. In terms of the clear side view, I feel conflicted. On one hand, as the commentator has noted, it makes observing how much mouthwash is left much easier, but on the other hand, it also makes the inner construction (which was done sloppily in my opinion) visible, leaving a clear view of the electronics inside. However, in the grand scheme of what was built, I see the construction and functionality of the device as satisfactory. For my purposes, the device is able perform its function well, and has few, near insignificant, hindrances that stand out. If there was one major complaint I have personally, it is that the side panels were not wide enough to fit into the front panel, and the wiring and tapping together of pieces could have done with better. From this, I learned more on how to improve my modeling skills and how to manage the scope of a project so that it does not become overwhelming. Other skills I developed were working with Fusion 360 and laser-cutting, which were both foreign to me before this project. Reflecting upon these thoughts, if I were to build another iteration of this, I would make the project more compact by creating a custom tank for the liquid, as well as making the housing smaller by making it less tall, and wider horizontally. By doing so, I believe that it will become easier to use and more visually appealing in a restroom.

Block Diagram and Schematic:

Code:

//Assistive Device: Dental Routine Timer
//Peter Heo
//Websites used in learning to implement and use RFID:
//https://www.teachmemicro.com/arduino-rfid-rc522-tutorial/
//https://stackoverflow.com/questions/32839396/how-to-get-the-uid-of-rfid-in-arduino/32842194
//Pin mapping:
//Pin Number          Pin Name            Desc.
//A0                  FSR Round Pin       Input for FSR Round Sensor
//3                   SS Pin Floss        Input for SS Pin for RFID Reader for Floss
//7                   Pump Pin            Output for Relay 
//8                   Switch Pin          Input for Toggle Switch
//9                   RST Pin             Input for RST Pin of Both RFID Readers
//10                  SDA Pin             Input for SDA Pin of Both RFID Readers
//11                  MOSI Pin            Input for MOSI Pin of Both RFID Readers
//12                  MISO Pin            Input for MISO Pin of Both RFID Readers
//13                  SCK Pin             Input for MISO Pin of Both RFID Readers
//SDA                 LCD SDA Pin         Pin for SDA of LCD Display
//SCL                 LCD SCL Pin         Pin for SCL of LCD Display
      

#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <NewPing.h>
#include <SPI.h>
#include <MFRC522.h>

//Initialize pins and objects for the RFID readers: one for the floss and one for the moutwash cup.

#define SSCUPPIN 10
#define RSTPIN 9
#define SSFLOSSPIN 3
MFRC522 rfidCup(SSCUPPIN, RSTPIN);
MFRC522 rfidFloss(SSFLOSSPIN, RSTPIN);

//Initialize pins for the switch, peristaltic pump, the round FSR, and, as well as the LCD screen object.
const int TOOTHBRUSHPIN = A0;
const int SWITCHPIN = 8;
const int PUMPPIN = 7;
LiquidCrystal_I2C screen(0x27, 16, 2);

int brushTimer = 2;
int brushTime = 0;
int washTimer = 2;
int washTime = 0;
int flossTimer = 2;
int flossTime = 0;
long prevTime = 0;

boolean setUpFinished = false;
boolean brushStarted = false;
boolean brushFinished = false;
boolean washStarted = false;
boolean washFinished = false;
boolean cupFilled = false;
boolean flossStarted = false;
boolean flossFinished = false;
boolean flossPlaced = false;
boolean routineFinished = false;


void setup() {
  //Set up master toggle switch.
  pinMode(SWITCHPIN, INPUT);
  //Set up FSR sensors (for toothbrush and mouthwash cup).
  pinMode(TOOTHBRUSHPIN, INPUT);
  //Set up pump pin relay.
  pinMode(PUMPPIN, OUTPUT);
  //Set up LCD display.
  screen.init();
  screen.backlight();
  screen.display();
  //Set up RFID readers.
  SPI.begin();
  rfidCup.PCD_Init();
  rfidFloss.PCD_Init();

  Serial.begin(9600);

}

void loop() {


  //Sense if the device is on, if the brush is placed, if the cup is placed, and if the floss is placed.
  boolean deviceOn = (digitalRead(SWITCHPIN) == HIGH);
  boolean brushFound = (analogRead(TOOTHBRUSHPIN) > 15);
  boolean cupFound = false;
  boolean flossFound = false;

  //Sense for cup.
  if (rfidCup.PICC_IsNewCardPresent() && rfidCup.PICC_ReadCardSerial()) {
    if (rfidCup.uid.uidByte[0] == 0xd6  &&
        rfidCup.uid.uidByte[1] == 0xfc &&
        rfidCup.uid.uidByte[2] == 0x5a &&
        rfidCup.uid.uidByte[3] == 0x3e ) {
      cupFound = true;
    }
  }
  else if (rfidCup.PICC_IsNewCardPresent() && rfidCup.PICC_ReadCardSerial()) {
    if (rfidCup.uid.uidByte[0] == 0xd6  &&
        rfidCup.uid.uidByte[1] == 0xfc &&
        rfidCup.uid.uidByte[2] == 0x5a &&
        rfidCup.uid.uidByte[3] == 0x3e ) {
      cupFound = true;
    }
  }

  //Sense for floss.
  if (rfidFloss.PICC_IsNewCardPresent() && rfidFloss.PICC_ReadCardSerial()) {
    flossFound = true;
  }
  else if (rfidFloss.PICC_IsNewCardPresent() && rfidFloss.PICC_ReadCardSerial()) {
    flossFound = true;
  }

  Serial.println(analogRead(TOOTHBRUSHPIN));
  float currTime = millis();

  //Detect for master toggle switch state.
  //If it is on, indicate that device is on with LCD display.
  if (deviceOn) {
    //Display starting text.
    screen.home();
    screen.print("Device is on");
    screen.setCursor(0, 1);

    //Enter set-up stage.
    if (!setUpFinished) {
      //Sense for toothbrush.
      //Indicate for user to place brush if brush is not found.
      if (!brushFound) {
        screen.print("Place brush");
        delay(1000);
        screen.clear();
      }
      //Indicate if brush is found.
      else if (brushFound) {
        screen.print("Found brush");
        delay(1000);
        screen.clear();
        //Indicate for user to place cup if cup is not found.
        if (!cupFound) {
          screen.setCursor(0, 1);
          screen.print("Place cup");
          delay(1000);
          screen.clear();
        }
        //Indicate if cup is found.
        else if (cupFound) {
          screen.setCursor(0, 1);
          screen.print("Cup found");
          delay(1000);
          screen.clear();
          if (flossFound) {
            screen.setCursor(0, 1);
            screen.print("Floss found");
            delay(1000);
            screen.clear();
          }
          else if (!flossFound) {
            screen.setCursor(0, 1);
            screen.print("Place floss");
            delay(1000);
            screen.clear();
          }
          if (cupFound && flossFound && brushFound) {
            //If both cup, floss, and brush are placed, setup is done.
            screen.setCursor(0, 1);
            setUpFinished = true;
            screen.print("Setup done");
            setUpFinished = true;
            delay(3000);
            screen.clear();
          }
        }
      }
    }


    //Enter brush procedure.
    else if (setUpFinished && !brushFinished) {
      //Tell user to start brushing.
      if (!brushStarted && brushFound) {
        screen.print("Take brush");
        delay(2000);
        screen.clear();
      }
      //If brush is taken, begin brush procedure.
      else if (!brushStarted && !brushFound) {
        screen.print("Begin brushing");
        brushStarted = true;
        delay(5000);
        screen.clear();
      }
      //Begin timing user for brushing.
      else if (brushStarted && !brushFinished) {
        //If time is up, exit procedure.
        if (brushTimer - brushTime <= 0) {
          brushFinished = true;
          screen.print("Brushing done");
          delay(5000);
          screen.clear();
        }
        //Otherwise, display timer for brushing.
        else if (!brushFinished) {
          screen.print("Brush time: ");
          //
          if (currTime - prevTime >= 1000) {
            prevTime = currTime;
            brushTime += 1;
          }
          screen.print(brushTimer - brushTime);
          delay(250);
          screen.clear();
        }
      }
    }

    //Enter mouthwash stage once brush is finished.
    else if (brushFinished && !washFinished) {

      //If the cup is placed and washing has not yet started, wait for pump to fill the cup.
      if (!washStarted && cupFound && !cupFilled) {
        //Indicate to user that cup is being filled with mouthwash.
        screen.print("Found cup.");
        delay(1000);
        screen.clear();
        screen.print("Fill cup");
        delay(2000);
        //Activate pump for enough time so that cup is filled.
        digitalWrite(PUMPPIN, HIGH);
        delay(30000);
        digitalWrite(PUMPPIN, LOW);
        screen.clear();
        screen.print("Cup filled");
        cupFilled = true;
        delay(2000);
        screen.clear();
      }
      if (!washStarted && !cupFound && !cupFilled) {
        screen.print("Place cup...");
        delay(1000);
        screen.clear();
      }
      //If the cup is placed and filled, wait for user to take the cup.
      else if (!washStarted && cupFound && cupFilled) {
        screen.print("Take cup");
        delay(1000);
        screen.clear();
      }
      //If cup is taken, begin wash procedure.
      else if (!washStarted && !cupFound && cupFilled) {
        screen.print("Begin rinse");
        washStarted = true;
        delay(2000);
        screen.clear();
      }
      //If the cup has taken the cup, begin timing user for moutwashing.
      else if (washStarted && !washFinished && cupFilled) {
        //If time is up, exit procedure.
        if (washTimer - washTime <= 0) {
          washFinished = true;
          screen.print("Rinsing done");
          delay(2000);
          screen.clear();
        }
        //Otherwise, display timer for washing.
        else if (!washFinished) {
          screen.print("Rinse time: ");
          //
          if (currTime - prevTime >= 1000) {
            prevTime = currTime;
            washTime += 1;
          }
          screen.print(washTimer - washTime);
          delay(250);
          screen.clear();
        }
      }
    }

    //Enter mouthwash stage once brush is finished.
    else if (washFinished && !flossFinished) {

      //Look for floss.
      if (!flossStarted && flossFound && !flossPlaced) {
        //Indicate to user that floss was found by device.
        screen.print("Found floss.");
        flossPlaced = true;
        delay(1000);
        screen.clear();
      }
      //If floss was not found, indicate for user to place floss.
      if (!flossStarted && !flossFound && !flossPlaced) {
        screen.print("Place floss...");
        delay(1000);
        screen.clear();
      }
      //If the flossed is placed, wait for user to take the floss.
      else if (!flossStarted && flossFound && flossPlaced) {
        screen.print("Take floss");
        delay(1000);
        screen.clear();
      }
      //If floss is taken, begin floss timer.
      else if (!flossStarted && !flossFound && flossPlaced) {
        screen.print("Begin flossing");
        flossStarted = true;
        delay(2000);
        screen.clear();
      }
      //If the cup has taken the floss, begin timing user for flossing.
      else if (flossStarted && !flossFinished) {
        //If time is up, exit procedure.
        if (flossTimer - flossTime <= 0) {
          flossFinished = true;
          screen.print("Flossing done");
          delay(5000);
          screen.clear();
        }
        //Otherwise, display timer for flossing.
        else if (!flossFinished) {
          screen.print("Floss time: ");
          //
          if (currTime - prevTime >= 1000) {
            prevTime = currTime;
            flossTime += 1;
          }
          screen.print(flossTimer - flossTime);
          delay(200);
          screen.clear();
        }
      }
    }

    //If the user has finished the entire routine, indicate so and wait for the user to turn the device off.
    else if (flossFinished && brushFinished && washFinished && !routineFinished) {
      routineFinished = true;
    }
    else if (routineFinished) {
      screen.print("You're done!");
      delay(1000);
      screen.clear();
      screen.print("Turn device off");
      delay(1000);
      screen.clear();
    }
  }


  //If device is off, reset fields.
  else if (!deviceOn) {
    screen.home();
    screen.print("Device is off");
    screen.setCursor(0, 1);
    brushTime = 0;
    washTime = 0;
    flossTime = 0;
    prevTime = 0;

    setUpFinished = false;
    brushStarted = false;
    brushFinished = false;
    washStarted = false;
    washFinished = false;
    cupFilled = false;
    flossStarted = false;
    flossFinished = false;
    flossPlaced = false;
    routineFinished = false;
    delay(2000);
    screen.clear();
  }
}