2. Chapter Button and leds

Usually, there are three essential parts in a complete automatic control device: INPUT, OUTPUT, and CONTROL. In last section, the LED module was the output part and RPI was the control part. In practical applications, we not only make LEDs flash, but also make a device sense the surrounding environment, receive instructions and then take the appropriate action such as turn on LEDs, make a buzzer beep and so on.

../../../_images/button-led-flow-chart.png

Next, we will build a simple control system to control an LED through a push button switch.

2.1. Project Push Button Switch & LED

In the project, we will control the LED state through a Push Button Switch. When the button is pressed, our LED will turn ON, and when it is released, the LED will turn OFF. This describes a Momentary Switch.

2.1.1. Component List

Raspberry Pi

(Recommended: Raspberry Pi 5 / 4B / 3B+ / 3B)

(Compatible: 3A+ / 2B / 1B+ / 1A+ / Zero W / Zero)

raspberrypi5

LED x1

red-led

Breadboard x1

breadborad-830

GPIO Extension Board & Ribbon Cable

extension-board

Push Button

Switch x1

button-small

Resistor 10KΩ x2

res-10k

Resistor 220Ω x1

res-220R

Jumper (some)

jumper-wire

Note

In the code “button” represents switch action.

2.1.2. Component knowledge

2.1.2.1. Push Button Switch

This type of Push Button Switch has 4 pins (2 Pole Switch). Two pins on the left are connected, and both left and right sides are the same per the illustration:

../../../_images/button-small-img-sch.jpg

When the button on the switch is pressed, the circuit is completed (your project is Powered ON).

2.1.3. Circuit

  1. Schematic diagram

../../../_images/button-led-sch1.jpg

Note

R3 is used to limit current to protect GPIO 18, if you set it to output HIGH level by mistake.

  1. Hardware connection

../../../_images/button-led-hdc1.jpg

Note

There are two kinds of push button switch in this kit.

The smaller push button switches are contained in a plastic bag.


Hint

If you need any support, please feel free to contact us via: support@freenove.com

This is how it works.

When button switch is released:

../../../_images/button-led-released.png

When button switch is pressed:

../../../_images/button-led-pressed.png

2.1.4. Code

This project is designed for learning how to use Push Button Switch to control an LED. We first need to read the state of switch, and then determine whether to turn the LED ON in accordance to the state of the switch.

2.1.4.1. C Code ButtonLED

First, observe the project result, then learn about the code in detail.

Hint

If you need any support, please feel free to contact us via: support@freenove.com

  1. Use cd command to enter ButtonLED directory of C code.

$ cd ~/Freenove_Kit/Code/C_Code/02.1.1_ButtonLED
  1. Use the following command to compile the code ButtonLED.c and generate executable file ButtonLED.

$ gcc ButtonLED.c -o ButtonLED -lwiringPi
  1. Then run the generated file ButtonLED.

$ sudo ./ButtonLED

Later, the terminal window continues to print out the characters “led off…”. Press the button, then LED is turned on and then terminal window prints out the “led on…”.

Release the button, then LED is turned off and then terminal window prints out the “led off…”. You can press Ctrl+C to terminate the program.

The following is the program code:

 1/**********************************************************************
 2* Filename    : ButtonLED.c
 3* Description : Control led by button.
 4* Author      : www.freenove.com
 5* modification: 2019/12/26
 6**********************************************************************/
 7#include <wiringPi.h>
 8#include <stdio.h>
 9
10#define ledPin    0  	//define the ledPin
11#define buttonPin 1		//define the buttonPin
12
13void  main(void)
14{
15	printf("Program is starting ... \n");
16
17	wiringPiSetup();	//Initialize wiringPi.	
18
19	pinMode(ledPin, OUTPUT); //Set ledPin to output
20	pinMode(buttonPin, INPUT);//Set buttonPin to input
21
22	pullUpDnControl(buttonPin, PUD_UP);  //pull up to HIGH level
23	while(1){
24		if(digitalRead(buttonPin) == LOW){ //button is pressed 
25			digitalWrite(ledPin, HIGH);  //Make GPIO output HIGH level
26			printf("Button is pressed, led turned on >>>\n");		//Output information on terminal
27		}
28		else {							//button is released 
29			digitalWrite(ledPin, LOW);  //Make GPIO output LOW level
30			printf("Button is released, led turned off <<<\n");		//Output information on terminal
31		}
32	}
33}

In the circuit connection, LED and Button are connected with GPIO17 and GPIO18 respectively, which correspond to 0 and 1 respectively in wiringPI. So define ledPin and buttonPin as 0 and 1 respectively.

1#define ledPin    0     //define the ledPin
2#define buttonPin 1     //define the buttonPin

In the while loop of main function, use digitalRead(buttonPin) to determine the state of Button. When the button is pressed, the function returns low level, the result of “if” is true, and then turn on LED. Or, turn off LED

1if(digitalRead(buttonPin) == LOW){ //button is pressed 
2	digitalWrite(ledPin, HIGH);  //Make GPIO output HIGH level
3	printf("Button is pressed, led turned on >>>\n");		//Output information on terminal
4}
5else {							//button is released 
6	digitalWrite(ledPin, LOW);  //Make GPIO output LOW level
7	printf("Button is released, led turned off <<<\n");		//Output information on terminal
8}

2.1.4.2. Reference

int digitalRead (int pin);

This function returns the value read at the given pin. It will be “HIGH” or “LOW”(1 or 0) depending on the logic level at the pin.

2.2. Project MINI Table Lamp

We will also use a Push Button Switch, LED and RPi to make a MINI Table Lamp but this will function differently: Press the button, the LED will turn ON, and pressing the button again, the LED turns OFF. The ON switch action is no longer momentary (like a door bell) but remains ON without needing to continually press on the Button Switch.

First, let us learn something about the push button switch.

2.2.1. Debounce a Push Button Switch

When a Momentary Push Button Switch is pressed, it will not change from one state to another state immediately. Due to tiny mechanical vibrations, there will be a short period of continuous buffeting before it stabilizes in a new state too fast for Humans to detect but not for computer microcontrollers. The same is true when the push button switch is released. This unwanted phenomenon is known as “bounce”.

../../../_images/02_00.png

Therefore, if we can directly detect the state of the Push Button Switch, there are multiple pressing and releasing actions in one pressing cycle. This buffeting will mislead the high-speed operation of the microcontroller to cause many false decisions. Therefore, we need to eliminate the impact of buffeting. Our solution: to judge the state of the button multiple times. Only when the button state is stable (consistent) over a period of time, can it indicate that the button is actually in the ON state (being pressed).

This project needs the same components and circuits as we used in the previous section.

2.2.2. Code

In this project, we still detect the state of Push Button Switch to control an LED. Here we need to define a variable to define the state of LED. When the button switch is pressed once, the state of LED will be changed once. This will allow the circuit to act as a virtual table lamp.

2.2.2.1. C Code Tablelamp

First, observe the project result, and then learn about the code in detail.

If you have any concerns, please contact us via: support@freenove.com

  1. Use cd command to enter 02.2.1_Tablelamp directory of C code.

$ cd ~/Freenove_Kit/Code/C_Code/02.2.1_Tablelamp
  1. Use the following command to compile “Tablelamp.c” and generate executable file “Tablelamp”.

$ gcc Tablelamp.c -o Tablelamp -lwiringPi
  1. Tablelamp: Then run the generated file “Tablelamp”.

$ sudo ./Tablelamp

When the program is executed, press the Button Switch once, the LED turns ON. Pressing the Button Switch again turns the LED OFF.

 1/**********************************************************************
 2* Filename    : Tablelamp.c
 3* Description : DIY MINI table lamp
 4* Author      : www.freenove.com
 5* modification: 2019/12/27
 6**********************************************************************/
 7#include <wiringPi.h>
 8#include <stdio.h>
 9
10#define ledPin    0  	//define the ledPin
11#define buttonPin 1		//define the buttonPin
12int ledState=LOW;		//store the State of led
13int buttonState=HIGH;	//store the State of button
14int lastbuttonState=HIGH;//store the lastState of button
15long lastChangeTime;	//store the change time of button state
16long captureTime=50;	//set the stable time for button state 
17int reading;
18int main(void)
19{
20	printf("Program is starting...\n");
21
22	wiringPiSetup(); //Initialize wiringPi.	
23
24	pinMode(ledPin, OUTPUT);   //Set ledPin to output
25	pinMode(buttonPin, INPUT); //Set buttonPin to input
26
27	pullUpDnControl(buttonPin, PUD_UP);  //pull up to high level
28	while(1){
29		reading = digitalRead(buttonPin); //read the current state of button
30		if( reading != lastbuttonState){  //if the button state has changed, record the time point
31			lastChangeTime = millis();
32		}
33		//if changing-state of the button last beyond the time we set, we consider that 
34		//the current button state is an effective change rather than a buffeting
35		if(millis() - lastChangeTime > captureTime){
36			//if button state is changed, update the data.
37			if(reading != buttonState){
38				buttonState = reading;
39				//if the state is low, it means the action is pressing
40				if(buttonState == LOW){
41					printf("Button is pressed!\n");
42					ledState = !ledState; //Reverse the LED state
43					if(ledState){
44						printf("turn on LED ...\n");
45					}
46					else {
47						printf("turn off LED ...\n");
48					}
49				}
50				//if the state is high, it means the action is releasing
51				else {
52					printf("Button is released!\n");
53				}
54			}
55		}
56		digitalWrite(ledPin,ledState);
57		lastbuttonState = reading;
58	}
59
60	return 0;
61}

This code focuses on eliminating the buffeting (bounce) of the button switch. We define several variables to define the state of LED and button switch. Then read the button switch state constantly in while () to determine whether the state has changed. If it has, then this time point is recorded.

1reading = digitalRead(buttonPin); //read the current state of button
2if( reading != lastbuttonState){  //if the button state has changed, record the time point
3	lastChangeTime = millis();
4}
millis()

This returns a number representing the number of milliseconds since your program called one of the wiringPiSetup functions. It returns to an unsigned 32-bit number value after 49 days because it “wraps” around and restarts to value 0.

Then according to the recorded time point, evaluate the duration of the button switch state change. If the duration exceeds captureTime (buffeting time) we have set, it indicates that the state of the button switch has changed. During that time, the while () is still detecting the state of the button switch, so if there is a change, the time point of change will be updated. Then the duration will be evaluated again until the duration is determined to be a stable state because it exceeds the time value we set.

1if(millis() - lastChangeTime > captureTime){
2	//if button state is changed, update the data.
3	if(reading != buttonState){
4		buttonState = reading;

Finally, we need to judge the state of Button Switch. If it is low level, the changing state indicates that the button Switch has been pressed, if the state is high level, then the button has been released. Here, we change the status of the LED variable, and then update the state of the LED.

 1if(buttonState == LOW){
 2	printf("Button is pressed!\n");
 3	ledState = !ledState; //Reverse the LED state
 4	if(ledState){
 5		printf("turn on LED ...\n");
 6	}
 7	else {
 8		printf("turn off LED ...\n");
 9	}
10}