lejos.hardware.sensor.I2CSensor 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.lang.IllegalArgumentException;
import lejos.hardware.port.I2CException;
import lejos.hardware.port.I2CPort;
import lejos.hardware.port.Port;
/**
* Class that implements common methods for all I2C sensors.
*
* Extend this class to implement new I2C sensors.
*
* TODO: We should probably change this class to use the Product ID etc. obtained
* by the Lego kernel module during initialisation.
*
* @author Lawrie Griffiths ([email protected]) and Andy Shaw.
*
*/
public class I2CSensor extends BaseSensor implements SensorConstants {
/**
* Register number of sensor version string, as defined by standard Lego I2C register layout.
* @see #getVersion()
*/
protected static final byte REG_VERSION = 0x00;
/**
* Register number of sensor vendor ID, as defined by standard Lego I2C register layout.
* @see #getVendorID()
*/
protected static final byte REG_VENDOR_ID = 0x08;
/**
* Register number of sensor product ID, as defined by standard Lego I2C register layout.
* @see #getProductID()
*/
protected static final byte REG_PRODUCT_ID = 0x10;
protected static final int DEFAULT_I2C_ADDRESS = 0x02;
protected I2CPort port;
protected int address;
private byte[] ioBuf = new byte[32];
protected int retryCount = 3;
/**
* Create the sensor using an already open sensor port. Do not configure the hardware
* @param port the open port
* @param address I2C address
*/
public I2CSensor(I2CPort port, int address)
{
this.port = port;
this.address = address;
}
public I2CSensor(I2CPort port)
{
this(port, DEFAULT_I2C_ADDRESS);
}
/**
* Create the sensor using the specified port. Configure the hardware as required.
* @param port port the sensor is attached to
* @param address I2C address
* @param type type of I2C sensor
*/
public I2CSensor(Port port, int address, int type)
{
this(port.open(I2CPort.class), address);
if (!this.port.setType(type))
{
this.port.close();
throw new IllegalArgumentException("Invalid sensor mode");
}
releaseOnClose(this.port);
}
public I2CSensor(Port port)
{
this(port, DEFAULT_I2C_ADDRESS, TYPE_LOWSPEED);
}
public I2CSensor(Port port, int address)
{
this(port, address, TYPE_LOWSPEED);
}
/**
* Set the number of times that a get/send data request should be retried.
* @param newCount number of times to try the request
*/
public void setRetryCount(int newCount)
{
if (newCount <= 0)
throw new IllegalArgumentException("Invalid retry count");
retryCount = newCount;
}
/**
* Return the current get/send retry count value
* @return current retry count
*/
public int getRetryCount()
{
return retryCount;
}
/**
* Executes an I2C read transaction and waits for the result.
*
* @param register I2C register, e.g 0x41
* @param buf Buffer to return data
* @param len Length of the return data
*/
public void getData(int register, byte [] buf, int len) {
getData(register, buf, 0, len);
}
/**
* Executes an I2C read transaction and waits for the result.
*
* @param register I2C register, e.g 0x41
* @param buf Buffer to return data
* @param offset Offset of the start of the data
* @param len Length of the return data
*/
public synchronized void getData(int register, byte [] buf, int offset, int len) {
// need to write the internal address.
ioBuf[0] = (byte)register;
I2CException error = null;
for(int i = 0; i < retryCount; i++)
{
try {
port.i2cTransaction(address, ioBuf, 0, 1, buf, offset, len);
return;
}
catch (I2CException e)
{
error = e;
}
}
throw error;
}
/**
* Executes an I2C write transaction.
*
* @param register I2C register, e.g 0x42
* @param buf Buffer containing data to send
* @param len Length of data to send
*/
public void sendData(int register, byte [] buf, int len) {
sendData(register, buf, 0, len);
}
/**
* Executes an I2C write transaction.
*
* @param register I2C register, e.g 0x42
* @param buf Buffer containing data to send
* @param offset Offset of the start of the data
* @param len Length of data to send
*/
public synchronized void sendData(int register, byte [] buf, int offset, int len) {
if (len >= ioBuf.length)
throw new IllegalArgumentException("Invalid buffer length");
ioBuf[0] = (byte)register;
// avoid NPE in case length==0 and data==null
if (buf != null)
System.arraycopy(buf, offset, ioBuf, 1, len);
I2CException error = null;
for(int i = 0; i < retryCount; i++)
{
try {
port.i2cTransaction(address, ioBuf, 0, len+1, null, 0, 0);
return;
}
catch (I2CException e)
{
error = e;
}
}
throw error;
}
/**
* Executes an I2C write transaction.
*
* @param register I2C register, e.g 0x42
* @param value single byte to send
*/
public synchronized void sendData(int register, byte value) {
ioBuf[0] = (byte)register;
ioBuf[1] = value;
sendData(register, null, 0, 1);
}
/**
* Read the sensor's version string.
* This method reads up to 8 bytes
* and returns the characters before the zero termination byte.
* Examples: "V1.0", ...
*
* @return version number
*/
public String getVersion() {
return fetchString(REG_VERSION, 8);
}
/**
* Read the sensor's vendor identifier.
* This method reads up to 8 bytes
* and returns the characters before the zero termination byte.
* Examples: "LEGO", "HiTechnc", ...
*
* @return vendor identifier
*/
public String getVendorID() {
return fetchString(REG_VENDOR_ID, 8);
}
/**
* Read the sensor's product identifier.
* This method reads up to 8 bytes
* and returns the characters before the zero termination byte.
* Examples: "Sonar", ...
*
* @return product identifier
*/
public String getProductID() {
return fetchString(REG_PRODUCT_ID, 8);
}
/**
* Read a string from the device.
* This functions reads the specified number of bytes
* and returns the characters before the zero termination byte.
*
* @param reg
* @param len maximum length of the string, including the zero termination byte
* @return the string containing the characters before the zero termination byte
*/
protected String fetchString(byte reg, int len) {
byte[] buf = new byte[len];
try
{
getData(reg, buf, 0, len);
}
catch (I2CException e)
{
return "";
}
int i;
char[] charBuff = new char[len];
for (i=0; i