My Android Things

Android Things Tutorials (IoT)

Tutorial 9 : Working with Tactile Switch via Drivers

In last tutorial, we have seen how to use Tactile Switch with Android Things. In this tutorial we will do the same but with freely available drivers. So what is this driver thing? The driver are simple java library, which gives us the functionality to control some hardware (In our case tactile button) without needing to know how to control the device. They provide us better way to control hardware; as different aspect of controlling a hardware has been contributed by many users around the world (and we know a hive mind is always better than a single small mind). So as in previous tutorial we have make uses of tactile switch on our own. But we didn't handle my problems that can arise using it. Like Bouncing problem that exist in tactile switch. 

What is Bouncing?
All type of buttons are made of metal. As the mechanical property of a metal, when two metal objects collide, there is a vibration created in both of the pieces. You can notice it when you strike two spoons together, or struck a plate with a spoon. Same thing happens here. But in a tiny scale. The force applied to push the button causes the metallic disk in the switch to vibrate a little. This vibration lasts for a few milli seconds, but this vibration is enough to cause an effect of continuously pressing and releasing the button in rapid succession. The button actually toggle several times during a few milli seconds each time it is pressed. This is called the Contact Bouncing or the Switch Bouncing. This will create unexpected effect on the circuit. As in this circuit. The microcontroller is fast enough to detect the toggle and execute the code accordingly several times in a few milli seconds. An example of it as in graph format can be seen as:

(Switch Bouncing)

Switch Debouncing
Switch debouncing is technique to handle switch bouncing problem. It can be implemented in 4 ways:
  • Hardware Debouncing
  • R-C Debouncing
  • Software Debouncing
  • Using Debouncing IC’s
We will not go in depth of these techniques. But one thing to note that our Button Driver has inbuilt code to handle Software Debouncing. So we have better excuse now to use Button driver.

Building the Circuit:
We will use the same circuit that we have used in previous tutorial (Tutorial 8). Final circuit image will be like this:


Programming It:
This is what we need to change from previous tutorial. Create a new project as "MAT9" with "Android Things" template. There is no need to select UI layout file while creating project. 

1. Gradle dependency

To use the button driver, simply add the line below to your project's build.gradle, where <version> matches the last version of the driver available on jcenter.

dependencies {
    compile 'com.google.android.things.contrib:driver-button:<version>'
}
2. Change the MainActivity
Open up MainActivity.java and add the following static and member variables at the top of the class and resolve the dependencies to Gpio and Button Class (Please make sure you resolve it to com.google.android.things.contrib.driver.button.Button):

Button mButton;
private static final String TAG = "MAT9";
private static final String BUTTON_PIN = "BCM17";

Change the OnCreate method with following code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
mButton = new Button(BUTTON_PIN,
// high signal indicates the button is pressed
// use with a pull-down resistor
Button.LogicState.PRESSED_WHEN_HIGH
);
mButton.setOnButtonEventListener(new Button.OnButtonEventListener() {
@Override
public void onButtonEvent(Button button, boolean state) {
Log.d(TAG, "GPIO changed, button pressed");
}
});
} catch (IOException e) {
// couldn't configure the button...
}
}

Also don't forget to close the button in onDestroy:
@Override
protected void onDestroy() {
super.onDestroy();
if(mButton!=null){
try {
mButton.close();
} catch (IOException e) {
// error closing button
}
}
}

From above code please note Button.LogicState.PRESSED_WHEN_HIGH. There are two logic states: PRESSED_WHEN_HIGH and PRESSED_WHEN_LOW. These states define which button state (down or up) will be considered ON. i.e. If you define logicstate as PRESSED_WHEN_LOW and press your button down; then you will get "TRUE" in second parameter "boolean STATE" of OnButtonEventListener. But If you define logicstate as PRESSED_WHEN_HIGH and press your button down; then you will get "FALSE" in second parameter "boolean STATE" of OnButtonEventListener

Party time

Run the app on your Raspberry Pi by pressing run button on your Android Studio, and press your button, you will get LOG in your Studio saying "GPIO changed, button pressed" for both event i.e. Button_Down and Button_Up.

Download Project Source 
MAT9.zip (58.7KB)


Second Way of Programming It:
We will change our project little bit to handle KeyEvents Ourself. Create a new project as "MAT9two" with "Android Things" template. There is no need to select UI layout file while creating project. 

1. Gradle dependency

To use the button driver, simply add the line below to your project's build.gradle, where <version> matches the last version of the driver available on jcenter.

dependencies {
    compile 'com.google.android.things.contrib:driver-button:<version>'
}
2. Change the MainActivity
Open up MainActivity.java and add the following static and member variables at the top of the class and resolve the dependencies to Gpio and Button Class (Please make sure you resolve it to com.google.android.things.contrib.driver.button.ButtonInputDriver):
ButtonInputDriver mInputDriver;
private static final String TAG = "MAT9";
private static final String BUTTON_PIN = "BCM17";

Change the OnCreate method with following code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
mInputDriver = new ButtonInputDriver(BUTTON_PIN,
Button.LogicState.PRESSED_WHEN_HIGH,
KeyEvent.KEYCODE_A // the keycode to send
);
mInputDriver.register();
} catch (IOException e) {
// error configuring button...
}
}

Now you are free to register KeyEvents for your program; like KeyUp or KeyDown:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_A) {
Log.d(TAG, "GPIO changed, button pressed down");
return true; // indicate we handled the event
}
return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_A) {
Log.d(TAG, "GPIO changed, button up");
return true; // indicate we handled the event
}
return super.onKeyDown(keyCode, event);
}
Also don't forget to close the button in onDestroy:
@Override
protected void onDestroy() {
super.onDestroy();
if(mInputDriver!=null) {
mInputDriver.unregister();
try {
mInputDriver.close();
} catch (IOException e) {
// error closing input driver
}
}
}

Party time

Run the app on your Raspberry Pi by pressing run button on your Android Studio, and press your button, you will get LOG in your Studio saying "GPIO changed, button pressed down" and  "GPIO changed, button pressed up" for event i.e. Button_Down and Button_Up.

Download Project Source 
MAT9TWO.zip (59KB)

Add comment

Loading