001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) FIRST 2008-2012. All Rights Reserved. */ 003/* Open Source Software - may be modified and shared by FRC teams. The code */ 004/* must be accompanied by the FIRST BSD license file in the root directory of */ 005/* the project. */ 006/*----------------------------------------------------------------------------*/ 007package edu.wpi.first.wpilibj; 008 009import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances; 010import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType; 011import edu.wpi.first.wpilibj.communication.UsageReporting; 012import edu.wpi.first.wpilibj.interfaces.Accelerometer; 013import edu.wpi.first.wpilibj.livewindow.LiveWindow; 014import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable; 015import edu.wpi.first.wpilibj.tables.ITable; 016 017/** 018 * 019 * @author dtjones 020 */ 021public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindowSendable { 022 023 private static final byte kAddress = 0x1D; 024 private static final byte kPowerCtlRegister = 0x2D; 025 private static final byte kDataFormatRegister = 0x31; 026 private static final byte kDataRegister = 0x32; 027 private static final double kGsPerLSB = 0.00390625; 028 private static final byte kPowerCtl_Link = 0x20, kPowerCtl_AutoSleep = 0x10, kPowerCtl_Measure = 0x08, kPowerCtl_Sleep = 0x04; 029 private static final byte kDataFormat_SelfTest = (byte) 0x80, kDataFormat_SPI = 0x40, kDataFormat_IntInvert = 0x20, kDataFormat_FullRes = 0x08, kDataFormat_Justify = 0x04; 030 031 public static class Axes { 032 033 /** 034 * The integer value representing this enumeration 035 */ 036 public final byte value; 037 static final byte kX_val = 0x00; 038 static final byte kY_val = 0x02; 039 static final byte kZ_val = 0x04; 040 public static final Axes kX = new Axes(kX_val); 041 public static final Axes kY = new Axes(kY_val); 042 public static final Axes kZ = new Axes(kZ_val); 043 044 private Axes(byte value) { 045 this.value = value; 046 } 047 } 048 049 public static class AllAxes { 050 051 public double XAxis; 052 public double YAxis; 053 public double ZAxis; 054 } 055 private I2C m_i2c; 056 057 /** 058 * Constructor. 059 * @param port The I2C port the accelerometer is attached to 060 * @param range The range (+ or -) that the accelerometer will measure. 061 */ 062 public ADXL345_I2C(I2C.Port port, Range range) { 063 m_i2c = new I2C(port, kAddress); 064 065 // Turn on the measurements 066 m_i2c.write(kPowerCtlRegister, kPowerCtl_Measure); 067 068 setRange(range); 069 070 UsageReporting.report(tResourceType.kResourceType_ADXL345, tInstances.kADXL345_I2C); 071 LiveWindow.addSensor("ADXL345_I2C", port.getValue(), this); 072 } 073 074 /** {inheritdoc} */ 075 @Override 076 public void setRange(Range range) { 077 byte value = 0; 078 079 switch(range) { 080 case k2G: 081 value = 0; 082 break; 083 case k4G: 084 value = 1; 085 break; 086 case k8G: 087 value = 2; 088 break; 089 case k16G: 090 value = 3; 091 break; 092 } 093 094 // Specify the data format to read 095 m_i2c.write(kDataFormatRegister, kDataFormat_FullRes | value); 096 } 097 098 /** {@inheritDoc} */ 099 @Override 100 public double getX() { 101 return getAcceleration(Axes.kX); 102 } 103 104 /** {@inheritDoc} */ 105 @Override 106 public double getY() { 107 return getAcceleration(Axes.kY); 108 } 109 110 /** {@inheritDoc} */ 111 @Override 112 public double getZ() { 113 return getAcceleration(Axes.kZ); 114 } 115 116 /** 117 * Get the acceleration of one axis in Gs. 118 * 119 * @param axis The axis to read from. 120 * @return Acceleration of the ADXL345 in Gs. 121 */ 122 public double getAcceleration(Axes axis) { 123 byte[] rawAccel = new byte[2]; 124 m_i2c.read(kDataRegister + axis.value, rawAccel.length, rawAccel); 125 126 // Sensor is little endian... swap bytes 127 return accelFromBytes(rawAccel[0], rawAccel[1]); 128 } 129 130 private double accelFromBytes(byte first, byte second) { 131 short tempLow = (short) (first & 0xff); 132 short tempHigh = (short) ((second << 8) & 0xff00); 133 return (tempLow | tempHigh) * kGsPerLSB; 134 } 135 136 /** 137 * Get the acceleration of all axes in Gs. 138 * 139 * @return An object containing the acceleration measured on each axis of the ADXL345 in Gs. 140 */ 141 public AllAxes getAccelerations() { 142 AllAxes data = new AllAxes(); 143 byte[] rawData = new byte[6]; 144 m_i2c.read(kDataRegister, rawData.length, rawData); 145 146 // Sensor is little endian... swap bytes 147 data.XAxis = accelFromBytes(rawData[0], rawData[1]); 148 data.YAxis = accelFromBytes(rawData[2], rawData[3]); 149 data.ZAxis = accelFromBytes(rawData[4], rawData[5]); 150 return data; 151 } 152 153 public String getSmartDashboardType(){ 154 return "3AxisAccelerometer"; 155 } 156 157 private ITable m_table; 158 159 /** {@inheritDoc} */ 160 public void initTable(ITable subtable) { 161 m_table = subtable; 162 updateTable(); 163 } 164 165 /** {@inheritDoc} */ 166 public void updateTable() { 167 if (m_table != null) { 168 m_table.putNumber("X", getX()); 169 m_table.putNumber("Y", getY()); 170 m_table.putNumber("Z", getZ()); 171 } 172 } 173 174 /** {@inheritDoc} */ 175 public ITable getTable(){ 176 return m_table; 177 } 178 179 public void startLiveWindowMode() {} 180 public void stopLiveWindowMode() {} 181}