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 /*----------------------------------------------------------------------------*/ 007 package edu.wpi.first.wpilibj; 008 009 import edu.wpi.first.wpilibj.communication.UsageReporting; 010 011 /** 012 * 013 * @author dtjones 014 */ 015 public class ADXL345_I2C extends SensorBase { 016 017 private static final byte kAddress = 0x3A; 018 private static final byte kPowerCtlRegister = 0x2D; 019 private static final byte kDataFormatRegister = 0x31; 020 private static final byte kDataRegister = 0x32; 021 private static final double kGsPerLSB = 0.00390625; 022 private static final byte kPowerCtl_Link = 0x20, kPowerCtl_AutoSleep = 0x10, kPowerCtl_Measure = 0x08, kPowerCtl_Sleep = 0x04; 023 private static final byte kDataFormat_SelfTest = (byte) 0x80, kDataFormat_SPI = 0x40, kDataFormat_IntInvert = 0x20, kDataFormat_FullRes = 0x08, kDataFormat_Justify = 0x04; 024 025 public static class DataFormat_Range { 026 027 /** 028 * The integer value representing this enumeration 029 */ 030 public final byte value; 031 static final byte k2G_val = 0x00; 032 static final byte k4G_val = 0x01; 033 static final byte k8G_val = 0x02; 034 static final byte k16G_val = 0x03; 035 public static final DataFormat_Range k2G = new DataFormat_Range(k2G_val); 036 public static final DataFormat_Range k4G = new DataFormat_Range(k4G_val); 037 public static final DataFormat_Range k8G = new DataFormat_Range(k8G_val); 038 public static final DataFormat_Range k16G = new DataFormat_Range(k16G_val); 039 040 private DataFormat_Range(byte value) { 041 this.value = value; 042 } 043 } 044 045 public static class Axes { 046 047 /** 048 * The integer value representing this enumeration 049 */ 050 public final byte value; 051 static final byte kX_val = 0x00; 052 static final byte kY_val = 0x02; 053 static final byte kZ_val = 0x04; 054 public static final Axes kX = new Axes(kX_val); 055 public static final Axes kY = new Axes(kY_val); 056 public static final Axes kZ = new Axes(kZ_val); 057 058 private Axes(byte value) { 059 this.value = value; 060 } 061 } 062 063 public static class AllAxes { 064 065 public double XAxis; 066 public double YAxis; 067 public double ZAxis; 068 } 069 private I2C m_i2c; 070 071 /** 072 * Constructor. 073 * 074 * @param module The slot of the digital module that the sensor is plugged into. 075 * @param range The range (+ or -) that the accelerometer will measure. 076 */ 077 public ADXL345_I2C(int moduleNumber, DataFormat_Range range) { 078 DigitalModule module = DigitalModule.getInstance(moduleNumber); 079 m_i2c = module.getI2C(kAddress); 080 081 // Turn on the measurements 082 m_i2c.write(kPowerCtlRegister, kPowerCtl_Measure); 083 // Specify the data format to read 084 m_i2c.write(kDataFormatRegister, kDataFormat_FullRes | range.value); 085 086 UsageReporting.report(UsageReporting.kResourceType_ADXL345, UsageReporting.kADXL345_I2C, moduleNumber-1); 087 } 088 089 /** 090 * Get the acceleration of one axis in Gs. 091 * 092 * @param axis The axis to read from. 093 * @return Acceleration of the ADXL345 in Gs. 094 */ 095 public double getAcceleration(Axes axis) { 096 byte[] rawAccel = new byte[2]; 097 m_i2c.read(kDataRegister + axis.value, rawAccel.length, rawAccel); 098 099 // Sensor is little endian... swap bytes 100 return accelFromBytes(rawAccel[0], rawAccel[1]); 101 } 102 103 private double accelFromBytes(byte first, byte second) { 104 short tempLow = (short) (first & 0xff); 105 short tempHigh = (short) ((second << 8) & 0xff00); 106 return (tempLow | tempHigh) * kGsPerLSB; 107 } 108 109 /** 110 * Get the acceleration of all axes in Gs. 111 * 112 * @return Acceleration measured on all axes of the ADXL345 in Gs. 113 */ 114 public AllAxes getAccelerations() { 115 AllAxes data = new AllAxes(); 116 byte[] rawData = new byte[6]; 117 m_i2c.read(kDataRegister, rawData.length, rawData); 118 119 // Sensor is little endian... swap bytes 120 data.XAxis = accelFromBytes(rawData[0], rawData[1]); 121 data.YAxis = accelFromBytes(rawData[2], rawData[3]); 122 data.ZAxis = accelFromBytes(rawData[4], rawData[5]); 123 return data; 124 } 125 126 // TODO: Support LiveWindow 127 }