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:

Advertisements

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:

How to take inputs in a Microcontroller, interfacing buttons with microcontroller

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:

How to interface buttons with microcontrollers

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:

How to take inputs in a Microcontroller, interfacing buttons with microcontroller

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.

How to take inputs in a Microcontroller, interfacing buttons with microcontroller

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:

How to take inputs in a Microcontroller, interfacing buttons with microcontroller

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:

How to take inputs in a Microcontroller, interfacing buttons with microcontroller

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.

How to interface buttons with microcontrollers

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:

For Professional Designs or Help:

Loading

MKDas

Mithun K. Das; B. Sc. in EEE from KUET; Head of R&D @ M's Lab Engineering Solution. "This is my personal blog. I post articles on different subjects related to electronics in the easiest way so that everything becomes easy for all, especially for beginners. If you have any questions, feel free to ask through the contact us page." Thanks.

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

Leave a Reply

Avatar placeholder

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