Problem:
Stoves are a common household product for anyone with a kitchen and extremely useful in giving a person some autonomy over their life. However, they are by nature extremely hazardous because they deal with high temperatures. Although many electric stovetops have indication lights for when the surface is hot, these indications do nothing to help a blind user know when the stovetop is hot and not safe to touch.
Solution:
To solve this problem, I have decided to make a stove top temperature indicator that relies on sound and proximity to the stovetop to indicate when a surface is safe to touch. A set of ultrasonic rangers determines when an object is near and how far away the object is from the stove top. If the stovetop is too hot, the device then uses vibration motors to bounce around and audibly indicate the ensuing danger. The user also has an override button to turn the vibration off because the device cannot discern the difference between intentional and unintentional object placement on the hot stove.
Proof of Concept:
For a proof of concept, I have built a smaller version with one ultrasonic for each x and y components of the stove top. There are only two vibration motors as well just to show the possibility. In a real version of the concept, the vibration motors would be placed in a resonating surface such as a bell to create more noise and alert the user better.
Demo:
Code:
//Temperature stuff const int tempSensor = A0; float stoveTemp; float stoveTempThreshold = 40; // [*C] float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07; //Vibration motor stuff const int vibrationMotor1 = 6; const int vibrationMotor2 = 7; const int vibrationMotorCount = 2; int vibrationMotors[vibrationMotorCount] = {vibrationMotor1, vibrationMotor2}; //Object detection stuff const int trigPin1 = 12; const int echoPin1 = 13; const int trigPin2 = 8; const int echoPin2 = 9; float dangerDistance = 5; //Distance threshold //E-stop stuff const int stopButton = 3; //Logical stuff bool stoveIsHot; bool objectOnStove; bool userOverride = false; //Debounce Stuff unsigned long debounceTimer = 0; unsigned long debounceDelay = 100; bool prevButtonState = false; bool currButtonState = false; bool lookForPress = true; void setup() { pinMode(trigPin1, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin1, INPUT); // Sets the echoPin as an Input pinMode(trigPin2, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin2, INPUT); // Sets the echoPin as an Input pinMode(tempSensor, INPUT); pinMode(stopButton, INPUT_PULLUP); pinMode(vibrationMotor1, OUTPUT); pinMode(vibrationMotor2, OUTPUT); attachInterrupt(digitalPinToInterrupt(stopButton), stopNoise, LOW); Serial.begin(9600); // Starts the serial communication } void loop() { if (prevButtonState != currButtonState) { debounceTimer = millis(); prevButtonState = currButtonState; } if (millis() - debounceTimer > debounceDelay) { lookForPress = true; } if (!userOverride) { stoveIsHot = checkStoveTemp(); if (stoveIsHot) { objectOnStove = checkStoveSpace(); } } else { vibrateMotors(0); } } int getDistance(int trigPin, int echoPin) { long duration; int distance; // Clears the trigPin digitalWrite(trigPin, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculating the distance distance = duration * 0.034 / 2; // Prints the distance on the Serial Monitor return distance; } bool checkStoveTemp() { const int stoveTempThreshold = 40; static float stoveTemp; static bool DANGER; stoveTemp = analogRead(tempSensor); stoveTemp = log(stoveTemp); stoveTemp = (1.0 / (c1 + c2 * stoveTemp + c3 * stoveTemp * stoveTemp * stoveTemp)); stoveTemp = stoveTemp - 353.15; //Serial.println(stoveTemp); if (stoveTemp > stoveTempThreshold) { if (!DANGER) { DANGER = true; Serial.println("WARNING...DANGER!!"); } } else { if (DANGER) { DANGER = false; Serial.println("Surface is safe to touch now"); } } return DANGER; } bool checkStoveSpace() { static bool moveHand = false; static const int numberOfDistanceSensors = 2; static float distanceReadings[numberOfDistanceSensors]; static int distanceSensorPins[2 * numberOfDistanceSensors] = {trigPin1, echoPin1, trigPin2, echoPin2}; //Check ultrasonic rangers for (int i = 0; i < numberOfDistanceSensors; i++) { int currTrig = distanceSensorPins[2 * i]; int currEcho = distanceSensorPins[2 * i + 1]; distanceReadings[i] = getDistance(currTrig, currEcho); } //Indicate danger if something is close to stove for (int i = 0; i < numberOfDistanceSensors; i++) { if (distanceReadings[i] < dangerDistance) { Serial.println("MOVE YOU HAND!!"); //Make warning noise vibrateMotors(1); return true; } } //Turn off warning noise vibrateMotors(0); return false; } void vibrateMotors(int vibrationSpeed) { for (int i = 0; i < vibrationMotorCount; i++) { digitalWrite(vibrationMotors[i], vibrationSpeed); } } void stopNoise() { if (lookForPress) { currButtonState = !currButtonState; lookForPress = false; if (userOverride) { userOverride = false; } else { userOverride = true; } } }