355 lines
7.6 KiB
Java
355 lines
7.6 KiB
Java
package altimeter;
|
|
|
|
import gnu.io.CommPortIdentifier;
|
|
import gnu.io.PortInUseException;
|
|
import gnu.io.SerialPort;
|
|
import gnu.io.UnsupportedCommOperationException;
|
|
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.Enumeration;
|
|
|
|
/**
|
|
* Class to interface the PerfectFlite Alt15K/WD altimeter.
|
|
*
|
|
* Also includes a main method that retrieves all flight profiles and saves them to files.
|
|
*
|
|
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
|
*/
|
|
|
|
public class RotationLogger {
|
|
private static final boolean DEBUG = false;
|
|
|
|
private static final int BYTES = 65536;
|
|
|
|
|
|
private final CommPortIdentifier portID;
|
|
private SerialPort port = null;
|
|
private InputStream is = null;
|
|
private OutputStream os = null;
|
|
|
|
|
|
|
|
public static String[] getNames() {
|
|
ArrayList<String> list = new ArrayList<String>();
|
|
|
|
Enumeration<?> pids = CommPortIdentifier.getPortIdentifiers();
|
|
|
|
while (pids.hasMoreElements()) {
|
|
CommPortIdentifier pid = (CommPortIdentifier) pids.nextElement();
|
|
|
|
if (pid.getPortType() == CommPortIdentifier.PORT_SERIAL)
|
|
list.add(pid.getName());
|
|
}
|
|
return list.toArray(new String[0]);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public RotationLogger(String name) throws IOException {
|
|
CommPortIdentifier myPortID = null;
|
|
|
|
Enumeration<?> portIdentifiers = CommPortIdentifier.getPortIdentifiers();
|
|
while (portIdentifiers.hasMoreElements()) {
|
|
CommPortIdentifier pid = (CommPortIdentifier) portIdentifiers.nextElement();
|
|
|
|
if(pid.getPortType() == CommPortIdentifier.PORT_SERIAL &&
|
|
pid.getName().equals(name)) {
|
|
myPortID = pid;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (myPortID == null) {
|
|
throw new IOException("Port '"+name+"' not found.");
|
|
}
|
|
this.portID = myPortID ;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void readData() throws IOException, PortInUseException {
|
|
int c;
|
|
|
|
int[] data = new int[BYTES];
|
|
|
|
FileOutputStream rawdump = null;
|
|
|
|
|
|
try {
|
|
open();
|
|
|
|
System.err.println("Sending dump mode command...");
|
|
|
|
for (int i=0; i<16; i++) {
|
|
os.write('D');
|
|
try {
|
|
Thread.sleep(10);
|
|
} catch (InterruptedException ignore) { }
|
|
}
|
|
|
|
System.err.println("Waiting for response...");
|
|
while (true) {
|
|
c = is.read();
|
|
if (c == 'K') {
|
|
break;
|
|
} else {
|
|
System.err.printf("Received spurious c=%d\n",c);
|
|
}
|
|
}
|
|
|
|
System.err.println("Received response.");
|
|
|
|
|
|
|
|
System.err.println("Opening 'rawdump'...");
|
|
rawdump = new FileOutputStream("rawdump");
|
|
|
|
|
|
|
|
System.err.println("Performing dump...");
|
|
|
|
os.write('A');
|
|
|
|
byte[] buffer = new byte[1024];
|
|
int printCount = 0;
|
|
for (int count=0; count < BYTES; ) {
|
|
if ((BYTES-count) < buffer.length) {
|
|
buffer = new byte[BYTES-count];
|
|
}
|
|
|
|
int n = is.read(buffer);
|
|
if (n < 0) {
|
|
System.err.println("Error condition, n="+n);
|
|
return;
|
|
}
|
|
|
|
rawdump.write(buffer, 0, n);
|
|
|
|
for (int i=0; i<n; i++) {
|
|
data[count+i] = unsign(buffer[i]);
|
|
}
|
|
count += n;
|
|
if (count - printCount > 1024) {
|
|
System.err.println("Read "+count+" bytes...");
|
|
printCount = count;
|
|
}
|
|
}
|
|
|
|
|
|
System.err.println("Verifying checksum...");
|
|
int reported = is.read();
|
|
|
|
byte computed = 0;
|
|
for (int i=0; i < data.length; i++) {
|
|
computed += data[i];
|
|
}
|
|
if (computed == reported) {
|
|
System.err.println("Checksum ok ("+computed+")");
|
|
} else {
|
|
System.err.println("Error in checksum, computed="+computed+
|
|
" reported="+reported);
|
|
}
|
|
|
|
System.err.println("Communication done.");
|
|
|
|
} catch (UnsupportedCommOperationException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
} finally {
|
|
close();
|
|
if (rawdump != null)
|
|
rawdump.close();
|
|
}
|
|
|
|
convertData(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////// Data interpretation //////////////
|
|
|
|
|
|
private static void convertData(int[] data) {
|
|
|
|
System.err.println("Converting data...");
|
|
|
|
int lastBuffer = data[0xffff];
|
|
if (lastBuffer < 0 || lastBuffer > 3) {
|
|
System.err.println("Illegal last accessed buffer: "+lastBuffer);
|
|
return;
|
|
}
|
|
System.err.println("Last used buffer: "+lastBuffer);
|
|
|
|
for (int i=4; i>0; i--) {
|
|
int n = (lastBuffer + i) % 4;
|
|
int bufNumber = 4-i;
|
|
|
|
convertBuffer(data, n * (BYTES/4), bufNumber);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private static void convertBuffer(int[] data, int position, int bufNumber) {
|
|
int startPosition;
|
|
|
|
startPosition = data[position + 0xfd] << 8 + data[position+0xfe];
|
|
|
|
// 50 samples per 128 bytes
|
|
int startTime = (startPosition -position) * 50 / 128;
|
|
|
|
System.err.println(" Buffer "+ bufNumber + " (at position "+position+")...");
|
|
System.err.println(" Start position "+startPosition+" time "+startTime);
|
|
|
|
System.out.println("# Buffer "+bufNumber);
|
|
System.out.println("# Start position t="+startTime);
|
|
|
|
|
|
int t = 0;
|
|
for (int page = 0; page < 128; page++) {
|
|
int pageStart = position + page * 128;
|
|
|
|
if (pageStart == startPosition) {
|
|
System.out.println("# ---clip---");
|
|
}
|
|
|
|
for (int i=0; i<125; i += 5) {
|
|
int sample1, sample2;
|
|
|
|
int start = pageStart + i;
|
|
// System.err.println("page="+page+" i="+i+
|
|
// " position="+position+" pageStart="+pageStart+" start="+start);
|
|
|
|
sample1 = (data[start] << 2) + (data[start+1] >> 6);
|
|
sample2 = ((data[start+1] & 0x3f) << 4) + (data[start+2] >> 4);
|
|
System.out.printf("%d %4d %4d %4d\n", bufNumber, t, sample1, sample2);
|
|
t++;
|
|
|
|
sample1 = ((data[start+2] & 0x0f) << 6) + (data[start+3] >> 2);
|
|
sample2 = ((data[start+3] & 3) << 8) + data[start+4];
|
|
System.out.printf("%d %4d %4d %4d\n", bufNumber, t, sample1, sample2);
|
|
t++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void open() throws PortInUseException, IOException,
|
|
UnsupportedCommOperationException {
|
|
|
|
if (port != null) {
|
|
System.err.println("ERROR: open() called with port="+port);
|
|
Thread.dumpStack();
|
|
close();
|
|
}
|
|
|
|
if (DEBUG) {
|
|
System.err.println(" Opening port...");
|
|
}
|
|
|
|
port = (SerialPort)portID.open("OpenRocket",1000);
|
|
|
|
port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
|
|
SerialPort.PARITY_NONE);
|
|
|
|
port.setInputBufferSize(1);
|
|
port.setOutputBufferSize(1);
|
|
|
|
is = port.getInputStream();
|
|
os = port.getOutputStream();
|
|
}
|
|
|
|
|
|
private void close() {
|
|
if (DEBUG)
|
|
System.err.println(" Closing port");
|
|
|
|
SerialPort p = port;
|
|
port = null;
|
|
is = null;
|
|
if (p != null)
|
|
p.close();
|
|
}
|
|
|
|
|
|
|
|
private static int unsign(byte b) {
|
|
if (b >= 0)
|
|
return b;
|
|
else
|
|
return 256 + b;
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] arg) throws Exception {
|
|
|
|
if (arg.length > 2) {
|
|
System.err.println("Illegal arguments.");
|
|
return;
|
|
}
|
|
if (arg.length == 1) {
|
|
FileInputStream is = new FileInputStream(arg[0]);
|
|
byte[] buffer = new byte[BYTES];
|
|
int n = is.read(buffer);
|
|
if (n != BYTES) {
|
|
System.err.println("Could read only "+n+" bytes");
|
|
return;
|
|
}
|
|
|
|
int[] data = new int[BYTES];
|
|
for (int i=0; i<BYTES; i++) {
|
|
data[i] = unsign(buffer[i]);
|
|
}
|
|
|
|
int checksum=0;
|
|
for (int i=0; i<BYTES; i++) {
|
|
checksum += data[i];
|
|
}
|
|
checksum = checksum%256;
|
|
System.err.println("Checksum: "+checksum);
|
|
|
|
convertData(data);
|
|
return;
|
|
}
|
|
|
|
|
|
String device = null;
|
|
String[] devices = RotationLogger.getNames();
|
|
for (int i=0; i<devices.length; i++) {
|
|
if (devices[i].matches(".*USB.*")) {
|
|
device = devices[i];
|
|
break;
|
|
}
|
|
}
|
|
if (device == null) {
|
|
System.err.println("Device not found.");
|
|
return;
|
|
}
|
|
|
|
|
|
System.err.println("Selected device "+device);
|
|
|
|
|
|
RotationLogger p = new RotationLogger(device);
|
|
|
|
p.readData();
|
|
|
|
}
|
|
|
|
|
|
}
|