Reading a button in the BeagleBone Black PART II
In this post, I will continue to show you how to read a button with the BeagleBone Black. In the first entry I showed how to read an input from a button doing POLLING in the code, i.e., checking continuously for the state of the button inside the main program.
In this post, I show a new method named WaitForButton()
to the C++ class BUTTON
that stop the main program until a button has been pressed.
Circuit and components
The circuit can be seen in Figure 1. Please keep in mind that the BeagleBone works at 3.3V and not 5V like microcontrollers as Arduino. It is so muy important to avoid damage to the board, especially when you are working with buttons or digital inputs in general.
The components are:
- 1 Resistor of 10KΩ as a pull-down resistor
- 1 Push button of 12mm
- Jumpers male-male to make the connections
Coding
I added the corresponding methods to read a button into the class BUTTON who is derived from GPIO class. The methods are:
WaitForButton()
WaitForButton(int)
The WaitForButton()
method, first checks if the GPIO is attached to a button has been set up as INPUT and then wait until the button has changed from a LOW
state to a HIGH
state. This means the button has been pressed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int BUTTON::WaitForButton()
{
if (this->mode != INPUT)
{
perror("'waitForButton' method only works on INPUT mode");
return -1;
}
string message;
WriteFile(path, "edge", "rising");
while (stopWaitForButtonFlag == false)
{
previousValueOnPin = ReadButton();
if (previousValueOnPin == LOW)
break;
}
while (stopWaitForButtonFlag == false)
{
if (ReadButton() == HIGH)
break;
}
if (previousValueOnPin != valueOnPin)
{
message = "A RISING edge was detected!";
cout << RainbowText(message, "Pink") << endl;
return 1;
}
return 0;
}
The second method WaitForButton(int)
is an overload of the first. The difference consists that this method receives one
of the next types of transition on the pin:
RISING
FALLING
BOTH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
int BUTTON::WaitForButton(int edge = RISING)
{
if (this->mode != INPUT)
{
perror("'waitForButton' method only works on INPUT mode");
return -1;
}
string message;
switch (edge)
{
case RISING:
WriteFile(path, "edge", "rising");
while (stopWaitForButtonFlag == false)
{
previousValueOnPin = ReadButton();
if (previousValueOnPin == LOW)
break;
}
while (stopWaitForButtonFlag == false)
{
if (ReadButton() == HIGH)
break;
}
if (previousValueOnPin != valueOnPin)
{
message = "A RISING edge was detected!";
cout << RainbowText(message, "Pink") << endl;
return 1;
}
break;
case FALLING:
WriteFile(path, "edge", "falling");
while (stopWaitForButtonFlag == false)
{
previousValueOnPin = ReadButton();
if (previousValueOnPin == HIGH)
break;
}
while (stopWaitForButtonFlag == false)
{
if (ReadButton() == LOW)
break;
}
if (previousValueOnPin != valueOnPin)
{
message = "A FALLING edge was detected!";
cout << RainbowText(message, "Pink") << endl;
return 1;
}
break;
case BOTH:
WriteFile(path, "edge", "both");
previousValueOnPin = ReadButton();
while (stopWaitForButtonFlag == false)
{
if (previousValueOnPin != ReadButton())
{
message = "A RISING OR FALLING edge was detected!";
cout << RainbowText(message, "Yellow") << endl;
return 1;
}
}
break;
}
return 0;
}
The button can be declared as a BUTTON
object
specifying the pin attached to it:
1
BUTTON redButtonPin(P8_08);
In the main program, only a single line makes to wait for the press of a button, before continue with the next line of code:
1
redButtonPin.WaitForButton();
Listing_3.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include "../../Sources/GPIO.h"
#include "../../Sources/BUTTON.h"
using namespace std;
int main()
{
string message = "Main program starting here...";
cout << RainbowText(message,"Blue", "White", "Bold") << endl;
BUTTON redButtonPin(P8_08);
message = "The program is waiting for a press on a Button\nPlease, press the red button!";
cout << endl << RainbowText(message, "Red") << endl;
redButtonPin.WaitForButton();
message = "The red button was pressed!!!";
cout << RainbowText(message, "Red") << endl;
message = "Main program finishes here...";
cout << RainbowText(message,"Blue", "White","Bold") << endl;
return 0;
}
Execution of the program:
Se you in the next post.