Summary
This tutorial shows how to slightly modify the ioio lib in order to add a listener for digital input.
Description
At the very least, you're reading this because you want to do something when the value of your digital input changes. This might even mean that you've tried to listen for the digital input changes by creating a new thread and use the blocking call Digitalinput.waitForValue(). This is one way but we can also go into the IOIOLib and add a listener. Adding this listener to the pin is what this article is all about.
Before we begin
This tutorial assumes you are somewhat familiar with your ioio, java, and android. How familiar do you have to be to use the tutorial without problems? Work with the ioio examples first or be able to read your targeted digital input before attempting this tutorial.
Steps
As an overview, we are going to make the following changes/additions to the IOIOLib:
Add the abstract class, "Listener.java" to the package "ioio.lib.impl".
Create a new class named "Listener.java" inside of the package "ioio.lib.impl".
In this class delete everything and the following:
package ioio.lib.impl;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
public abstract class Listener {
private final Set<String> properties;
public Listener(String... properties) {
Collections.addAll(this.properties = new TreeSet<String>(), properties);
}
protected final Set<String> getProperties() {
return this.properties;
}
public abstract <T> void propertyChanged(final String property,
final T oldValue, final T newValue);
}
See it on github at:
https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/Listener.java
Step Two
Modify the abstract class, "DigitalInput.java", in the package "ioio.lib.api". Adding the the abstract methods for the Listener.
To do this, find the file "DigitalInput.java" in the package "ioio.lib.api" and add the following (inside the class):
// Custom
public boolean addListener(final Listener x);
public boolean removeListener(final Listener x);
See it on github at (lines 129 and 130):
https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/api/DigitalInput.java
Step Three
Modify the class, "DigitalInputImpl.java", in the package "ioio.lib.impl". Add the implementation for the Listener, and call "firePropertyChanged" at the start of "setValue".
Find the class "DigitalInputImpl.java" in the package "ioio.lib.impl" and add the following (inside the class):
private final List<Listener> listeners = new LinkedList<Listener>();
protected final <T> void firePropertyChanged(final String property,
final T oldValue, final T newValue) {
assert(property != null);
if((oldValue != null && oldValue.equals(newValue))
|| (oldValue == null && newValue == null))
return;
for(final Listener listener : this.listeners) {
try {
if(listener.getProperties().contains(property))
//System.out.println("property changed");
listener.propertyChanged(property, oldValue, newValue);
} catch(Exception ex) {
System.out.println(ex.getMessage());
// log these, to help debugging
ex.printStackTrace();
}
}
}
@Override
synchronized public final boolean addListener(final Listener x) {
if(x == null) return false;
return this.listeners.add(x);
}
@Override
synchronized public final boolean removeListener(final Listener x) {
return this.listeners.remove(x);
}
See it on github at: https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/DigitalInputImpl.java (lines 107 through 135)
In this same class add the following inside of the method "setValue":
firePropertyChanged("value",value_,value);
See it on github at: https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/DigitalInputImpl.java (line 55)
Step Four
Create your DigitalInput in the Looper class
I'm using the HelloIOIO project as the example. Find where your looper class starts, and declare a DigitalInput named "exampleInput". For this example, it is directly under the line "private DigitalOuput led_;". The line we are adding looks like this:
private DigitalInput exampleInput;
See it on github at:
https://github.com/ergobot/HelloIOIO/blob/master/src/ioio/examples/hello/MainActivity.java
(line 47)
Step Five
Add the listener in the setup method of the looper class
Note: For the example, we are using pin 47.
Find your setup method in the looper class, and add the following:
// Our digital input (the pin being used for this example is pin #47)
exampleInput = ioio_.openDigitalInput(47);
exampleInput.addListener(new ioio.lib.impl.Listener("value") {
public <T> void propertyChanged(final String p, final T oldValue,
final T newValue) {
// This is where you do what you want with the old or new value
// Write to the logcat
Log.v("exampleInput", "exampleInput - " + System.nanoTime() +" oldValue = " + ((Boolean) oldValue ? 0:1) + " : newValue = " + newValue);
// or another way to write it... print it out
System.out.println(p + " changed: " + oldValue + " to " + newValue);
}
});
See it on github at: https://github.com/ergobot/HelloIOIO/blob/master/src/ioio/examples/hello/MainActivity.java (lines 64 to 79)
...and there it is! Hope you helps you. When searching, there wasn't a way to do this. It may not be the best but take it and make it your own. If you know of a better way, put it in the comments.
Resources:
Original idea:
https://groups.google.com/d/msg/ioio-users/aROyaAVOhAQ/UVQHx5Lmh6kJ
Listener based on stackoverflow.com answer:
http://stackoverflow.com/questions/2822901/watching-a-variable-for-changes-without-polling
Eclipse IDE (from the adt-bundle)
link - http://developer.android.com/sdk/index.html
HelloIOIO
original - https://github.com/ytai/ioio/tree/master/software/applications/HelloIOIO
modified - https://github.com/ergobot/HelloIOIO
IOIOLib
original - https://github.com/ytai/ioio/tree/master/software/IOIOLib
modified - https://github.com/ergobot/IOIOLib
IOIO Mint
adafruit - http://www.adafruit.com/products/885
This tutorial shows how to slightly modify the ioio lib in order to add a listener for digital input.
Description
At the very least, you're reading this because you want to do something when the value of your digital input changes. This might even mean that you've tried to listen for the digital input changes by creating a new thread and use the blocking call Digitalinput.waitForValue(). This is one way but we can also go into the IOIOLib and add a listener. Adding this listener to the pin is what this article is all about.
Before we begin
This tutorial assumes you are somewhat familiar with your ioio, java, and android. How familiar do you have to be to use the tutorial without problems? Work with the ioio examples first or be able to read your targeted digital input before attempting this tutorial.
Steps
As an overview, we are going to make the following changes/additions to the IOIOLib:
- Add the abstract class, "Listener.java", to the package "ioio.lib.impl"
- Modify the abstract class, "DigitalInput.java", in the package "ioio.lib.api". Adding the the abstract methods for the Listener.
- Modify the class, "DigitalInputImpl.java", in the package "ioio.lib.impl". Add the implementation for the Listener, and call "firePropertyChanged" at the start of "setValue"
- Create your DigitalInput in the Looper class
- Add the listener in the setup method of your looper class
Step One
Add the abstract class, "Listener.java" to the package "ioio.lib.impl".
Create a new class named "Listener.java" inside of the package "ioio.lib.impl".
In this class delete everything and the following:
package ioio.lib.impl;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
public abstract class Listener {
private final Set<String> properties;
public Listener(String... properties) {
Collections.addAll(this.properties = new TreeSet<String>(), properties);
}
protected final Set<String> getProperties() {
return this.properties;
}
public abstract <T> void propertyChanged(final String property,
final T oldValue, final T newValue);
}
See it on github at:
https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/Listener.java
Step Two
Modify the abstract class, "DigitalInput.java", in the package "ioio.lib.api". Adding the the abstract methods for the Listener.
To do this, find the file "DigitalInput.java" in the package "ioio.lib.api" and add the following (inside the class):
// Custom
public boolean addListener(final Listener x);
public boolean removeListener(final Listener x);
See it on github at (lines 129 and 130):
https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/api/DigitalInput.java
Step Three
Modify the class, "DigitalInputImpl.java", in the package "ioio.lib.impl". Add the implementation for the Listener, and call "firePropertyChanged" at the start of "setValue".
Find the class "DigitalInputImpl.java" in the package "ioio.lib.impl" and add the following (inside the class):
private final List<Listener> listeners = new LinkedList<Listener>();
protected final <T> void firePropertyChanged(final String property,
final T oldValue, final T newValue) {
assert(property != null);
if((oldValue != null && oldValue.equals(newValue))
|| (oldValue == null && newValue == null))
return;
for(final Listener listener : this.listeners) {
try {
if(listener.getProperties().contains(property))
//System.out.println("property changed");
listener.propertyChanged(property, oldValue, newValue);
} catch(Exception ex) {
System.out.println(ex.getMessage());
// log these, to help debugging
ex.printStackTrace();
}
}
}
@Override
synchronized public final boolean addListener(final Listener x) {
if(x == null) return false;
return this.listeners.add(x);
}
@Override
synchronized public final boolean removeListener(final Listener x) {
return this.listeners.remove(x);
}
See it on github at: https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/DigitalInputImpl.java (lines 107 through 135)
In this same class add the following inside of the method "setValue":
firePropertyChanged("value",value_,value);
See it on github at: https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/DigitalInputImpl.java (line 55)
Step Four
Create your DigitalInput in the Looper class
I'm using the HelloIOIO project as the example. Find where your looper class starts, and declare a DigitalInput named "exampleInput". For this example, it is directly under the line "private DigitalOuput led_;". The line we are adding looks like this:
private DigitalInput exampleInput;
See it on github at:
https://github.com/ergobot/HelloIOIO/blob/master/src/ioio/examples/hello/MainActivity.java
(line 47)
Step Five
Add the listener in the setup method of the looper class
Note: For the example, we are using pin 47.
Find your setup method in the looper class, and add the following:
// Our digital input (the pin being used for this example is pin #47)
exampleInput = ioio_.openDigitalInput(47);
exampleInput.addListener(new ioio.lib.impl.Listener("value") {
public <T> void propertyChanged(final String p, final T oldValue,
final T newValue) {
// This is where you do what you want with the old or new value
// Write to the logcat
Log.v("exampleInput", "exampleInput - " + System.nanoTime() +" oldValue = " + ((Boolean) oldValue ? 0:1) + " : newValue = " + newValue);
// or another way to write it... print it out
System.out.println(p + " changed: " + oldValue + " to " + newValue);
}
});
See it on github at: https://github.com/ergobot/HelloIOIO/blob/master/src/ioio/examples/hello/MainActivity.java (lines 64 to 79)
...and there it is! Hope you helps you. When searching, there wasn't a way to do this. It may not be the best but take it and make it your own. If you know of a better way, put it in the comments.
Resources:
Original idea:
https://groups.google.com/d/msg/ioio-users/aROyaAVOhAQ/UVQHx5Lmh6kJ
Listener based on stackoverflow.com answer:
http://stackoverflow.com/questions/2822901/watching-a-variable-for-changes-without-polling
Eclipse IDE (from the adt-bundle)
link - http://developer.android.com/sdk/index.html
HelloIOIO
original - https://github.com/ytai/ioio/tree/master/software/applications/HelloIOIO
modified - https://github.com/ergobot/HelloIOIO
IOIOLib
original - https://github.com/ytai/ioio/tree/master/software/IOIOLib
modified - https://github.com/ergobot/IOIOLib
IOIO Mint
adafruit - http://www.adafruit.com/products/885
No comments:
Post a Comment