(soft intro music)
- Welcome to the fifth PIC18F14K50 tutorial
based in the C language.
We will be learning about buttons today.
And in the previous tutorial we learned how to do a button,
how to make one work from scratch.
And now we are going to be learning about how to do it
with the MPLAB Code Configurator or the MCC.
So this is gonna have a lot of overlap from tutorial four.
So if you've already watched tutorial four
you're gonna get some repeated information,
which is fantastic.
It's always good to hear something again
and get it hopefully in a slightly different way
to help cement it in the brain.
Otherwise, our approach to the program itself
is going to be slightly different
because we're going to be using that visual configurator
versus doing everything from scratch.
With that, let's start out with the first thing
and conceptually, I wanna go over a brief topic
that you may already be aware of
or you may have heard in the previous tutorial
and that is a weak pull-up or a pull-up resistor.
Now in this system
we will have the internal weak pull-up resistor
of the microcontroller on our input.
And if you don't know what a pull-up resistor is
all it does is it takes an input
that has perhaps a floating voltage
and ties it weakly to power, to VCC.
And it does this so that if it's not connected to anything
it could float and you don't ever want that.
So you just want to pull it up to either ground or VCC.
And it's typically high to VCC,
but you don't wanna tie it so hard.
You don't want to directly tie it to VCC
that you can't change it.
So right now with what we're doing here
is we're going to have the output, or excuse me, the input
connected through the internal resistor that ties it to VCC.
So whenever nothing is acting on it, it will read high,
but then with the button will short it to ground
and draw immediately to ground if necessary.
And that's one of those things
where you want your pull-up resistor
to be a large enough value
that when you are tying it to ground
that you're not drawing a lot of current
straight from VCC through that resistor,
but you also don't want it so big or such a large resistance
that it doesn't really tie it to VCC strongly enough.
So we'll see that in action here,
but I just wanted to conceptually go over the concept
of a weak pull-up resistor
because we will be dealing with that in this circuit.
So with that, we will be taking this button
and we will make it so when we push the button
the light turns on, push the button to light turns off.
And if you have this set up from tutorials two or three.
then it's a very quick addition of a single button.
And if you are going from tutorial four
it should already be set up.
But the main goal of what we're doing here
is just making it so when we push that button,
this LED turns on, push it again, it turns off.
So very straightforward.
Let's go over the schematic really briefly
so that you can see exactly how it's connected
so you aren't just hearing what I'm saying.
And then we'll go over the configuration itself
before going over the code we need to create
and then we'll see it in action.
So as you look at schematics diagram,
you can see once again
that all we have is the PICkit 4 connected.
We have our resistor in series with our LED
connected to the same pin, RC0,
and all we've added is on pin 11, which is RB6,
part of port B is a switch that is tied directly to ground.
Now if we didn't have the internal pull-up resistor,
you wouldn't want that.
You'd have to have a slightly different configuration.
But because we do, we can tie it directly to ground.
And as I mentioned, that is all we need for the schematics.
It's very, very straightforward.
So with that, let's jump straight
into the MCC configuration.
I've already created the project
and change the settings to power the circuit
from the PICkit 4.
So we're just going to assume
that you're already to that point,
we went over that in projects or in tutorials two and three.
If you don't remember how to do that
you can go check it out.
Otherwise, we'll just go to the point
where we open up the MCC and configure it
so that we can have both the input of the button
and the output of the LED.
So we are here and we go up and we hit the MCC button.
And this seems to take a little bit of time.
So if it doesn't seem like it's doing anything,
just have patience.
Maybe you have a faster computer than me and it goes better
or if you have a worse one, takes even longer, who knows.
But just be patient, it is working.
We will select the MCC Classic as gen as before
and we still don't need any of this optional content.
So we can just hit finish
and it will generate the layout for us.
All right, there we go.
And finally it popped up.
First things first, so I don't forget,
let's change our package over to a DIP
or if you have a different package
use that different package.
And then our internal oscillator is all good.
The system clock is all good, everything here is still good.
We don't need to change anything.
We just need to get rid
of the low voltage programming enable.
Now we need to make sure that we have our RC0
set up as an output and our RB6 on pin 11 as an input.
So we can go to and you can look at it
as either the pin number or the port, however you want.
So let's just do RC0 and set that as an output
and then Port B six and set that as an input.
There we go.
So now that we've done that
we can go to our pin module and we can change the names.
So this is clear IO_RB6 isn't super clear.
So let's just call this input.
And then our RC0 will be our LED.
Actually, let's just call this button.
I think that's the name I use.
And then as before, RC0 is not analog output
so let's get rid of that.
But we do wanna keep it as an output
because it is an output and we don't need to worry
about the starting high.
On the button we don't care.
It's gonna be tied to VCC anyway by going over here
to the WPU, the weak pull-up, and we want to select that.
And then we will need to make sure
that we enable the RABPU bit from the register view as well.
See, it's nice.
It gives you that little warning right there.
So let's scooch over a little bit to the right.
Make sure there's nothing else we care about.
There's the interrupt.
So we could set it up and later we will set it up
in a later tutorial so that this triggers an interrupt.
But right now we're not doing that.
So let's switch over to the registers view
and look at all these things we can do with the registers.
In this case, we just want to go here to the nRABPU,
which I talked about more in depth in the previous tutorial.
But basically this is just saying that, well, first of all
that n means you invert whatever it is.
So this particular bit is active low.
Of course it says here disabled or enabled.
So you're not dealing in terms of zero or one.
Makes it a little bit more clear,
but if you did have to manually control this bit
you would put it as zero to enable it versus one.
And that's all that n is saying right there.
And then the RA and the B actually is talking about port A
and port B, and then PU is pull-up.
So that's basically saying that for all of port A
and port B, you are allowing those pull-ups to be used.
So that's the global place that you can turn on
or off all of the pull-ups.
Or you can go, as we did under the easy setup pin module
change each pin individually for the weak pull-up.
And really that's all we need to do to get this set up.
I just double checked, everything looks good to go.
So let's just hit generate
and it will create everything that we need to get started.
Once it says info generation complete, it is done.
I just keep on waiting for it
to automatically change the views.
It's not going to.
So I need to go to projects, and again,
I can verify that my header files have been created
and I can look at my source files.
So let's open up main.c
and we get all of this just annoying stuff.
So I'm going to delete all of the comments
because I don't like them.
So we are just going to add our application code
right in here and we will be good to go.
So now I've inserted the code that Sergey has provided us
and it basically starts out with the main function
that we jump straight into the system initialize.
And the system initialize you can find out what's going on
by reviewing the MCC generated file.
So if you're interested
in what's going on behind the scenes, you can look in there,
but it's basically just the configuration bits.
And then we jump into this while loop.
So while one basically means that for and ever
we are going to be running this.
We will go and we will, basically, if nothing happens
that while one will be doing the if button get value
equals equals zero, and if it does not equal zero,
then it just asks again
and it asks again over and over and over again.
And again, remember that when this switch is not depressed
it's going to be reading a one.
So when you push the button, then it'll read a zero
and then this if statement becomes true.
So in line 10, if button get value equals zero,
then you go into that and you jump directly to a delay.
So why would you want a delay immediately
after seeing the button has been pushed?
Well, if you have any experience
with switches or microcontrollers or whatever,
you can know that you get some spurious noise sometimes
and that most transitions are not that clean.
That when you push the button instead,
in this case of it going from one to zero
as a perfect drop-off, it usually drops,
bounces a couple of times and then levels off.
And that's why you have what's called a debounce.
And this can be done in hardware
with like a capacitor resistor,
or you can do it in software like this
where basically you say, hey, I'm reading a zero.
Let's wait 20 milliseconds, in this case,
to see if it stays at zero.
And if it does, then we know it was intentional,
not just some random noise
or that it went because these are fast enough
it can say, oh, push the button.
Oh, nevermind.
Oh yes, he is, and it'll flicker a whole bunch of times.
And so this just cleans up the noise of that switch
being pushed and removes that bouncing effect
via a debounce.
So that is all that is happening
with that delay is that in number 10 you check,
oh, hey, it's dropped to zero.
In line 12, you wait 20 milliseconds
and then in 13 you check again
to make sure that the value is still zero.
So in line 15 you have a while button get value
equals equals zero.
And as long as you're holding onto that button,
you stay in this infinite wild loop
and it just sits there checking, checking,
over and over and over and over again.
And not until you release it and you get a one
and that no longer becomes true,
then you jump out and go to line 16
where you do another delay for 20 milliseconds.
And again, that 20 millisecond delay is for a debounce.
That's same thing going from one to zero.
You're gonna have that same problem going from zero to one.
So that is all we're doing.
And in line 17, it's doing that second check
after the 20 millisecond delay to make certain
that it's acting the way it's supposed to be doing
and also getting rid of any spurious signals
that you don't want.
And finally, finally, after all of that
when you've released it, you go to line 19,
which instead of doing the XOR
and all that complicated stuff
you just do LED toggle and it toggles.
As you can see in the pin manager that we have named it LED.
So that's why it's LED_toggle.
If we were to name that blinky LED,
then it would need to be blinky LED toggle.
And the same with button.
It says button get value, but if we did something else
you would have to change that.
So if you do decide, hey, LED and button is too boring
when you're doing yours
just realize you will need to change the code as well
to make those match
or else you're going to have some problems.
And that's really it in terms of the software.
The only thing I would like to point out
is that this is considered a blocking routine.
So what that means is it blocks all other code
from running on the CPU.
It literally does nothing,
but checks the state of the button
or turns the LED on and off.
You can't fit anything else in there.
And this is incredibly inefficient,
but if this is all you need to do,
well, it works and it's just fine
and it's a great learning experience.
But we will be going over it in a couple of tutorials
about how to make it so your microcontroller is checking
to see if the button's been pushed
while still executing other work
instead of just sitting there,
has it been pushed yet?
Has it been pushed yet?
I don't know.
Has it been pushed yet?
Nope. Okay, still here.
Very inefficient, but also very, very simple.
So that's why we do it.
So with that, let's program this thing and see it in action.
All right, says it's working.
Let's make sure it is.
Yep, there it is.
I don't know if you can see that,
but it is now turning on and off with every button press.
So let's get the camera up closer so we can see it
and talk about its performance in the way it is working.
So this, you can obviously see that the LED is off
and I just push it, it turns on, turns off,
turns on, turns off.
So as I mentioned, it waits until you release
to make the transition.
So it's off, I push the button, nothing's happening,
nothing's happening, nothing's happening, release.
Push the button, nothing's happening,
nothing's happening, release.
So you could set it so that it happened
on the forward edge, but we set it up to do the back edge.
If you wanna do it the other way, do a little experiment.
See if you know how to make that change.
It should be exciting.
And also 20 milliseconds.
Do we know if that's fast enough?
Is that gonna cause it so it's not responsive?
I don't think that's the case
because I'm going about as fast I can.
I'm not a gamer or anything.
Maybe if I got a real person who's really quick at that
they'd be able to do it faster.
But that seems pretty good.
So I think the timing on the debounce delay is spot on
and it is acting exactly as we would expect.
Perfect.
So that seems to be about it.
I think we've covered everything.
Now you know how to both use an output via your GPIO
and an input via your GPIO and use a button.
So you now, well, the world is your oyster.
Hopefully you found it a little bit easier
to use the MPLAB Code Configurator.
Again, this is a simple enough project
that it probably would be faster just to do it in code,
but it's great to see the two different ways to approach it.
And again, it seems like the MCC is much more scalable
as you get to have a lot more complex projects.
So I'm glad that Sergey is doing it this way
where he's doing it both without and then with the MCC.
And if you have any questions,
again, Sergey goes super detailed with his written tutorial
and he explains all of these things
in a lot of detail to be incredibly redundant.
But I hope you like this video.
I hope it was helpful.
If it was, please give it a like, subscribe to our channel,
all that good stuff and we will catch you in the next one.
Take care.