This tutorial was featured on the official Arduino blog on 3/9/2011
That’s right folks, it’s Monday, and the second installment of my arduino tutorial series is here! I spent the last week in Disney World, but now that I’m back, it’s time to get down to business! This week, I’ll show you how to read a push button, debounce its input using software, how to create a function in the arduino programming environment, and how to change LED brightness using Pulse Width Modulation (PWM). If you have no idea what PWM is, or if you are confused about analog and digital signals, go check out my TechBits episode on the topic first! Don’t forget to go browse the element14 Arduino Group; it’s a great place to post questions, and learn from others!
You can download the files associated with this episode here:
Distributed under the GNU General Public (Open-Source) License.
Please Attribute and Share-Alike.













July 25, 2012 at 4:56 pm
jeremy, i need to use both Keypad and client_A function at the same time. Kindly help me through this.
#include
#include
#include
#include
#include
#include
#include
#include
#include “EmonLib.h”
// Include Emon Library
EnergyMonitor emon1;
////////////////////////////////////////////////////// LCD ///////////////////////////////////////////////////
LiquidCrystal lcd(A4, A5 ,5, 4, 3, 2);
////////////////////////////////////////////////////// ETHER /////////////////////////////////////////////////
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192,168,1,177); //Client IP
IPAddress server(192,168,1,170); //Server IP
EthernetClient client;
/////////////////////////////////////////////////////// KEYPAD //////////////////////////////////////////////
const byte ROWS = 2; // Two rows
const byte COLS = 3; // Three columns
char keys[ROWS][COLS] = {
{
’1′,’2′,’3′ }
,
{
’4′,’5′,’6′ }
,
};
byte rowPins[ROWS] = {
7, 6}; //Keypad Rows
byte colPins[COLS] = {
A3, 9, 8 }; //Keypad Colums
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
////////////////////////////////////////////////////VARIABLE DECLARATTION//////////////////////////////////////
int a=0,b=0,c=0,d=0,count=0,count1=0,count2=0,count3=0,k1,bed1,l1,g1;
int k, bed, l ,g;
///////////////////////////////////////////////////////INPUTS/OUTPUTS//////////////////////////////////////////
int led1 = (13); //Relay 1st Room
int led2 = (A0); //Relay 2nd Room
int led3 = (A1); //Relay 3rd Room
//int led4 = (A3); //Relay 4th Room
int buttonInt=0;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////// SETUP //////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
lcd.begin(16, 2);
//int tickEvent = t.every(2000, Client_A);
//Timer1.initialize(100000);
attachInterrupt(buttonInt, keypad, RISING );
Serial.begin(9600);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
//pinMode(led4, OUTPUT);
delay (1000);
lcd.print(“Welcome…”);
delay(1000);
lcd.clear();
lcd.print(“Set Priorities”);
delay(2000);
lcd.clear();
Ethernet.begin(mac, ip);
if (client.connect(server, 4400))
{
lcd.clear();
Serial.println(“connected”);
}
else
{
Serial.println(“connection failed”);
}
/*lcd.print(“pres 1 fr kitchn”);
delay(2000);
lcd.clear();
lcd.print(“pres 2 fr bed”);
delay(2000);
lcd.clear();
lcd.print(“pres 3 fr longue”);
delay(2000);
lcd.clear();
lcd.print(“pres 4 fr grage”);
delay(2000);
lcd.clear();
*/
}
char key;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////// MAIN LOOP ///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
// for (int i=0; i<5000; i++)
keypad();
{
Client_A();
}
}
// keypad function calling
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////// PRIORITIES //////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keypad()
{
key = kpd.getKey();
if(key!=NO_KEY)
{
if(key=='6')
{
lcd.clear();
lcd.print("Again");
Serial.print("Again");
a=0;
b=0;
c=0;
d=0;
count=0;
count1=0;
count2=0;
count3=0;
}
else
if((key=='1') && (b<1) && (c<1) && (d<1) && (a==0) && (count%2==0))
{
lcd.clear();
a=1;
b=0;
c=0;
d=0;
count++;
}
else
if((key=='2') && (a<1) && (c<1) && (d<1) && (b==0) && (count1%2==0))
{
lcd.clear();
a=0;
b=1;
c=0;
d=0;
count1++;
}
else
if((key=='3') && (a<1) && (b<1) && (d<1) && (c==0) && (count2%2==0))
{
lcd.clear();
a=0;
b=0;
c=1;
d=0;
count2++;
}
else
if((key=='4') && (a<1) && (b<1) && (c0 && bed>0 && l>0 && g>0)
{
if (led1==HIGH || led2==1023 || led3==1023 || led4==1023)
{
switching2();
}
if(k==4)
{
digitalWrite(led1, HIGH);
}
if(bed==4)
{
analogWrite(led2, 1023);
}
if(l==4)
{
analogWrite(led3, 1023);
}
if(g==4)
{
analogWrite(led4, 1023);
}
}
}
void switching2()
{
if ((led1==HIGH && led2==1023)||(led1==HIGH && led3==1023)||(led1==HIGH && led4==1023)||(led3==1023 && led2==1023)||(led4==1023 && led2==1023)||(led3==HIGH && led4==1023))
{
switching3();
}
if(k==3)
{
digitalWrite(led1, HIGH);
}
if(bed==3)
{
analogWrite(led2, 1023);
}
if(l==3)
{
analogWrite(led3, 1023);
}
if(g==3)
{
analogWrite(led4, 1023);
}
}
void switching3()
{
if(led1==HIGH && led2==1023 && led3==1023 || led1==HIGH && led2==1023 && led4==1023 || led2==1023 && led4==1023 && led3==1023 || led1==HIGH && led4==1023 && led3==1023)
{
switching4();
}
if(k==2)
{
digitalWrite(led1, HIGH);
}
if(bed==2)
{
analogWrite(led2, 1023);
}
if(l==2)
{
analogWrite(led3, 1023);
}
if(g==2)
{
analogWrite(led4, 1023);
}
}
void switching4()
{
if(k==1)
{
digitalWrite(led1, HIGH);
}
if(bed==1)
{
analogWrite(led2, 1023);
}
if(l==1)
{
analogWrite(led3, 1023);
}
if(g==1)
{
analogWrite(led4, 1023);
}
}
void unswitching()
{
if(led1==HIGH && led2==1023 && led3==1023 || led1==HIGH && led2==1023 && led4==1023 || led2==1023 && led4==1023 && led3==1023 || led1==HIGH && led4==1023 && led3==1023)
{
unswitching2();
}
if(k==1)
{
digitalWrite(led1, LOW);
}
if(bed==1)
{
analogWrite(led2, 0);
}
if(l==1)
{
analogWrite(led3, 0);
}
if(g==1)
{
analogWrite(led4, 0);
}
}
void unswitching2()
{
if(led1==HIGH && led2==1023 || led1==HIGH && led3==1023 || led1==HIGH && led4==1023 || led3==1023 && led2==1023 || led4==1023 && led2==1023 || led3==HIGH && led4==1023)
{
unswitching3();
}
if(k==2)
{
digitalWrite(led1, LOW);
}
if(bed==2)
{
analogWrite(led2, 0);
}
if(l==2)
{
analogWrite(led3, 0);
}
if(g==2)
{
analogWrite(led4, 0);
}
}
void unswitching3()
{
if (led1==HIGH || led2==1023 || led3==1023 || led4==1023)
{
unswitching4();
}
if(k==3)
{
digitalWrite(led1, LOW);
}
if(bed==3)
{
analogWrite(led2, 0);
}
if(l==3)
{
analogWrite(led3, 0);
}
if(g==3)
{
analogWrite(led4, 0);
}
}
void unswitching4()
{
if(k==4)
{
digitalWrite(led1, 0);
}
if(bed==4)
{
analogWrite(led2, 0);
}
if(l==4)
{
analogWrite(led3, 0);
}
if(g==4)
{
analogWrite(led4, 0);
}
}*/
void Client_A()
{
double Irms = emon1.calcIrms(1480); //Value of current from current transformer
char Ir[60];
delay (1000);
if (client.available()>0)
{
char rec = client.read();
Serial.print(rec);
switch (rec)
{
case ‘I’:
client.write(“1–1–”);
client.flush();
break;
case ‘D’:
dtostrf(Irms, 1, 2, Ir);
client.write(Ir);
client.flush ();
break;
delay(1000);
case ’0′:
// switching(); //switching starts here
client.flush ();
}
}
if (!client.connected())
{
Serial.println();
lcd.println(“disconnecting.”);
client.stop();
while(true);
}
}
November 2, 2012 at 9:45 pm
I saw the Tutorial 02 for Arduino: Buttons, PWM, and Functions and it was perfect.
But I still have a problem.
When I press the button the LED stay´s on, but I want the LED blinking. How can I do that?
November 3, 2012 at 7:38 am
I saw the Tutorial 02 for Arduino: Buttons, PWM, and Functions and it was perfect.
But I still have a problem.
When I press the button the LED stay´s on, but I want the LED blinking. How can I do that?
July 30, 2012 at 3:00 am
Hello Jeremy! Could you please explain why boolean function (boolean debounce(boolean last)) written before void loop? Does it jump out of (void loop) when we push button?
August 5, 2012 at 3:20 pm
Yes, you can jump to functions from within the loop. Upon completion, you return to where you were in the loop.
August 21, 2012 at 8:50 pm
What do I need to open your download files.? Thank you.
August 22, 2012 at 10:54 pm
The Arduino programming environment. See my first video.
September 5, 2012 at 9:57 am
How does the Boolean function make the light stay on and stay off corresponding with the switch as compared to the earlier demonstration. didn’t quite get the boolean function.
September 26, 2012 at 6:57 am
Hi Jermy,
I have a question about the debounce function you made in this tutorial.
boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
if (last != current)
{delay(5);
current = digitalRead(switchPin);
}
return current;
debounce is the name of the function?
current is the output of the function?
last is the input?
so in this tutorial last will be changed out with lastButton and current will be replaced by currentButton when you use the function in the program?
What does actual the return command do?
thanks for any answer, regards Pelle
October 3, 2012 at 3:35 pm
debounce is the name of the function
last is what you pass to the function
The return function outputs the value of the “current”
October 10, 2012 at 3:58 pm
Hi Jeremy,
Thank you for you Arduino tutorials it really help me and it is wonderful. Is it posibble if you could do a tutorial;
– Use a sensor to create a disco light controller
Cheers,
October 23, 2012 at 2:34 pm
Hi Jeremy,
I have followed Tutorial 2 and seem to have a problem. My code looks to be exactly the same as yours however when I press the pushbutton nothing happens. My only experience is Tutorial 1 so far so might be missing something but can’t seem to find it!
October 23, 2012 at 2:42 pm
Figured it out now, obviously it was a u53r error (a missing = sign)! Haha
Pete
December 30, 2012 at 6:23 pm
Why can’t you just give the code as a text file?
January 4, 2013 at 3:43 pm
Because I’m supplying it in the Arduino File format…
January 27, 2013 at 3:07 pm
Hello Jeremy.
Love your tutorials thanks alot for them !
I have a question about the Debounce code.
How do you multiply if for more than 1 switch ?
fx. i have 4 switch and each switch should control an LED. input on 8-9-10-11 and output on 2-3-4-5.
seems like everything i’ve tried to dublicate and rewrite the code won’t work. Can you offer a helping hand ? Thanks a bunch.
P.S tried google without much help. Been trying to fix this for 4 hours now , driving me crazy ! :)
January 27, 2013 at 11:23 pm
There are a lot of other xbee shields available. Just do a google search for one. Sparkfun and Adafruit both sell shields.
February 8, 2013 at 6:59 pm
Can anyone see the problem with my code? I’ve tried switching pins and everything to see if maybe the arduino was flawed, but the outcome is always the same: as soon as I load up the program, the led turns on. Pressing the button doesn’t do anything for it.
int switchPin = 8;
int ledPin = 12;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean ledOn = false;
void setup()
{
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
}
boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
if (last != current)
{
delay(5);
current=digitalRead(switchPin);
}
return current;
}
void loop()
{
currentButton = debounce(lastButton);
if (lastButton == LOW && currentButton == HIGH);
{
ledOn=!ledOn;
}
lastButton = currentButton;
digitalWrite(ledPin, ledOn);
}
February 23, 2013 at 9:13 pm
Hi Jeremy,
Thanks so much for producing these tutes. I’ve learned more about button->led control with this one than I have in about a two weeks of painful dead end or carbon copy google directed research. I’m an arduino infant of about 2 months so things are still falling into place for me and this pool of knowledge will definitely help push me forward a little faster.
I am hoping you might be able to point me in the right direction with something i’m trying to achieve. I’d like to manipulate the PWM to have the LED flash at a defined interval, constantly, after the button changes state and then have the LED return to an always LOW state after the buttons state changes again.
I have attempted to combine the ever present “button switch” and “blink without delay” codes which are readily available but have had no luck so far in achieving anything more than a solid LOW or HIGH LED state.
Your code achieves a similar outcome but in a slightly different way to the others i’ve seen in that you’re applying the use of PWM and, from what I understand of your code, may allow for the type of outcome i’m aiming for.
Do you think you might be able to help out. I’ll hack at your code and see what I can do right away and hope that you’ll respond soon. If I nail it then I’ll post what i’ve done here if that’s all good with you.
Thanks again.
February 27, 2013 at 11:22 pm
You should implement a state machine to accomplish this. Use a variable to track button presses. Trigger a timer interrupt every x millisecond and have it toggle the LED depending on the value of that state variable.
March 1, 2013 at 8:45 am
I wanna do the same code of switching ON/OFF a led but with a push button, but i want to use several leds and push buttons say 3. So should I do the exact same things 3 times or is there another way to optimize the code? the part the confusing me is the debouncing part, I dunno if I should define 2 more “current” variables for each button of what?!
Thanks :)
March 21, 2013 at 6:38 pm
Hi Jeremy!
First of all thank you for the tutorials, they are really awesome!
I have a doubt concerning the if condition. You say if (lastButton == LOW && currentButton == HIGH), then ledOn !=ledOn. I tried to remove the condition lastButton==LOW to see what could have happened and the debounce stopped working. Point is that I do not understand how checking the lastButton influences the code. I mean, why the currentButton condition is not sufficient? And how is the code behaviour modified by putting both the last and currentButton condition instead of using the only currentButton one?
Thank you a lot!
Pingback: Tutorials for Arduino Getting Acquainted with Arduino - Arduino for ProjectsArduino for Projects
May 14, 2013 at 12:50 pm
Hi jeremy,
I am building a radiation detector. so using an arduino uno to record the voltage output from two different detectors on a sd card. I need the sd card to record the voltages vs time for each one of the detectors on the same card but on separately. could you help me with the code as i have just started using the system a day ago and an a mechanical engineering student. your help would be very much appreciated as i have very basic programming knowledge. thank you
yaz
Pingback: Arduino Liquid Crystal Displays -Arduino for Projects
Pingback: Arduino Interrupts and Debouncing -Arduino for Projects