lejos.hardware.sensor.HiTechnicAngleSensor Maven / Gradle / Ivy
Show all versions of lejos-ev3-api Show documentation
package lejos.hardware.sensor;
import lejos.hardware.port.I2CPort;
import lejos.hardware.port.Port;
import lejos.utility.Delay;
import lejos.utility.EndianTools;
/**
* Hitechnic Angle sensor
* The Angle sensor measures axle rotation position and rotation speed.
*
*
* The code for this sensor has not been tested. Please report test results to
* the leJOS forum.
*
*
*
*
*
* Supported modes
*
*
* Mode name
* Description
* unit(s)
* Getter
*
*
* Absolute angle
* Measures the rotation position of a rotating axle
* Degrees (0-359)
* {@link #getAngleMode() }
*
*
* Accumulated angle
* Measures the accumulated number of degrees an axle has rotated
* Degrees
* {@link #getAccumulatedAngleMode() }
*
*
* Angular velocity
* the speed of the axle rotation
* rotations / second
* {@link #getAngularVelocityMode() }
*
*
*
*
*
* Sensor configuration
* The zero position of the sensor can be set and stored in the sensors memory
* using the calibrateAngle method. The accumulated angle can be set to zero
* using the resetAccumulatedAngle method. The accumulated angle is not stored
* in memory.
*
*
*
* See
* Sensor Product page
* See The
* leJOS sensor framework
* See {@link lejos.robotics.SampleProvider leJOS conventions for
* SampleProviders}
*
*
*
*
*
*/
public class HiTechnicAngleSensor extends I2CSensor {
protected static final int REG_ANGLE = 0x42;
protected static final int REG_ACCUMULATED_ANGLE = 0x44;
protected static final int REG_SPEED = 0x48;
protected static final int HTANGLE_MODE_CALIBRATE = 0x43;
protected static final int HTANGLE_MODE_RESET = 0x52;
private byte buf[] = new byte[4];
public HiTechnicAngleSensor(I2CPort port) {
super(port, DEFAULT_I2C_ADDRESS);
init();
}
public HiTechnicAngleSensor(Port port) {
super(port);
init();
}
protected void init() {
setModes(new SensorMode[] { new AngleMode(), new AccumulatedAngleMode(),
new AngularVelocityMode() });
}
/**
* Reset the rotation count of accumulated angle to zero. Not saved in EEPORM.
*/
public void resetAccumulatedAngle() {
sendData(0x41, (byte) HTANGLE_MODE_RESET);
}
/**
* Calibrate the zero position of angle. Zero position is saved in EEPROM on
* sensor. Thread sleeps for 50ms while that is done.
*/
public void calibrateAngle() {
sendData(0x41, (byte) HTANGLE_MODE_CALIBRATE);
Delay.msDelay(50);
}
/**
* HiTechnic angle sensor, Angle mode
* Measures the rotation position of a rotating axle.
*
*
* Size and content of the sample
* The sample contains one elements containing the angle of the sensor in the range of 0 to 359 degrees.
*
*/
public SensorMode getAngleMode() {
return getMode(0);
}
private class AngleMode implements SensorMode {
@Override
public int sampleSize() {
return 1;
}
@Override
public void fetchSample(float[] sample, int offset) {
getData(REG_ANGLE, buf, 2);
int bits9to2 = buf[0] & 0xFF;
int bit1 = buf[1] & 0x01;
sample[offset] = (bits9to2 << 1) | bit1;
}
@Override
public String getName() {
return "Angle";
}
}
/**
* HiTechnic angle sensor, Accumulated angle mode
* Measures the accumulated number of degrees an axle has rotated.
*
*
* Size and content of the sample
* The sample contains one elements containing the accumulated rotation (in degrees) of the axle.
*/
public SensorMode getAccumulatedAngleMode() {
return getMode(1);
}
private class AccumulatedAngleMode implements SensorMode {
@Override
public int sampleSize() {
return 1;
}
@Override
public void fetchSample(float[] sample, int offset) {
getData(REG_ACCUMULATED_ANGLE, buf, 4);
sample[offset] = -EndianTools.decodeIntBE(buf, 0);
}
@Override
public String getName() {
return "AccumulatedAngle";
}
}
/**
* HiTechnic angle sensor, Angular velocity mode
* Measures the rotational speed of an axle.
*
*
* Size and content of the sample
* The sample contains one elements containing the angular velocity (in degrees) of the axle.
*/
public SensorMode getAngularVelocityMode() {
return getMode(2);
}
private class AngularVelocityMode implements SensorMode {
@Override
public int sampleSize() {
return 1;
}
@Override
public void fetchSample(float[] sample, int offset) {
getData(REG_SPEED, buf, 2);
// 1 rpm = 360°/60sec = 6°/sec
//FIXME shouldn't we multiply by 6 instead of dividing by 60?
sample[offset] = -EndianTools.decodeShortBE(buf, 0) / 60f;
}
@Override
public String getName() {
return "AngularVelocity";
}
}
}