(uplifting music)
- Welcome to the fourth tutorial
in our PIC18F14K50 tutorial series
that Sergei is putting together.
This is a non-MCC tutorial.
The next one will be using the MP Lab code configurator,
but this one we will be just doing it from scratch.
What we are doing today is we are using a button.
So, in our previous tutorial,
we turned an LED on and off every half second.
Now we will make it so when you push a button,
it turns the LED on, push the button again,
turns it off, back and forth, back and forth.
So basically, you can think of this as last tutorial
we discussed how to use an output,
this tutorial will discuss how to use an input
and an output.
So before I get into the schematics here,
I will say that you should just be able to make
some very minor changes to the last setup.
So if you've already done tutorial two or three,
then you should basically just be able to put on a switch
and be good to go.
But I want to talk about the weak pull-up resistors
that we will be using for this switch.
Now the PIC18F14K50
actually has internal weak pull-up resistors
that are internal to it,
and you just need to turn it on.
And if you don't remember what a pull-up resistor is,
we've talked about it in a lot of other tutorials,
but I'll just touch on it briefly.
All that does is that basically makes the input
of the pin tied weakly to VCC or your power rail,
and what that means is that you have a large,
usually a 10,000 ohm or greater resistor
between the power rail and the input,
so that if nothing's connected to it,
it floats up to your power rail.
In this case, it'll be about five volts,
but as soon as you connect it to ground,
it will immediately go down to ground
without causing any problems
and without a huge amount of current.
And you really want to have a pull-up resistor,
either internally in this case
or externally if you don't have it on any input,
because that way you won't get kind
of this fluttering random voltage.
So, if you haven't ever dealt with pull-up resistors,
that's very briefly what it is.
Sergei has gone into much greater depth
in other tutorials not in this series
so you can go check those out
if you still have any lingering questions.
But with that, let's move on to the schematic diagram.
So as I mentioned, we didn't change things very much.
If anything, this looks exactly like what we did
in tutorials two and three,
except we have our switch here connecting our RB6
to ground.
That is the only difference we have in the schematic,
but one of the benefits is RB6
and the entire RB port has weak pull-ups.
So, unless you're pushing that button
it is tied to VCC and as it's reading that input,
it'll see it as high unless you're pressing the button.
Alright, so the physical setup is quite straightforward.
That is good to go.
I think now we can just jump straight
into the software itself.
So one thing is when I was doing tutorials two
and three, I had everything hooked up
when I started my project and this time I didn't.
And when you go through and it asks, "Hey,
what debugging tool do you want to use?"
It didn't pop up automatically
because it wasn't connected.
So I thought, "Hmm, that's not good.
That might make it another step to add that tool,"
but it's not a big deal.
So I just wanted to go over that briefly
that if you create your project and it's not connected
to your PICkit 4, all you have to do is literally
have X or MP Lab open, plug it in,
you'll get a little thing in the corner saying,
"Hey, we detected your PICkit 4."
And then it won't automatically add to your project,
but you can just go to project settings,
which that either is going to your project up the top,
right clicking on it and hitting Properties
or you can click this button right here and hit Properties.
And then once you click that, it'll pop up and say, "Hey,
do you want to use this PICkit 4?"
And you just say, "Yes" and you're good to go,
you're golden.
So just FYI, if that happens to you and you're like,
"Oh my goodness, how do I add my PICkit to this later?"
That's how you do it.
Very straightforward.
So now let's jump into the program itself.
We have already put all the config bits,
basically exactly like we did in the previous tutorials.
We can double check those if we want just to see
that our oscillator is our internal RC oscillator,
watchdog timer enable is off and LVP is off,
so we are good to go.
So we won't worry about the config bits anymore and probably
in future tutorials we won't even mention those again,
unless there's something specific that we need to deal with.
So, we have our entirety of the program.
It's here in what is showing to be lines 63 through 85,
and it does look a lot more complicated,
and it is a little bit more complicated,
but it's not that bad.
As we see in 65 we still have pin RC0 as an output,
we have that TRISCbit set to zero,
but then in 66 we have our RB6 pin as an input,
which is the pin that we've connected our switch to.
So nothing too exciting here.
Now in 67 we see that enable pull-up resistor
at RB6 pin in Sergei's comments,
and we can look at that WPUbits.WPUB6 = 1.
Now, this is one of those things
where it just makes a lot more sense
if you know what those commands are.
And so you can just look at that as WPU week pull-up B,
that's port B, because this is RB6 is on port B.
And then bits, that means that instead
of addressing all of it, you just want to address one
of the bits in that port,
and then you do dot,
and then you say which bit that is and that is WPUB6.
And so that's all that's saying
on 67 is week pull-up port B bits,
week pull-up port B6 equals one.
So once you know that,
it makes a lot more sense and it's nice.
This is one of the benefits
of the IDE is that since it's highlighted in green,
or not highlighted but is green text,
you know that you've named it correctly
and everything is good to go.
Then in 68 you have INTCON2bits.nRABPU = 0.
This one's a little bit more complicated
because there's an oddity here.
You would think, "INTCON,
well, that seems something like interrupt control,"
and you'd be right, that's exactly it.
It's interrupt control register two,
and then you want to adjust address the bits
and you're like,
"But we're not dealing with interrupts, are we?"
No, no, we're not.
We're not dealing with interrupts at all.
However, probably just because the designers
of the chip are like, "Ah, we have an extra bit here.
Let's stick it right here."
The global control for weak pull-ups is actually
in the interrupt control register, which is random,
but that's why it is right there.
So INTCON2, most of that register is dedicated
to interrupt control, but in this case,
this one bit, it's dedicated to the pull-ups.
So the .nRABPU is a little bit more straightforward.
That n basically means it's inverse, so it's active low.
So in this case, when you have zero,
that means that you do want to enable the weak pull-ups.
And then RAB is just port RA and port RBPU pull-ups.
So again, that's what 68 is doing.
So in 67 we said specifically we want our RB6 pull-up
to be initialized,
and then in 68 we initialized all of them in general.
And you'll notice this a lot in microcontroller work
that you'll have like global
and then you'll have specific, and you'll,
maybe I'm going the wrong way with my hands,
but you can say, "Hey, I want to enable this one thing,
but if you haven't enabled it globally, it won't work."
And that's just so you can,
if you'd like to with one, changing one bit,
turn off a whole bunch of stuff,
turn on a whole bunch of stuff,
and then also allow you the granularity
if you want to control just that single thing.
So that's what's going on in 67 and 68.
Now in 69, we get into the meat of our program
and that's basically where we check in 71,
if the button is low, so PORTBbits.RB6 == 0.
So in that if statement,
it's saying, "Hey, is this zero?"
And since it's active, well, since it's normally high,
right now, it's not high, it's just sitting there,
and this is an incredibly inefficient, simple,
but inefficient way to check for a button push,
because it's just checking, "Is it on, is it pushed?
Nope? Okay.
Is it pushed? Nope? Okay."
Just over and over.
And that's all it's doing over and over forever and ever.
So the problem with this is it's called blocking.
It's blocking the ability for the CPU,
the microcontroller to do anything else,
and in a later tutorial coming up soon,
we learn how to create a button function
that does not block other activities,
and that is obviously much better,
but this is simple and good for our needs right now.
So in 71, we are checking to see if our switch has been
or if our button's been pushed and that input drops low.
And then in 73 we have what's called a debounce delay.
Now, if you're familiar with microcontrollers at all,
you know that, well,
that doesn't just have to be microcontrollers,
if you're familiar with switches at all,
you know that when you push a button,
it's not a perfect square,
like oh, it jumps, there's like bounces
and it goes up and down, up and down, up and down,
and so sometimes you don't know,
"Is this noise or is this a button being pushed?"
So this is a very common,
yet very heavy handed way of checking to see
if the button has actually been pushed or it's just noise.
And so what happens is you push the button, it says, "Hey,
I just detected that it's low.
Let's wait 20 milliseconds.
Is it still low?
Oh, okay, he must have really pushed the button."
So that is why you have the same exact thing
in 74 as you do in 71,
is you're checking to see if it's low.
If it is, you wait 20 milliseconds.
Then you check to see if it's low again.
And then if it is, you're like, "Oh, great!"
Now the way this particular program is set up
is that it actually toggles when you release.
So on line 76, you get that while PORTBbits.RB6 == 0,
you just wait,
and so then you get into the loop where you're just waiting
and now it's checking to see if it goes high.
And then it waits, waits, waits.
As soon as you release,
it does that same debounce,
because you get the noise going either direction,
waits 20 milliseconds, and then in line 78,
if it has actually been released,
it says, "All right, we're done.
Let's actually do the action,
break out of this and go back up to line 69
and start that while loop over again."
Now, in line 80,
you can see the exact same command that we had
in the last tutorial, which just toggles the bit.
So in 80, you just get that XOR function
that says, "Whatever the current value is,
toggle it to the other one"
and that's it.
Once it does that,
it's just sitting there waiting, waiting, waiting, waiting,
pushes the button, it does those checks, toggles it,
waits, waits, waits, waits, push the button,
checks the button, toggles it, and it just waits.
So that is all this microcontroller is going to be doing,
which is not using it to its greatest potential,
but again, sometimes you just need something simple.
Okay, so with that, let us actually program this thing.
I already programmed it before,
so there shouldn't be anything surprising going on here.
Yes, Programming/Verify complete.
Okay, so now we can just test this out
and you can see, again, that push it up,
push on, push off, push on, push off.
Now there's a couple of things you can notice here.
First I push and then release,
and that's when it toggles as I mentioned earlier,
push, release, so it's performing exactly as we wanted.
Now we currently have a 20 millisecond debounce
and so that's something where you can try
and get it so it doesn't go,
but I think that 20 milliseconds is fast enough
that it's still very responsive.
But oops, and I just pulled that up.
Please be careful.
And yet it's slow enough
that it's not really affecting anything.
So I think 20 milliseconds
for this application seems to be a pretty sweet spot.
So, that seems to be working quite well,
exactly as we anticipated.
So that's about it for this tutorial.
We learned about the weak pull-ups.
We learned about using inputs as well as outputs.
We learned about the weak pull-up needing both the local
and the global enabling bits,
so that's something that you need to watch out for,
not just with weak pull-ups, but basically anything.
Make sure that everything is set up properly.
Everything seems to be quite straightforward.
We're gonna get set up
and we're going to do another tutorial just like this
but we will be using the MP Lab code configurator
to get ourselves a little bit more comfortable with that.
Now the homework that Sergei has for this is
to make it so when you push the button,
not only does it toggle,
but when you're holding the button, it oscillates
at four hertz or basically four times a second.
So that will add an interesting dimension there.
So if you wanna do that before jumping
over the MCC tutorial, that would be fantastic.
If you liked this tutorial, if you found it helpful at all,
please give the video a like, (mouse clicking)
subscribe, to our channel
and we will catch you
in the next one. (bell dings)
Take care.
(toaster rattles)