All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lejos.hardware.sensor.I2CSensor Maven / Gradle / Ivy

Go to download

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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy