DIGITAL ARDUINO CLOCK WITH ANIMATION – Arduino project

DIGITAL ARDUINO CLOCK WITH ANIMATION – Arduino project


in this tutorial we’re going to create a
digital clock we have a mode-button where you can set if you want to change
the hours, the minutes and the seconds and as you can see I change it with a
set-button and if we wait for 5 seconds and do nothing
the clock will resume its normal operation I’ve split this tutorial in two parts we start with a very easy clock where the green button adjusts the hours and the
blue button adjusts the minutes in the second, more advanced part, we’re going to
create the menu you just saw on top of this clock there’s a tiny animation
and I’m also show you how to create this in the description of this video you find a chapter list so you can jump to the chapter of your
preference However, I advise you to follow the complete tutorial so you can learn from my mistakes
and build this clock step-by-step for this tutorial you’ll need several components
an Arduino, a breadboard an OLED display, two push buttons
and 9 jumper wires male-to-male in the description of this video you find links
to web shop selling these components every project starts with a plan and I also receive questions like:
how can I do this project I don’t know where to start I want to build this and that and I know what I want but I don’t know how to
split it up and create this project on my Arduino so therefore I have a small
presentation to show you how I created this clock if you don’t like this, then you can in the description find all the chapters with timestamps and you can directly skip to building the circuit however I advise you to watch this tiny
presentation because you can learn how to structure your project our clock’s main function is to display time we want to display hours, minutes and maybe seconds but we also need to adjust the time so we want to adjust the hours
minutes and even seconds so how can we do this? we can use a single button and
this button increases a minute every time it’s being pressed but there’s a tiny problem with this imagine the clock is just 1 minute behind then you have to
press once and you’re done but what if it is running 1 minute too fast? then you have to press it 720 times
if it’s a 12-hour clock and even 1440 times if
this is a 24-hour clock so that’s not very useful so we can add another button
so we have two buttons an hours button, which change the hours and a minute button which change the minutes we might even have to have to add a third button
because we also like to reset the seconds there is no use to setting the seconds
to a certain position like 39 so you want to reset it to zero
the moment your seconds need to hit zero after you thought about these solutions
then you have to think in components so we’d like to display the time therefore we need a display and we need two buttons: one for the hours
and one for the minutes and maybe a third one if you want to reset the seconds then you have to think about
how this could look when you design your clock so, this might be a clock it shows the time we have our hours button and our minutes button and on the top you see two bars that’s an animation and that’s what
we’re going to make I’ve split this up in 5 steps first we’re going to build a clock with delay() then we’re going to build a clock using millis() then we’re going to add an animation then we’re going to add a debounce to the buttons
I’ll explain in that chapter what that means and last we’re going to add
interrupts to the buttons in the second part of this tutorial
we’re going to look into the clock as you saw just saw in the demonstration our first step is to add the OLED
display to the center of our breadboard make sure there is enough space to add
two buttons later also keep in mind during this tutorial, that your pin
layout of the OLED display might differ for example the “serial data pin” and the
“serial clock pin” might be on a different position it doesn’t matter for your clock
but you have to keep in mind to use the correct pins when you’re
connecting these to your Arduino our next step is to add two buttons make sure that they overlap this tiny gap in the middle
of your breadboard we’re now going to make our ground connections all pins in this blue line are connected
with each other so we’re going to connect the right pin of
the green and the blue button to this rail via this wire and the other black wire our display has a GND connection which is also connected to the same horizontal rail
on our breadboard We’re now going to connect the wires to our Arduino the first wire is the ground which goes from here from the – rail to the ground on
our Arduino the red wire goes to the 5V of the Arduino it is connected to the VCC of our display the yellow wire is the serial clock
which goes to A5 on the Arduino and the serial data which goes to A4 on the Arduino the last step is to connect the blue button via the blue wire to pin number 2 and the green button via the white wire to
pin number 3 on the Arduino now that we finished our circuit we can now have a look at the code if we look at the libraries
we’re only using one that’s the U8g2 library so I’m going to tools ->manage libraries then we’re going to search for U8g2 and then you see here U8g2 by Oliver I already have installed this library
but you can install it if you haven’t already then we continue, we have 3 different variables the maximum number of hours is 24,
actually 23: 0 to 24 so 24 values so a byte is sufficient to store these the same goes for minutes and the
seconds then we have two constants defined:
two integers for the PIN_BUTTON_HOURS and PIN_BUTTON_MINUTES and then we also have two states so the state for the button hours
and for the minutes button and they’re both HIGH
and as I showed you here in this note it actually is a counter intuitive thing
because you think when I press the button it’s HIGH and when I release the
button it’s LOW but we’re using this input pull up here on line 62 I’ll show you that in a minute but then because of the pull up when there is no
button pressed the value is HIGH and when you press it becomes LOW then we have here on line 54
a timeString with 9 positions and that’s basically used to store
the string which we are going to show on the screen and that’s something I show you as well when we’re going to the printing / drawing function here we define our screen for the U8g2 library,
with all the pins and this is for my SSD1306 display but if you have a different display on
this website from Olli Kraus you can see exactly which one you need then we continue to the setup()
where we set the PIN_BUTTON_HOURS which we have defined over here
which in pin number 3 and we enable the input pull-up
so that’s the pull-up resistor which is built-in in your Arduino
the same for the minutes then we use the U8g2 object and say “setFont” so we change the default font of the U8g2 library into “logisoso28” and that font
exactly fits into my screen you can you can look at the U8g2 website for other fonts
but this one with the size of 28 fits perfectly when we’re showing the time then we tell U8g2 that we’re
ready with the configuration and it can begin in the loop() we check if the button has been pressed so we store the current
state of the button of the hour button in with the digitalRead and store it in
the buttonHourState and we check if it’s LOW
if it’s LOW we increase the number of hours same for the minutes, so if the buttonMinutsState is LOW then we increase the minutes and then we have several checks
because if we have more than 59 seconds it means 1 minute has been passed so on line 85, we reset the number of seconds
and increase the minutes the same we do for the the minutes and the same do we do for the hours
to see if a day has elapsed the trick is that we first need
to check the seconds, then the minutes then the hours, if you do it the other
way around it doesn’t work very well because if we increase here the minutes
we need to check if we already go past the 59 and if you do the
opposite then you can have 60 seconds then we tell U8g2 to draw the first page
that’s the way U8g2 works and then you have a do-while loop and it repeats
until there is no next page anymore on line 107 we see something new it’s sprint_P() maybe you know, sprintf() is for
formatted strings to print but the trick here with the underscore P is that we use program memory instead of RAM RAM is a very sparse thing on the Arduino
so if you can use program memory we reduce the load on the RAM well what we do is when you see PSTR that means Pointer to STRing
so what we do is this string we are converting it to a pointer and we store the formatted string into the variable timeString this looks a little bit odd but what it is is that we say here:
two decimals then we use the colon and then we use %02d so here there is no zero
and here is %02d that means that we’re adding a leading zero so it
becomes 01, 02, 03 till we are at 10 and the same goes here for the seconds so
here we define how our string looks on the screen and we store it into the timeString
then we draw the string on the screen so we print it on x position 0
y position 45 and we’re drawing the timeString then we wait for a second and
increase the seconds and then the whole loop starts again I’m now going to upload this code to my Arduino
and show you what it looks like I’ve uploaded code to my Arduino and as you can see
the clock is working so let’s adjust the hours by pressing the green button that’s not very easy to do and if I press the minute button it’s also very hard
to increase the minutes by one so what is causing this? well the reason for this is we are using delay delay doesn’t wait for several milliseconds delay just pauses the whole processor
for several milliseconds so what’s so what’s happening is that because we’re pausing the whole processor for one second it is fairly hard to detect if a button is pressed you have to exactly press the button at
the right moment in order to increase the hours or the minutes that’s not very useful for our clock so we’re going to solve this by using millis() so let’s have a look at a millis() code well, the begin is all the same but here on line 58 there is a new variable I’ve created an “unsigned long” in which I store the current millis so the amount of milliseconds elapsed
since the Arduino was started then we have an another variable
that’s the elapsedTimeUpdateMillis basically what it does is to store
the amount of time elapsed since the last time the screen was updated then we have an unsigned long:
lastTimeUpdateMillis and that’s the timestamp when we
did the last update of our screen then we have the constructor for the U8g2
which is the same as in the previous example the setup() is the same
but in the loop() there’s something new here on line 83 we update the currentMillis variable
with the current amount of millis elapsed you can also take into account that
millis() itself also takes some time and I looked it up and I found this website on line 82 and they showed that it takes 1.812 micro seconds so that’s 0.001812 milli seconds I’ll leave it for now
but you can take it into into account if you want to then we’re going to calculate the amount of time elapsed since the last time update on the screen so we take the current timestamp and subtract
the last time we updated our screen then we check if the buttons are pressed we check if there are minutes
and hours and seconds which we need to update but for the millis line 118 is interesting
because there is no delay() so we need to check if there is enough
time passed so here we check if the elapsed time between
two updates is more than 1000ms if so, we increase it with one and then we update the lastTimeUpdateMillis
with the current timestamp but there’s something which I’d like to
explain to you first I thought that this would be suffice so I just stored the current timestamp and I’m done but what I noticed is that sometimes it takes
more than 1000ms to update the screen so what happens is that it’s not exactly on the millisecond cycling of the loop() function so if the loop execution takes exactly 100ms then on 1000 is not larger than 1000 so then you have like 100ms in the next iteration
which makes it 1100 and then you can’t do anything with that 100ms
which you are to late so let’s say I have 1200ms in my elapsedTimeUpdateMillis so this if statement is TRUE
so update the seconds updated with the timestamp
so far so good but I’m already missing 200ms because I updated timestamp with the currentTime so that is 1200 but this was saving my trouble with the time drift because I now subtract the elapsedTimeUpdateMillis so in this example 1200 minus the 1000
which is 200 so what happens is that the lastUpdateMillis
will be the correct timestamp so it only takes 800ms for the next second
to update and saves us a lot of time drift so you have to maybe re-read this and just read the code a little bit slower for yourself
to understand this but basically what we do is
we want to avoid time drift as much as possible because it will slow down of speed up
the clock this is all the same as we had in the previous example so I’m now going to upload this code
to my Arduino and show you what it looks like I’ve uploaded the millis() sketch and we’re now going to see what happens
if you press the button for the hours so I can now easily adjust the hours and also
the minutes are working so now we’re going one step further and we’re going
to add animation to our clock the animation is quite simple we
basically draw a bar and this bar shows you the percentage of the seconds
elapsed so we need to add another variable and that’s here on line 65
and it’s the percentage of second elapsed that’s zero and the nice thing about this animation is that it needs to be updated as fast as possible because if we wait for one full second then every time a second has elapsed so this
value is zero so you won’t see any bar graph so what I did: I added here two
lines, sorry no I’m too fast, here on line 130 we calculate the percentage of
seconds elapsed so we take the elapsedTimeUpdateMillis
and divide it by 1000.0 why this point 0? well then it becomes a floating
point and with the division you want to have a
floating point as a result then we use this percentage because the percentage it will be 1 for a 100% 0.5 for 50% so we can use that to draw a bar and our screen is 128px
width so we have 128 values: 0-127 so that’s the complete width of the screen so we first draw this box on line 137 which is on x0 y0 then we have a width and the height so the width is 127 minus 127 multiplied by our percentage and the height of the bar is 2 the second bar is drawn at a Y of 3 so the
height was 2 from the first one so there’s one pixel line as a separator
and we do now the 127 times the percentage of seconds elapsed
with a height of 2 so basically they are the opposite of
each other all the other lines are still the same so I’m now going to show
you how this animation looks on your Arduino as you can see our animation is
working you see the yellow bars on top moving from left to right
also the hour button is still working and the minute button works as well there is one tiny thing what we like to fix if I hold down for example the minute button
the screen is kind of flickering the reason for this is that the update speed
of the minutes depends on the speed of the Arduino we’re going to solve this by a so called
debounce and I’m going to show you how this works so let’s add some debounce to our buttons
and with debounce we’re kind of controlling the way the button responds
independent of the speed of the Arduino so what we did was we defined a constant
here which is the DEBOUNCE_TIME a hundred means that a button will be
triggered at most every 100ms so even if I press it twice during 100ms
the button will only be triggered once so for every button we need to define the
elapsed button millis and the previous button millis and we have that for the hours and here
for the minutes so what we check is, we store in this variable how much time has elapsed since the last time I pressed the button and this is the timestamp for the last time the button was pressed and these are both unsigned long
since you might want to adjust the time while the clock has been running
for many times so then integer is definitely not enough so then we’re going to our code where we do the calculation so this is still the
same we store millis() in the currentMillis but here we calculate
the elapsed time update, button hour millis and the button minute millis because if the elapsed time is larger than the button debounce time then we
can check if the button has been pressed if not, we don’t have to check it because
we can’t trigger a button two times within the debounce time so then we read our button state but we also update the previousButtonHoursMillis with the
current timestamp and the same goes for the minutes over here then we again check if seconds is larger than 59 minutes, hours, all the same also here the
percentage calculation is all the same so nothing changes at
except that we now checks if the elapsedButtonMillis is larger than the
BUTTON_DEBOUNCE_TIME so I’m now going to upload this code to my Arduino
and show you how this works I’ve uploaded my debounce sketch to the our Dino and when
I hold my in minute button you see that the minutes will increase at a steady
speed this is because we added the debounce to our minute increase button
we’re now going a step further by using interrupts so let’s have a look at interrupts maybe
you’ve already followed one of my tutorials on buttons and interrupts but
I’m going to briefly introduce this to you again so one of the things we want
to do with interrupts is attach them to our pins and that’s something we do over
here on line 84 so we have an interrupt and that means that we don’t have to
check all the time if a button is pressed what happens is that the
interrupt as a name says will interrupt the program on a certain condition so
what we say here is we say falling and that means that when we press the button
the interrupt will be triggered and the interrupt is actually a function so the
function hours both impressed interrupts will be triggered if the pin button
hours will be falling you also have rising that’s when the
button is released and you have also change with chains is another thing we
want because if you press the button it will be triggered and then when you
release the button it will be triggered again so you can never increase by one
it will always be triggered twice so then we have some weird flags over here
and that’s because when I ran into us when I started my Rd now it wasn’t
showing all zeros what I was showing was 140 hours and 140 minutes and it turned
out that there were still some interrupt triggers left in the queue and therefore
on startup they were triggered but the problem was that I don’t want them to be
triggered only when I press the button and the trick was that you can clear the
cue when using these command commands here on line 95 and 96 keep in mind that
only Rd know you know there are only two pins which allow interrupts and that’s
been – and pin three so if you use for example pin nine and ten you can’t use
interrupts on these pins if you have a different type of Rd know for example
Omega has a lot more which interrupts so keep that in mind
because otherwise it can take a while until you understand you figure out that
there is no interrupt on the pins you’re using so I split it up my code a little
bit as you can see here also with a function draw screen on the end and draw
screen does nothing else than all the draw methods we already had but for us
here these are interesting this is the our button pressed interrupt so it will
be triggered when we press that button and this is the same code as we had in a
previous example but now moved to a function this is for the example but
normally you want to make your interrupt function as small as possible so
basically what you want is increase the hours and only increase the minutes and
all the checks you want outside of the function of your interrupt but for this
tutorial purpose I just put it over here so you better understand what’s going on
so I’m now going to upload these codes to the Arduino and show you how the
button works with interrupts so this is our running sketch on your Dino with our
interrupt code as you can see I can still change the hours and the minutes
one big difference with the last sketch is that I can when I press and hold down
the minutes button it only increases once this is because the interrupt is
triggered but you have to release the button until you can trigger it again in
a spring feast sketch the triggering was read in the loop so it checks
continuously whether or not you have pressed the button this concludes the
first clock we’re now going to continue with the second clock where we’re going
to use the mode and set buttons in the second part we’re going to make a
clock which is using a mode and set button the advantage of this is that
it’s a very versatile you can add multiple modes without having to add
another button so how does this mode button works well the clock starts by
displaying the time and when you press the button you can adjust the hours then
the minutes you can reset the seconds and if you press the mode button again
it starts by displaying the time when you press the button again it goes to
hours minutes etc the set button changes time depending on the mode you’re in
so in the hours mode you can change the hours in the minutes mode you can change
the minutes and in the second mode you can reset the seconds so this is what it
looks like you have an animation running like in the previous clock you have a
time you have a mode you have a set button but that’s one different thing
you have a position marker this position marker indicates what you are changing
so here you are changing the hours the minutes or the seconds in the next steps
we’re going to implement first a mode set clock without interrupts and
secondly we’re going to create a clock with interrupts I’m going to show you
how we can do this so we’re going to create a clock which
has a mode button and a set button the structure is basically the same as a
previous clock but there are some differences for example I’ve renamed all
the our buttons to the mode button and all the minutes buttons to the set
button so we also have new D bounds here I’ve separated the mode and a set button
with different debounce times and here you also see some constants defining the
modes so I have a mode to show the time and mode to set the seconds the minutes
and the hours so in the background I’m using just numbers for this but it’s a
lot easier to read the code when there is this name instead of saying mode is
zero you have no clue but 0s so we need a variable to store the current node
that’s here on line 78 I don’t use it int because about is sufficient we only
have four numbers to stores 0 1 2 & 3 so this setup remains the same and here on
line 100 we read the state of the pin button mode and check if this one is low
and then we activate the button mode handler function and the same goes for
this set button then we call the set handler we check the time that’s another
function and the check time is here just to check if there’s a minute elapsed an
hour elapsed or a day elapsed and here is something new because here we check
if the current modish show time and if so then we increase the seconds and
increase seconds is here at the bottom we check if the time has elapsed and
then we update the previous time millets etc I’ve told this in the previous
example so then we if it’s not in the show time mode so basically we’re
setting a value for the hours the minutes or the seconds then it just
updates the previous time update nearly with the current release
it draws the screen so let’s have a look at these handlers well for the motor is
very simple what we do we if the demands time has elapsed of course we increment
the current mode so if you are in multi row which is showing the time you do
plus plus which is the same as plus one so then we are having the set hours etc
but there is no fourth mode the highest mode you can have is mode number three
so if we reach the four because the previous was three so now with current
mode is four then we reset it back to zero and in that way you can press the
mode button all the time and just iterate over the four modes we’re having
the set button does something more because the set button works depending
on the modes you’re in so what we do is we check if the current mode is set
seconds and if so we reset the seconds but if the current mode is minutes then
we increase the minutes and if the career mode is hours we increase the
hours if you want to set an alarm for example you create a custom mode for
that then you can add another if checking if the mode is set alarm or
stopwatch or whatever so let’s have a look at the draw screen function here
because I’ve changed something as well if the current mode is not show time
that means were setting the hours the minutes or the seconds so what we do we
need to draw a triangle and a triangle indicates if we’re setting the hours
minutes or seconds so if you’re setting for example the minutes there’s a tiny
triangle on top of the minute number so you know you’re changing that value so
you see a lot of numbers here and I’m going to explain to you what they mean
so first here this is the first number this is the x position and the x
position is the current it’s minus one sorry for emote number
one it’s zero and in mode number three it’s two and we’re doing this because
I’ve splitted the screen in three parts so I want depending on the mode draw the
triangle on a third of the screen so here I’m multiplying the current mode
minus one times 43 so if I’m in mode one minus one is zero times 43 plus five is
five and the thing is that this 43 is a third of 128 and I can choose float
numbers so I made it this way and five is some kind of Martian I don’t want the
triangles to exactly be one third of the screen I wanted one third of the screen
minus five pixels on both sides the Y position is zero so that’s a four first
most left point of the triangle but what we then do is we take the current mode
and here we did minus one here we don’t the x 43 minus five so that’s our top
right point of the triangle and it’s on Y position zero so now actually we’ve
drawn if you draw a line between those two points we draw a horizontal line so
if you look a little bit further then you see here the current mode minus one
times 43 so this is the same as over here but I add 21 and why do I add 21
because we if we divide 43 divided by 2 then you get a floating point number and
that’s not what we want so I create an integer and that’s the center between
our first two points but instead of using an Y of zero I use a Y of five so
now we have a triangle with two points one point in the center which is 5
pixels offset from the to what you can do is fill her around
with these numbers to see how this draw triangle exactly works because now I’m
telling you it in the code and it’s very theoretical but if you change the
numbers you’ll see for yourself what happens that’s basically the whole code
for this clock so I’m going to upload this to me our Dino and I show you what
it looks like so our mode and set code is running on
your Dino with the milk button I can change between hours
minutes and seconds so let’s start by adjusting the hours so I select hours
and I can increase it with my set button the same goes for the minutes and I can
also reset the seconds when I press the button the mode button again it goes
back to time and you see the seconds are increasing so our clock is running again
I’m now going to show you how to implement this clock with using
interrupts and we’re even going to use a timeout so we’re going one step further and
we’re going to use the interrupts and it timeouts it’s not very hard because we
already made the first clock which and interrupts so what changed is that here
we have now interrupts clear flags as you can see so we clear the queue again
as in the previous example and we add touch to interrupts here and when the
mode is pressed we call the function mode button pressed interrupts and for
the set button the set button pressed interrupts so if we have a look at the
code of these interrupts of interrupts functions you see here for the mote
pressed interrupts we say button mode press is true and here you see button
set press is true I like to keep these as light as possible and with that I
mean as dump as possible so this one is only setting a variable to true and
that’s basically it you want to keep your interrupts functions as clear clean
as possible but there’s this special thing here the remote press is a special
variable if you scroll a little bit up here you see bitter mode press per to
disable Yin but here you see any word of volatile and volatile means that you can
use it in the loop function and in the interrupts if I didn’t add volatile to
this variable what could happen is that a function in the loop is actually
modifying little more pressed and at the same time I press the button which
raises an interest and then you can you can have some kind of what they call
race conditions and stuff and does solve with volatile if you want to know more
about volatile google it there’s a lot of information out there so I kept it
quite dump because here I check if the built-in mode press is true and if so
I’m calling the mode button handler so in my previous clock I had all this code
inside the interrupt which isn’t the best way to do so but
was easy for the tutorial but now we’re going to ride more clean coats so and
moved it into these functions and as you can see this is exactly the same code as
we had before except for this line because I set button mode pressed back
to false and the same goes with the set button here button set pressed goes back
to false so there’s one more thing and that is the time out so Whitney time out
we’re going to show the time if we don’t do something for quite some time and
that time is defined over here in line 53 is the most set time out so basically
we wait 500 milliseconds of 5 seconds and if you don’t do anything for 5
seconds while setting the hours the minutes or the seconds it will return to
displaying the time so how does this work
well we already kept for the D balance the time since I want to show you the
timestamp since we pressed the button for the last time
so what I do here it’s actually very easy on line 125 here we check in two
parts if the in lapse button mode Milly’s is larger than this five seconds
then this 5000 and the same here for the set button so if we haven’t pressed the
mode button and the set button for the period of time the fighting mode set
timeout and then the current mode becomes shim mode show time so it shows
the time you can fiddle around with this as well because you can also say well
you have to wait for 10 seconds and then I want to show editing as setting the
hours you can change it to whatever you want but that’s how it this works so
actually it’s very easy because we already kept the time when we press the
button so you just have to see if it’s want you then our timeout so that is
basically the code I’m now going to send this to my Arduino and show you how the
timeout looks when it’s running on our Dena
so our code is running again on the Arduino and nothing has changed you can
still select the different motifs so I can adjust the hours the minutes reset
the seconds but there’s one big difference if I’m going to edit the time
and wait for 5 seconds then you’ll see is resume showing the time automatically
and this is exactly as we configured in our code we define that if a certain
amount of milliseconds it laughs it will go back to its default mode which is
showing the time this concludes the tutorial on this
digital clock you have learned why you shouldn’t use delay and how you can use
Milly’s to solve the problems with delay how to add your own animation how to use
debounce on the buttons how to use interrupts and how you can use the
several modes so you only need to use two buttons you can easily extend this
clock by adding new modes for example for alarm or stopwatch you can also use
a real-time clock to make the clock more accurate there are many things that you
can think of and just I encourage you to experiment with this clock if you have
any questions feel free to drop them in the comments and in the description of
this video you’ll find a link to the course material the circuit schema and a
shopping list with all the parts used in this tutorial I see you in the next
video

Leave a Reply

Your email address will not be published. Required fields are marked *