How to use a PUSHBUTTON with LEDs on ATMEGA328p in C

Updated: Jan 22


Welcome back to the best damn site to learn robotics for beginners on the planet!

Previously you learned how to glow an LED with the C language using the ATMEGA328p chip which is found in the popular Arduino boards.

We use C because it is much much more accurate and you will learn and know exactly how to control your electronic and robotic projects. It's all about flipping switches.

If you haven't learned how to glow the LED using the Timer/Counter in the ATMEGA328p check out my article here.

If you need some pushbuttons or LEDs


We will use our pushbutton which is a spring loaded piece of metal that floats above 2 metal contacts which are attached to metal pins.

If you need to learn more about pushbuttons, check out my lesson here.

We are going to set a voltage to go out on a pin.

I am going to use pin PC5.

You can use any pin that works for you.

I'm going to turn on pin PC5 and have it always sending out electricity.

The pin PC5 is connected to a wire that we can hook up to one pin of our pushbutton.

The ground wire is connected to the pin next to that one and must be on the same side.

Make sure you are connecting both wires on the same side otherwise it won't work. The pushbutton usually has 2 sides to it.

When we push down on the pushbutton, the metal piece touches the 2 sides of our pins, the positive side connected to our chip and the ground side.

This allows the electricity to flow and our code in our chip is going to use the Debounce trick.

This simply checks to see if the electricity went out on that pin PC5 and waits a few microseconds and then checks it again then waits again then takes note of the state that the button is in, whether it was pushed before or not.

Then it glows the LED on or off depending on that button state.

That's it!

Let's take a look at our breadboard setup. It's the same as the LED glow tutorial but we added the pushbutton.

Make sure to add your own power supply of 5v to the board as well. You can see my usb programmer's 5v and ground hooked up on the far right.

C Code for Pushbutton on ATMEGA328p

Now, let's take a look at a snapshot of our code.

We are taking the previous LED glow code and only adding the debounce code for the pushbutton.

It comes in at just under 64 lines of code with whitespaces included.

I'm only going to go over what I have added.

Let's zoom in on the...


Notice I have pre-defined the time I want the code to delay during the debounce. I called it debounceTime and set it to 1000 (it will be microseconds).

Next, I made the actual debounce code and created an 8 bit unsigned (neither positive nor negative value) and called it 'debounce' so you can see. There are no parameters needed so we put 'void' in the ( ).

The debounce uses stuff already outlined in the avr/io.h file.

The first you will notice is when we check to see if the electricity went out on our pin. I chose pin PC5. We use an if statement to check if the bit is clear on that pin.

Then we delay for a very short time using _delay_us( ).

us means microseconds.

This delay function was outlined in the util/delay.h file we included.

Don't you love it?

Then I put the name of my debounce time called 'debounceTime', so 1000 microseconds.

Then it checks and delays again to be sure the electricity really did go out on PC5 when you pressed your button.

If it didn't double confirm successfully, if you pushed way to fast or whatever it returns an error (1) and does nothing.

If it confirms twice successfully it returns (0) which means no problems.

Don't think too much about it.

Let's move onto our...


Don't worry about the mouse cursor next to the uint8_t i;

Notice I have set our button pin PC5 to output by itself and no other pins on PORTC.

We also create a way for our code to remember whether it the button was pushed and the LED glowed on or off last time.

We do this by making a simple 8 bit variable we can call buttonState or whatever you want and set it to 0.

0 will represent "not been pushed and the LED is off".

So when we give our chip 5v of power it is in this "LED is off" state.

Let's move onto the...


Notice right before the LED glow on code we put in an if ( ) { } statement with the debounce( ) code as the parameter.

This is like saying "if the debounce really happened then do the next part of code".

The next if that needs to happen is the buttonState absolutely MUST be 0.

This is why we have the double = .

When both of these conditions are met, the glow ON code carries through like the last tutorial and once it is done we change the buttonState to 1.

It doesn't have to be 1, you could say any 8 bit value other than 0 so 1-255 would do. But isn't it easy just to use 1?

We do the SAME if statements for the glow OFF and switch the buttonState back to 0.

Make sure to close all of the doors {

} .

Then make sure you save your file as a .c file with a new name in a new folder with the same name (without the .c of course) and copy paste your makefile you use and change the Target in the makefile to the name of your .c file (without the .c).

Click Make Clean (it's good practice).

Then Make ALL.

If no errors then click Program if you hooked up your usb programmer correctly.

This is where 99% of problems happen. So, don't unzip your body if you have to check spelling mistakes, the makefile, or the wiring, ok?


Make sure to check out my video tutorial and subscribe on Youtube and Odysee.

We are going to build something incredible together!

Stay positive!