Multiplexing Sample Application
This post goes over an application that reads inputs being activated as a pattern using their state mask. However many times inputs are triggered within a certain amount of milliseconds between them, those inputs state masks are added to the pattern already there. This continues until there is an input not within the set amount of milliseconds. Then it prints the pattern and begins creating a new one.
Make sure to have properly setup the project before using this code, to learn how to setup a custom java application on the JNIOR, a link is here.
After setting up the project, it will require two files. This first one we create is called MultiplexSample, which calls the run function we will create in the second file.
//function runs the application
public class MultiplexSample {
public static void main(String[] args) {
InputMultiplexer inputMultiplex = new InputMultiplexer();
inputMultiplex.run();
}
}
After that we begin creating the second file called InputMultiplexer. The first thing we include in the project is the import statements. The two imports we use are for IoEvents and the Iolog. We will use these to get the input’s information and process them as patterns.
We then declare the global variables. The first one we declare is the _iolog object. The Iolog keeps track of all IoEvents, including inputs. We will use the IoEvents from the Iolog to grab the information of the inputs when they are activated.
After this is _eventCaptureTime which grabs the start of when the IoEvents are grabbed at the start of each loop through the application.
We then need a long value called _startOfPatternTime. This is the current time of each new input that comes in. We need this because the program loops every 500 seconds, and if 1 input happens right after the loop ends we’ll miss it. The _startOfPatternTime is subtracted from the _eventCaptureTime which helps us check if that input should keep the pattern going.
The _refreshTimestamp value helps us only grab new IoEvents from the Iolog by only grabbing events past its value.
Next is the IoEvent array _ioEvents which contains the inputs we are processing from the Iolog for the current pattern.
We then have the pattern value, which is the pattern we are constantly building from the IoEvents state mask.
Lastly is PATTERN_WINDOW_DURATION which is the value in milliseconds we are looking to see pass between inputs to determine if they are close enough to combine into a new pattern or process as separate ones.
import com.integpg.system.IoEvent;
import com.integpg.system.Iolog;
public class InputMultiplexer implements Runnable {
//grabs the Iolog to get IoEvents
private Iolog _iolog = new Iolog();
//time of the first input to find the start of the input pattern
private long _startOfPatternTime = 0;
//time where Iolog is refreshed as to not look at old IoEvents
private long _refreshTimestamp = _startOfPatternTime;
//array of IoEvents to evaluate from the Iolog
private IoEvent[] _ioEvents;
//value for checking pattern has more IoEvents to process
private long _eventCaptureTime = 0;
//input pattern to log
private int _pattern = 0;
//duration between inputs required to continue a pattern
private static final int PATTERN_WINDOW_DURATION = 100;
Next is the run function, which sets the _eventCaptureTime value, calls the other functions we are about to create, and permanently loops the program every 500 seconds. This makes it so the application is constantly checking the Iolog for new IoEvents.
//function calls other functions to log input pattern in a infinite loop
@Override
public void run() {
while (true) {
_eventCaptureTime = System.currentTimeMillis();
getIoEvents();
lookForIoPattern();
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
}
}
Next is the lookForIoPattern function. This function starts with a for loop that will go through all recent IoEvents from the Iolog and processes their states to begin creating a new pattern.
Next the IoEvent states and mask values have an & operation done to get which states have turned high. Next the _startOfPatternTime was set if this was the first input in the pattern. After that _startOfPatternTime would be compared with either the current IoEvent’s timestamp or the _eventCaptureTime value to determine if more inputs need to be added to the pattern. _startOfPatternTime is compared to currentIoEvent’s timestamp to check if timestamps of inputs were within PATTERN_WINDOW_DURATION milliseconds of each other, which in this example is 100 milliseconds. If the 500 milliseconds that the program is looping in ends as another input comes in, then its compared to the _eventCaptureTime value to check if another input came in within 100 milliseconds of the last input, even if the loop ended. This would prevent patterns from getting cut of from one another because of the 500 millisecond loop.
//function checks the IoEvents of the Iolog and evaluates an input pattern
private void lookForIoPattern() {
//grabs the IoEvents of the Iolog
for (int index = _ioEvents.length - 1; index >= 0; index--) {
IoEvent currentIoEvent = _ioEvents[index];
System.out.println(currentIoEvent.timestamp);
//This value shows the state total for the IoEvent
System.out.println("This is the current I/O state: " + currentIoEvent.states);
//This value shows which input values were activated for the IoEvent
int statesTurnedHigh = currentIoEvent.states & currentIoEvent.mask;
System.out.println("This is the value of statesTurnedHigh: " + statesTurnedHigh + "\n");
//grabs the start of the input pattern if its hasn't been assigned yet and if enough time passes between IoEvents it evaluates the pattern,
//otherwise the pattern has an or statement performed on it with the current IO event
if (statesTurnedHigh != 0) {
if (_startOfPatternTime == 0) {
_startOfPatternTime = currentIoEvent.timestamp;
System.out.println("Start of pattern found.");
}
if (currentIoEvent.timestamp - _startOfPatternTime > PATTERN_WINDOW_DURATION) {
evaluatePattern(_pattern);
_startOfPatternTime = currentIoEvent.timestamp;
_pattern = currentIoEvent.states;
} else {
_pattern = currentIoEvent.states | _pattern;
}
}
}
//checks if the pattern is done or if the loop needs to grab more IoEvents
if (_startOfPatternTime != 0) {
if (_eventCaptureTime - _startOfPatternTime > PATTERN_WINDOW_DURATION) {
evaluatePattern(_pattern);
_startOfPatternTime = 0;
_pattern = 0;
}
}
}
The last two functions are the evaluatePattern function and the getIoEvents function. The evaluatePattern function simply grabs the pattern created from the lookForIoPattern function and prints it. The getIoEvents function is what is called to grab the most recent IoEvents from the IoLog.
//prints out the Input Pattern
private void evaluatePattern(int createdPattern) {
System.out.println("Pattern is " + createdPattern);
}
//grabs IoEvents and puts them into a class level array
private void getIoEvents() {
_iolog.refresh(_refreshTimestamp);
_ioEvents = _iolog.getInputEvents();
}
}
After adding those last functions, you should now have program that grabs all the inputs activating on the JNIOR, and creates a state pattern depending on how close each input’s timestamp is. Below is the code for the full application. Make sure you set the MultiplexSample file as the main function of your project.
//function runs the application
public class MultiplexSample {
public static void main(String[] args) {
InputMultiplexer inputMultiplex = new InputMultiplexer();
inputMultiplex.run();
}
}
import com.integpg.system.IoEvent;
import com.integpg.system.Iolog;
public class InputMultiplexer implements Runnable {
//grabs the Iolog to get IoEvents
private Iolog _iolog = new Iolog();
//time of the first input to find the start of the input pattern
private long _startOfPatternTime = 0;
//time where Iolog is refreshed as to not look at old IoEvents
private long _refreshTimestamp = _startOfPatternTime;
//array of IoEvents to evaluate from the Iolog
private IoEvent[] _ioEvents;
//value for checking pattern has more IoEvents to process
private long _eventCaptureTime = 0;
//input pattern to log
private int _pattern = 0;
//duration between inputs required to continue a pattern
private static final int PATTERN_WINDOW_DURATION = 100;
//function calls other functions to log input pattern in a infinite loop
@Override
public void run() {
while (true) {
_eventCaptureTime = System.currentTimeMillis();
getIoEvents();
lookForIoPattern();
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
}
}
//function checks the IoEvents of the Iolog and evaluates an input pattern
private void lookForIoPattern() {
//grabs the IoEvents of the Iolog
for (int index = _ioEvents.length - 1; index >= 0; index--) {
IoEvent currentIoEvent = _ioEvents[index];
System.out.println(currentIoEvent.timestamp);
//This value shows the state total for the IoEvent
System.out.println("This is the current I/O state: " + currentIoEvent.states);
//This value shows which input values were activated for the IoEvent
int statesTurnedHigh = currentIoEvent.states & currentIoEvent.mask;
System.out.println("This is the value of statesTurnedHigh: " + statesTurnedHigh + "\n");
//grabs the start of the input pattern if its hasn't been assigned yet and if enough time passes between IoEvents it evaluates the pattern,
//otherwise the pattern has an or statement performed on it with the current IO event
if (statesTurnedHigh != 0) {
if (_startOfPatternTime == 0) {
_startOfPatternTime = currentIoEvent.timestamp;
System.out.println("Start of pattern found.");
}
if (currentIoEvent.timestamp - _startOfPatternTime > PATTERN_WINDOW_DURATION) {
evaluatePattern(_pattern);
_startOfPatternTime = currentIoEvent.timestamp;
_pattern = currentIoEvent.states;
} else {
_pattern = currentIoEvent.states | _pattern;
}
}
}
//checks if the pattern is done or if the loop needs to grab more IoEvents
if (_startOfPatternTime != 0) {
if (_eventCaptureTime - _startOfPatternTime > PATTERN_WINDOW_DURATION) {
evaluatePattern(_pattern);
_startOfPatternTime = 0;
_pattern = 0;
}
}
}
//prints out the Input Pattern
private void evaluatePattern(int createdPattern) {
System.out.println("Pattern is " + createdPattern);
}
//grabs IoEvents and puts them into a class level array
private void getIoEvents() {
_iolog.refresh(_refreshTimestamp);
_ioEvents = _iolog.getInputEvents();
}
}