Variable Timer Using a Potentiometer
by Victor Tolentino in Circuits > Arduino
502 Views, 4 Favorites, 0 Comments
Variable Timer Using a Potentiometer
Hello. My name is Victor and I am a first year Mechanical Engineering student at SJSU. What I made is a variable timer that utilizes a potentiometer for selecting the timer values. I made this because the place I work at uses a timer for cooking food, and it doesn't really work that well. My engineer brain thought, "How about I spend days making a timer that can easily be bought from AliExpress for $5?" and this is what I ended up making. I had the parts and it seemed like a fun project so why not? My aim was not to make a timer to replace the one at my job, but to replicate it in hopes that I learn something along the way, and I indeed learned a lot. The images feature the different states of the timer: setting, starting, timer finished, and resetting. The code is attached below.
Downloads
Supplies
All of the necessary components can be found in an Arduino starter kit:
- Arduino Uno
this is the microcontroller that I programmed and connected all of the electric components to for the timer to function. I believe the Arduino Nano will also work.
- Arduino IDE
An IDE (Integrated Development Environment) is where the code is written, and the Arduino IDE is specifically made for Arduino Microcontrollers
- Button
Connected in a way so that it sends a value HIGH or LOW which can be used within my program.
- Piezo Buzzer
Can be programmed to make a sound at a certain frequency and duration.
- LCD
Used to display the time.
- Resistor, Jumper Wires, and Breadboard
For connecting components, and preventing them from overvolting
Brainstorming
I thought about what components I might need to build this timer, and how I would go about it. I knew I would need an LCD screen to display the time, and that I would use a potentiometer to set the time. I also would need to add buttons for features such as starting the timer, stopping the timer, and resetting it. To notify the user when the timer is done, I would also need to add a buzzer. I then got to work and connected all of my components.
Wiring
The wiring is a bit complicated, which is why I included the wiring schematic, and I made an organized wiring diagram with on TinkerCad.
Downloads
Coding
This was probably the most time-consuming part of the project. It's easy to hook up components but programming them to do what you want is a whole different story.
I won't be going over every aspect of the code, but I will be going over the important parts or ones that took me the most amount of time to figure out.
void displayTimeLCD(){
time = analogRead(potPin);
time = map(time,1023,0,0,400);
minutes = time/60;
seconds = time%60;
lcd.setCursor(0, 0); //time display code min:sec
lcd.print(minutes); //time display code min:sec
lcd.setCursor(1,0); //time display code min:sec
lcd.print(":"); //time display code min:sec
lcd.setCursor(2,0); //time display code min:sec
if(seconds%5 == 0) //time display code min:sec
{
lcd.print(seconds); //time display code min:sec
}
lcd.setCursor(0,2);
lcd.print("VIC'S TIMER");
}
So this function, displayTimeLCD() is where I set the values for the timer which are then displayed on the LCD. I store the value read from the potentiometer into the variable time which is then put into the function, map(). This function basically scales a set of numbers to another set of numbers. In this case, since the potentiometer gives a set of values from 0 to 1023, I mapped this set to a set of values from 0 to 400 to get a smaller set of values as I don't really need a timer to go to 1023 seconds.
The variable time represents how many total seconds the timer is set to. To convert this value into minutes and seconds, I used two operators, division and modulo. Dividing time by 60 gives the number of minutes, and taking the time modulo 60, gives the number of seconds. If you're curious on how the modulo operator works, the link below gives a pretty good explanation as to what it does.
The following code of LCD functions displays the time in a mm:ss format.
Coding Cont.
void startTimerSequence() {
lcd.clear();
tone(buzzerPin,85,100);
lcd.setCursor(0,1);
lcd.print("STARTED");
seconds = ((seconds+2)/5)*5; //rounds time to nearest multiple of 5
timeStarted = millis()/1000;
state = 1;
}
This function is called when the button to start the timer is pressed. The buzzer beeps and the code below rounds the seconds to the nearest multiple of 5, which is more useful for its application, cooking food. The variable timeStarted is used to mark when the timer was started based on the internal timer of the microcontroller, which will be used in the next portion of code. I used a state system in my program which has different portions of code which only run when the state is set to a certain value.
while(state == 1) {
while(minutes > -1) {
lcd.setCursor(0,0);
lcd.print(minutes);
lcd.setCursor(2,0);
lcd.setCursor(1,0); //time display code min:sec
lcd.print(":");
timeLeft = seconds - ((millis()/1000)-timeStarted);
// above is: seconds in timer - seconds since timer started
if(timeLeft<10) {//to display leading zeroes
lcd.print("0");
lcd.setCursor(3,0);
}
lcd.print(timeLeft); //prints to LCD & Serial to check accuracy
Serial.println(timeLeft); //prints to LCD & Serial to check accuracy
// if(digitalRead(pausePin) == HIGH)
// {
// tone(buzzerPin,85,100);
// state = 2;
// break;
// }
if(timeLeft == 0) {
minutes--;
seconds = 59;
timeStarted = millis()/1000;
}
}
timerFinished();
}
This is the code for the timer countdown. The variable timeLeft counts how many seconds are left in the timer. It took a while to figure out how to write this part, but writing the pseudocode helped me develop my thoughts. The commented-out parts was me trying to write code that stops the timer when another button is pressed, but I was unsuccessful. After the timer runs out, the function timerFinished() is executed.
void timerFinished() {
lcd.clear();
lcd.setCursor(0,1);
lcd.print("FINISHED");
state=2;
while(state==2) {
for(int i=0;i<3;i++)
{
tone(buzzerPin,85,200);
delay(500);
if(digitalRead(dismissPin) == HIGH)
{
tone(buzzerPin,85,100);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("TIMER RESET");
delay(1000);
lcd.clear();
state=0;
break;
}
}
delay(500);
}
}
In this function, the state is switched to the 2nd state, which executes the finished timer code. The buzzer beeps three times per second, similar to how the one at my job beeps. It keeps beeping until the dismiss button is pressed, then it exits the loop and resets the timer so a new timer can be started.
Video
Here is a video of the timer working
Conclusion
Overall, it was a very fun project. I learned how to use an LCD screen and its functions, learned the map() function, and utilized a buzzer for the first time. Though I had some issues making the timer code, it eventually worked out which was very satisfying. Some plans I have for the future is making a custom PCB for this device, so I can get some first-time experience with PCB design and have a circuit with stronger connections (the jumper wires led to some jumps in the potentiometer values that were read). I want to add a start and stop feature as well, so if anyone has advice for how I can go about that it would be greatly appreciated. I would also like to use better buttons (Keyboard Switches) and get a better potentiometer or possibly replace it with a rotary encoder instead to better replicate how the timer at my workplace functions. I could use an OLED instead of the LCD screen for a cleaner display. After all, this is only a prototype, and there is so much more I can do with this. I just wanted to show the process that I went through to develop this before I turn it into a final product. It was fun working with electronics since I don't do it very often, but I have a lot of good ideas for future projects that utilize them, so make sure to follow!