In this chapter, we will learn How to interface buttons with microcontrollers. This is another basic part of the series of Learning PIC microcontrollers in C. You need to learn this to utilize the microcontroller. So let’s start.
Disclaimer:
Handling electricity carries inherent risks. It’s essential to have the appropriate skills to manage it safely. Proceed at your own risk, as the author disclaims responsibility for any misuse, harm, or errors. All content on this website is unique and copyrighted; please avoid unauthorized copying. While most articles are open-source for your benefit, feel free to use the knowledge provided. If you find our resources helpful, consider purchasing available materials to support our work.
For assistance or guidance, leave a comment below; the author is committed to helping. Some articles may contain affiliate links that support the author with a commission at no additional cost to you. Thank you for your understanding and support.
Table of Contents
Previous chapter:
If you miss the previous chapter, you can read it here.
How to interface buttons with the microcontroller:
While we did the first blinking program for the PIC microcontroller, maybe you have seen that we used TRISA/B/C, etc register to set the pin as Input/Output. Yes, that is the register that sets the pin as input. Now, we will practice another simple project that will take input from us and execute the action. So let’s see How to interface buttons with microcontrollers.
Example code1:
Here is an example code that takes the button as the input and executes the action.
/* Project name: Test Project for learning PIC MCU Programmer: Mithun K. Das Email: mithun060@gmail.com Date:21-05-2023 */ void main() { TRISB = 0x00;//set all output TRISA = 0xFF;//set all input TRISC = 0x00;//set all output ADCON1 = 0x07;//keep adc off ADCON0 = 0x00;//turn off ADC PORTB = 0x00;//clear port B PORTC = 0x00;//clear port C while(1) { if(RA0_bit==1) //if RA0 pin is high { RB0_bit = 1; } else { RB0_bit = 0; } }//end of while(1) }//end of void main()
This is a very simple code that takes the input through the A0 pin of the MCU and gives output to the B0 pin.
The diagram to test this project:
Now, you may have a question about why there is a resistor R2 to pull down the input. Well, in this circuit or any similar cases, if you do not discharge the pin which is set as input then that pin may have a little hysteresis due to capacitance and different phenomena. Then the MCU will execute a little differently and in worse cases, it may work totally the wrong way.
Check the simulation:
You can clearly see that the output is not acting according to the input and just after the first press, the input itself is charged and not changing. Now, see the next test:
Have you found the difference? Yes, the input pin is not having any hysteresis. So, when we will take a pin as input, we will use a resistor to discharge that pin. Or if we are using that pin as Push to Low or in a pull-down way, then we will do the following changes to do the same type of work.
This will also work but in an inverted way if you use the same code. So what is happening here? We are pulling the pin down using the button and the R2 resistor is pulling that pin high. This is how it is working.
So, you have learned two ways to use a button as input and you can drive a LED according to your input activity. Now, let’s upgrade the code a bit and see what alternatives you can do.
Example code2:
void main() { TRISB = 0x00;//set all output TRISA = 0xFF;//set all input TRISC = 0x00;//set all output ADCON1 = 0x07;//keep adc off ADCON0 = 0x00;//turn off ADC PORTB = 0x00;//clear port B PORTC = 0x00;//clear port C while(1) { RB0_bit = RA0_bit; }//end of while(1) }//end of void main()
This is the same code you have seen just moments ago. Yes, this is how we can minimize code lines and also make it simpler.
And if you want to invert the output, simply write this:
while(1) { RB0_bit = ~RA0_bit; }//end of while(1)
Now practice a bit with these. So that you can understand it from deep inside of your brain.
In practice case study:
In the last practice, you are now able to use a push button with a microcontroller. Now, you need to come to practical life. When we use a mechanical push button in the circuit and we push the button, what happens? Actually, it creates a small fluctuation like this:
As the microcontroller is working very fast compared with our hand activity, it will actually make a fluctuation in the output pin as the button does. So it will create noise in the output. Now, how we can remove this?
We can remove this in two ways. One from hardware and another from code/firmware.
Hardware changes:
We can add a capacitor with that input pin like this:
Here capacitor C1 will eliminate the noises created by the button. And the same protection we can do from the firmware side too.
Firmware changes:
bit mask; void main() { TRISB = 0x00;//set all output TRISA = 0xFF;//set all input TRISC = 0x00;//set all output ADCON1 = 0x07;//keep adc off ADCON0 = 0x00;//turn off ADC PORTB = 0x00;//clear port B PORTC = 0x00;//clear port C mask = 1; while(1) { if(RA0_bit==0 && mask==1) { mask = 0; Delay_ms(100); } if(RA0_bit==1 && mask==0) { mask = 1; RB0_bit = 0; Delay_ms(100); } RB0_bit = mask; }//end of while(1) }//end of void main()
Here you can see I’m using a mask to change the state of the RB0 pin. And using a delay of 100ms in the input pin with mask conditions. Yes, you could use only the delay just after the button press but that will make a delay only will not solve the issue completely. But if you make a hysteresis with the mask and conditions, it will never flicker again. And this will solve the button debouncing.
Conclusion:
So you are learning step by step, right? I hope so and now you know, How to interface buttons with microcontrollers. As you see here I kept the capacitor C1 and also changed the firmware. So in combination, the flickering will be eliminated. Like this basic one, whenever you need to take any input try to use a small capacitor as a filter, and also never forget to use a pull-up or pull-down resistor or do this from inside of the MCU. Well, I’ll discuss this later on when it’s time.
Till then, keep practicing and the next chapter will be more interesting.
Read more on:
- Learning PIC Microcontrollers Programming in C: Chapter 1
- Learning PIC Microcontrollers Programming in C: Chapter 2
- Learning PIC Microcontrollers Programming in C: Chapter 3
- Learning PIC Microcontrollers Programming in C: Chapter 4
- Learning PIC Microcontrollers Programming in C: Chapter 5
- Learning PIC Microcontrollers Programming in C: Chapter 6
- Learning PIC Microcontrollers Programming in C: Chapter 8
For Professional Designs or Help:
6 Comments
iffi · 25/05/2023 at 11:55 pm
Hi,
Sir i have a problem same like this. my microcontroller is 16f676. PORT A and PORT C.
TRISA = 0xFF; means inputs. and TRISC = 0x00; means outputs.
i write same commands like :
while(1)
{
if(RA0_bit==1) //if RA0 pin is high
{
RC0_bit = 1;
}
else
{
RC0_bit = 0;
} // end
Button not work on led. what’s the problem no error in code.
MKDas · 26/05/2023 at 8:10 pm
check Crystal settings first. Then Comparator settings.
iffi · 27/05/2023 at 2:05 am
i am using Proteus 8. XTAL FREQ is 4000000.
Still Button is not doing his job :((
MKDas · 27/05/2023 at 4:20 pm
Crystal should be 4MHz. and from project settings of the code, set I/O for both osc pins. MCLR disabled. hope it will work.
JatinderBir Singh · 29/05/2023 at 3:41 pm
Very nice endeavour, Dada. Kindly give tutorial to interface TM1638 with PIC micro
TIA
MKDas · 29/05/2023 at 8:28 pm
maybe in future… Thanks