Bowel Monitor
Description:
The Bowel Monitor is a device built to ease the pain of waiting for the bathroom by giving information about who’s using the bathroom, their purpose inside, and how long they have been using the bathroom.
Build Process:
The build process for this device required lots of thought about user interaction. A key moment in the designing the functionality of the device arose in deciding where the device would actually be placed. Initially, the device was going to be placed inside the bathroom and the LCD display would be placed outside the bathroom. This method of communication would require communication through the door complicating the electronic physical build of the device. In order to cut down on complexity and reduce points of failure, I instead focused on minimizing the amount of separate components communicating with each other. I decided to have one device placed on the outside of the bathroom that the user could interact with before entering the bathroom. This type of device both cut down on the points of failure within the device by reducing both electrical complexity and simplified the user interaction by giving the immediate feedback about the information they are choosing to display.
Another major consideration was the process for determining whether or not the door has been closed. The device could either use a proximity sensor or magnetic field sensor to detect when the door closes and display the appropriate information. The proximity sensor would have required less components as it could be placed within the physical housing of the device and rely on proximity to a reference near the door; however, physically holding the proximity sensor inside the housing would reduce versatility as it could only be placed where there is a hole in the side of the box. In contrast, the magnetic field sensor required both the sensor inside the display module and a separate set of magnets on the outside of the box to trip the sensor when the door closes. While this design is physically more complex because of the extra component, electrically it is much simpler because the magnetic field sensor acts as a switch as opposed to the analog output from the proximity sensor. The magnetic field sensor could also be taped anywhere inside the housing making the Bowel Monitor more versatile in where it can be placed outside the bathroom. In order to simplify the electronics and increase versatility of the Bowel Monitor, I decided to use the magnetic field sensor to detect when the door has closed.
Discussion:
I am extremely pleased with the outcome of this project. I think the overall design and look of the Bowel Monitor came out clean and elegant as intended. I agree with the comments on cleanliness and humor of the device: “Everything about the display is so clean! I like the humor incorporated into the project and the timer is a nice feature.” Part of this cleanliness came from the laser cut look of the device. As noted by peers, “the laser cut look” and “plate with the LCD and the numbers [are] really clean and give a really nice user interface.” I believe the laser cut housing organized the display and user interaction creating a more cohesive and clean design. As for the design of the box itself, I agree that “adding more to the design of the box would add to the comedic feel of the overall project.” I think designing the box in the shape of something like a poop emoji would add more comedic effect to the device and consequently enhance its light-hearted nature. Similarly, adding emojis to the display could enhance the user experience with more comedy about the types of bathroom uses.
While the overall design and interaction succeeded in providing both comedic effect and useful information, I think some of the sensing mechanisms could have been enhanced to improve versatility of the Bowel Monitor. Replacing the magnetic sensor for a proximity sensor could decrease the physical complexity of the device by reducing the amount of components needed for the device to function. As for the user interaction with the device, adding a selection menu while the door is open would allow the user to select their business in the bathroom while the door is open instead of just while the door is closed. This would reduce the strain on the user by giving them more options on how to interact with the Bowel Monitor. They could either close the door, enter their information, and then go into the bathroom as before, or they could keep the door open while they select their information, and then use the bathroom as indicated.
As for my own experience designing and building the Bowel Monitor, I learned a lot about my design and manufacturing capabilities. I learned how to both design and manufacture electronic housing using a laser cutter as opposed to a 3D printer. I also thoroughly enjoyed applying technical knowledge in such a silly manner.
Technical Information:
/* 60-223, Project 2: Bowel Monitor James Kyle (jkyle1) time spent: Too much Collaboration and sources: 1) I watched the canvas course modules 2) Keypad tutorial: https://www.circuitbasics.com/how-to-set-up-a-keypad-on-an-arduino/ Challenge(s): I had lots of trouble coming up with the logical variables I needed to update the display properly. I also struggled with writing the function to determine how to update the display based on the key pressed on the key pad. I ended up using the serial monitor to display the value returned by each key press and then used that value to distinguish keys. Next time: I'll start by thinking at a higher level about the user interaction before diving into the details of coding the device behavior. I will also research the components I am using more thoroughly to ensure I understand how they work. Description: This device determines whether the bathroom door is open or closed. When the door is closed, the user is able to press keys on a keypad to indicate who they are and what they are doing in the bathroom. The device then displays that information along with the time they have been in the bathroom to give others an indication of how much longer they can expect to wait to use the bathroom. Pin mapping: Arduino pin | type | description ------------|--------|------------- A0 input R4 [Keypad] A1 input R3 [Keypad] A2 input R2 [Keypad] A3 input R1 [Keypad] A4 input Reed Switch 2 output D7 LCD 3 output D6 LCD 4 output D5 LCD 5 output D4 LCD 6 output E pin LCD 7 output RS pin LCD 10 output C4 [Keypad] 11 output C3 [Keypad] 12 output C2 [Keypad] 13 output C1 [Keypad] */ //Importing necessary libraries #include <Keypad.h> #include <LiquidCrystal.h> /*************** KEYPAD SETUP ***************/ //Setting up pins for key pad const int R1 = A3; const int R2 = A2; const int R3 = A1; const int R4 = A0; const int C1 = 13; const int C2 = 12; const int C3 = 11; const int C4 = 10; //Setting up key pad logic const byte ROWS = 4; const byte COLS = 4; //Creating key pad matrix char hexaKeys[ROWS][COLS] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPins[ROWS] = {R4, R3, R2, R1}; byte colPins[COLS] = {C4, C3, C2, C1}; //Creating key pad variable Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); char customKey; //variable to store key pressed /************** LCD DISPLAY **************/ //Setting up LCD LiquidCrystal lcd(2, 3, 4, 5, 6, 7); /************** Reed Switch **************/ const int REEDPIN = A4; /************* Variables *************/ //Variables for timing unsigned long timer = 0; //overall time unsigned int timerSec = 0; //time in seconds unsigned int timerMin = 0; //time in minutes unsigned long prevTime = 0; //previous time in miliseconds unsigned long prevTimer = 0; //previous time in seconds //Message variables for LCD display String useMessage; //Bathroom use type String user = ""; //Person using the bathroom String timerMessage; //For displaying time in bathroom String openMessage = "The Porcelain Throne Awaits Your Return"; //Idling message //Logical variables for updating LCD display and timer bool updateUseMessage = false; bool updateTime = false; bool resetDisplay = false; bool doorOpen = false; bool lcdClearClosed = false; bool lcdClearOpen = false; //Variables for timing LCD and scroll updates int displayCounter = 0; int scrollCounter = 0; void setup() { //Initializing reed pin using pull-up pinMode(REEDPIN, INPUT_PULLUP); //Debugging Serial.begin(9600); //Start communicating with LCD lcd.begin(16, 2); } void loop() { //Read Key Pad using Keypad.h customKey = customKeypad.getKey(); //Check if door is open or closed int doorState = digitalRead(REEDPIN); /*********************** ***Door Open Squence*** ***********************/ //If door is open, dislay idling message if (doorState == 1) { //Clear LCD only if door was just opened and LCD hasn't been cleared yet if (lcdClearOpen == false) { lcd.clear(); //clear LCD delay(100); lcd.setCursor(0, 0); lcd.print(openMessage); //Display idling message delay(1000); //Wait 1 second //Update LCD cleared variables lcdClearOpen = true; //LCD cleared after door was opened lcdClearClosed = false; //LCD needs to be cleared when door opens //Update timers and counters for LCD scrollCounter = 0; //Reset displayed time timerSec = 0; timerMin = 0; } //Scroll idling message until it reaches end of message, //then wait for 1 second and return to beginning of //idling message if (scrollCounter < openMessage.length() - 16) { lcd.scrollDisplayLeft(); scrollCounter = scrollCounter + 1; //increment scroll counter delay(500); } else { //If message reaches end point scrollCounter = 0; //clear LCD and reset counters lcdClearOpen = false; delay(1000); } } /************************* ***Door Closed Squence*** *************************/ //If door closes, display user inputs and time on LCD else if (doorState == 0) { //Starting timer timer = millis() / 1000 - prevTimer; //Clearing LCD if door was just closed if (lcdClearClosed == false) { lcd.clear(); lcdClearClosed = true; lcdClearOpen = false; prevTime = millis(); //resetting relative time prevTimer = millis() / 1000; //Conversion to seconds } //only update time if one second has passed if (millis() - prevTime > 1000) { updateTime = true; prevTime = millis(); //Converting time from seconds to minutes and seconds timerSec += 1; //incrementing seconds counter if (timerSec >= 60) { timerSec = 0; timerMin += 1; //incrementing minutes counter } } //update time on lcd if (updateTime == true) { lcd.setCursor(0, 1); lcd.print((String) timerMin + " min " + timerSec + " sec"); lcd.setCursor(14,1); lcd.print(user); updateTime = false; //resetting update variable for time } //If keypad pressed, do something based on the key pressed if (customKey) { updateUseMessageFunction(customKey); } //Update lcd if it needs to be updated if (updateUseMessage == true) { lcd.setCursor(0, 0); lcd.print(" "); //Clearing current use message lcd.setCursor(0, 0); lcd.print(useMessage); //Display new use message Serial.println(useMessage); //debugging line for lcd screen updateUseMessage = false; //resetting update variable so screen is updated only if there is a change } } } //This function determines how to update the display based on the keys //pressed on the key pad void updateUseMessageFunction(char key) { /**************************** ** Types of Bathroom Uses ** ****************************/ //Peeing if (int(key) == 49) { useMessage = "Pee Pee Time! "; //Changing use message updateUseMessage = true; //Indicating LCD needs to be updated } //Pooping if (int(key) == 50) { useMessage = "Poopy Time! "; updateUseMessage = true; } //Diarrhea or equivalent destructive act if (int(key) == 51) { useMessage = "Uh-oh! ;) "; updateUseMessage = true; } //Washing face if (int(key) == 52) { useMessage = "Washing Face"; updateUseMessage = true; } //Brushing Teeth if (int(key) == 53) { useMessage = "Brushing Teeth"; updateUseMessage = true; } //Showering if (int(key) == 54) { useMessage = "Showering"; updateUseMessage = true; } //Clear use type on screen if (int(key) == 42) { useMessage = " "; updateUseMessage = true; } /*************************** ** People Using Bathroom ** ***************************/ //James Kyle if (int(key) == 65) { user = "JK"; updateTime = true; } //Judson Kyle if (int(key) == 66) { user = "JK"; updateTime = true; } //Roommate 1 if (int(key) == 67) { user = "MR"; updateTime = true; } //Roommate 2 if (int(key) == 68) { user = "LW"; updateTime = true; } }