lejos.hardware.sensor.MindsensorsBTSense Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lejos-ev3-api Show documentation
Show all versions of lejos-ev3-api Show documentation
leJOS (pronounced like the Spanish word "lejos" for "far") is a tiny Java Virtual Machine. In 2013 it was ported to the LEGO EV3 brick.
The newest version!
package lejos.hardware.sensor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import lejos.hardware.Bluetooth;
import lejos.hardware.sensor.SensorMode;
import lejos.remote.nxt.NXTCommConnector;
import lejos.remote.nxt.NXTConnection;
/**
* Support for the Mindsensors BTSense application
*
* @author Lawrie Griffiths
*
*/
public class MindsensorsBTSense {
private int trId = 0;
private InputStream is;
private OutputStream os;
private byte[] reply = new byte[512];
private int currLen = 0;
private int packets = 0;
private boolean debug = true;
/**
* A - Accelerometer
* G - Gravity
* N - Linear Acceleration
* L - Light
* M - Magnetic Field
* C - Compass
* P - Proximity
* S - Sound
* D - Date
* T - Time
* G - Gyroscope
* E - Atmospheric pressure
* H - Humidity
* U - Temperature
* W - Network location
* O - GPS Location
*/
private Map modes = new HashMap();
/**
* Connection to the BTSense application and identify device as EV3
* @throws IOException
*/
public MindsensorsBTSense() throws IOException {
NXTCommConnector connector = Bluetooth.getNXTCommConnector();
if (debug) System.out.println("Waiting for connection ...");
NXTConnection con = connector.waitForConnection(0, NXTConnection.RAW);
System.out.println("Connected");
is = con.openInputStream();
os = con.openOutputStream();
if (debug) System.out.println("Sending Identify command");
sendCmd("@:xIE");
// Start a background thread to read data from phone and put it in the relevant sensor mode
new DataReader().start();
}
/**
* Get a SensorMode object for a specific sensor mode and request data from phone
*
* @param sensorType the single character sensor mode identifier
* @return the SensorMode implementation
* @throws IOException
* @throws InterruptedException
*/
public SensorMode getSensorMode(char sensorType) throws IOException, InterruptedException {
BTSenseMode mode = modes.get(sensorType);
if (mode == null) {
sendCmd("+:t" + sensorType + "1"); // Currently everything is priority 1
return new BTSenseMode(sensorType, modes);
} else {
return mode;
}
}
/**
* Send a command to the phone application, with a transaction id
* @param cmd
* @throws IOException
*/
public void sendCmd(String cmd) throws IOException {
byte[] b = new byte[cmd.length()+2];
b[0] = (byte) (cmd.length());
b[1] = 0;
System.arraycopy(cmd.getBytes(), 0, b, 2, cmd.length());
b[4] = (byte) trId++;
os.write(b, 0, cmd.length()+2);
os.flush();
}
// Read the reply into the reply buffer at specified offset
public int getReply(int offset) throws IOException {
//System.out.println("Reading data at offset " + offset);
return is.read(reply, offset, reply.length);
}
/**
* Process data from the phone application
* @throws IOException
*/
public void processData() throws IOException {
int len = 0;
while(true) {
if (currLen == 0) {
len = getReply(0);
if (debug) System.out.println("Received " + len + " bytes ");
if (len <= 0) return;
currLen = len;
}
int packetLength = reply[0];
//System.out.println("Packet length = " + packetLength);
if (packetLength > currLen - 1) {
len = getReply(currLen);
if (debug) System.out.println("Received extra " + len + " bytes ");
if (len <= 0) return;
currLen += len;
}
//printReply();
byte [] packet = new byte[packetLength];
System.arraycopy(reply, 1, packet, 0, packetLength);
packets++;
extractData(packet);
System.arraycopy(reply, packetLength+1, reply, 0, currLen - (packetLength + 1));
currLen -= (packetLength + 1);
}
}
// Diagnostic method to print the reply data in hex
private void printReply() {
// Print the current data
for(int i=0;i sampleSizes = new HashMap();
static {
sampleSizes.put('A', 3);
sampleSizes.put('R', 3);
sampleSizes.put('N', 3);
sampleSizes.put('L', 1);
sampleSizes.put('A', 3);
sampleSizes.put('M', 3);
sampleSizes.put('P', 1);
sampleSizes.put('C', 3);
sampleSizes.put('S', 1);
sampleSizes.put('D', 3);
sampleSizes.put('T', 3);
sampleSizes.put('G', 3);
sampleSizes.put('E', 1);
sampleSizes.put('H', 1);
sampleSizes.put('U', 1);
sampleSizes.put('W', 2);
sampleSizes.put('O', 6);
}
BTSenseMode(char sensorType, Map modes) throws InterruptedException {
this.sensorType = sensorType;
sampleSize = sampleSizes.get(sensorType);
latest = new float[sampleSize];
modes.put(sensorType, this);
synchronized(this) {
wait();
}
}
@Override
public int sampleSize() {
return sampleSize;
}
@Override
public void fetchSample(float[] sample, int offset) {
for(int i=0;i