package lejos.nxt.remote; import lejos.nxt.*; import java.io.*; /** * Emulates a Sensor Port using LCP */ public class RemoteSensorPort implements NXTProtocol, ADSensorPort, I2CPort { private int id; private int type, mode; private NXTCommand nxtCommand; public RemoteSensorPort(NXTCommand nxtCommand, int id) { this.nxtCommand = nxtCommand; this.id = id; } /** * Get the port number * @return the port number */ public int getId() { return id; } /** * Get the sensor type * @return the sensor type */ public int getType() { return type; } /** * Get the sensor mode * @return the sensor mode */ public int getMode() { return mode; } /** * Set the sensor type and mode * @param type the sensor type * @param mode the sensor mode */ public void setTypeAndMode(int type, int mode) { this.type = type; this.mode = mode; try { nxtCommand.setInputMode(id, type, mode); } catch (IOException ioe) {} } /** * Set the sensor type * @param type the sensor type */ public void setType(int type) { this.type = type; setTypeAndMode(type, mode); } /** * Set the sensor mode * @param mode the sensor mode */ public void setMode(int mode) { this.mode = mode; setTypeAndMode(type, mode); } /** * Reads the boolean value of the sensor. * @return Boolean value of sensor. */ public boolean readBooleanValue() { try { InputValues vals = nxtCommand.getInputValues(id); return (vals.rawADValue<600); } catch (IOException ioe) { return false; } } /** * Reads the raw value of the sensor. * @return Raw sensor value. Range is device dependent. */ public int readRawValue() { try { InputValues vals = nxtCommand.getInputValues(id); return vals.rawADValue; } catch (IOException ioe) { return 0; } } /** * Returns value compatible with Lego firmware. */ public int readValue() { int rawValue = readRawValue(); if (mode == MODE_BOOLEAN) { return (rawValue < 600 ? 1 : 0); } if (mode == MODE_PCTFULLSCALE) { return ((1023 - rawValue) * 100/ 1023); } return rawValue; } /** * Get the NXTCommand object used for remote access * @return the NXTCommand object */ public NXTCommand getNXTCommand() { return nxtCommand; } /** * Test if I2C is busy * @return the status value (see ErrorMessages) */ public int i2cBusy() { try { byte[] status = nxtCommand.LSGetStatus((byte) id); return (int) status[0]; } catch (IOException ioe) { return -1; } } /** * Disable I2C on the port - null for remote ports */ public void i2cDisable() { } /** * Enable I2C on the port - null for remote ports */ public void i2cEnable(int mode) { } /** * Start an I2C transaction. The remote implementation is synchronous. * @param address the I2C address (x01 - x7F) * @param internalAddress the register or internal address * @param numInternalBytes not used * @param buffer the buffer for reading or writing data * @param numBytes the number of bytes to read or write * @param transferType 0 for read, 1 for write * @return the status value */ public int i2cStart(int address, int internalAddress, int numInternalBytes, byte[] buffer, int numBytes, int transferType) { byte [] txData = {(byte) (address << 1), (byte) internalAddress}; int status; try { nxtCommand.LSWrite((byte) id, txData, (byte) numBytes); } catch (IOException ioe) { return -1; } do { status = i2cBusy(); } while (status == ErrorMessages.PENDING_COMMUNICATION_TRANSACTION_IN_PROGRESS || status == ErrorMessages.SPECIFIED_CHANNEL_CONNECTION_NOT_CONFIGURED_OR_BUSY); if (status != 0) return status; return 0; } public int i2cComplete(byte[] buffer, int numBytes) { try { byte [] ret = nxtCommand.LSRead((byte) id); if (ret == null) return -1; if (numBytes > ret.length) numBytes = ret.length; System.arraycopy(ret, 0, buffer, 0, numBytes); } catch (IOException ioe) { return -1; } return numBytes; } }