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
008 package edu.wpi.first.wpilibj;
009
010 import edu.wpi.first.wpilibj.communication.UsageReporting;
011 import edu.wpi.first.wpilibj.livewindow.LiveWindow;
012 import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
013 import edu.wpi.first.wpilibj.parsing.ISensor;
014 import edu.wpi.first.wpilibj.tables.ITable;
015
016 /**
017 * HiTechnic NXT Compass.
018 *
019 * This class alows access to a HiTechnic NXT Compass on an I2C bus.
020 * These sensors to not allow changing addresses so you cannot have more
021 * than one on a single bus.
022 *
023 * Details on the sensor can be found here:
024 * http://www.hitechnic.com/index.html?lang=en-us&target=d17.html
025 *
026 */
027 public class HiTechnicCompass extends SensorBase implements ISensor, LiveWindowSendable, PIDSource {
028
029 /**
030 * An exception dealing with connecting to and communicating with the
031 * HiTechnicCompass
032 */
033 public class CompassException extends RuntimeException {
034
035 /**
036 * Create a new exception with the given message
037 * @param message the message to pass with the exception
038 */
039 public CompassException(String message) {
040 super(message);
041 }
042
043 }
044
045 private static final byte kAddress = 0x02;
046 private static final byte kManufacturerBaseRegister = 0x08;
047 private static final byte kManufacturerSize = 0x08;
048 private static final byte kSensorTypeBaseRegister = 0x10;
049 private static final byte kSensorTypeSize = 0x08;
050 private static final byte kHeadingRegister = 0x44;
051 private I2C m_i2c;
052
053 /**
054 * Constructor.
055 *
056 * @param slot The slot of the digital module that the sensor is plugged into.
057 */
058 public HiTechnicCompass(int slot) {
059 DigitalModule module = DigitalModule.getInstance(slot);
060 m_i2c = module.getI2C(kAddress);
061
062 // Verify Sensor
063 final byte[] kExpectedManufacturer = "HiTechnc".getBytes();
064 final byte[] kExpectedSensorType = "Compass ".getBytes();
065 if (!m_i2c.verifySensor(kManufacturerBaseRegister, kManufacturerSize, kExpectedManufacturer)) {
066 throw new CompassException("Invalid Compass Manufacturer");
067 }
068 if (!m_i2c.verifySensor(kSensorTypeBaseRegister, kSensorTypeSize, kExpectedSensorType)) {
069 throw new CompassException("Invalid Sensor type");
070 }
071
072 UsageReporting.report(UsageReporting.kResourceType_HiTechnicCompass, module.getModuleNumber()-1);
073 LiveWindow.addSensor("HiTechnicCompass", slot, 0, this);
074 }
075
076 /**
077 * Destructor.
078 */
079 public void free() {
080 if (m_i2c != null) {
081 m_i2c.free();
082 }
083 m_i2c = null;
084 }
085
086 /**
087 * Get the compass angle in degrees.
088 *
089 * The resolution of this reading is 1 degree.
090 *
091 * @return Angle of the compass in degrees.
092 */
093 public double getAngle() {
094 byte[] heading = new byte[2];
095 m_i2c.read(kHeadingRegister, (byte) heading.length, heading);
096
097 return ((int) heading[0] + (int) heading[1] * (int) (1 << 8));
098 }
099
100 public double pidGet() {
101 return getAngle();
102 }
103
104 /*
105 * Live Window code, only does anything if live window is activated.
106 */
107 public String getSmartDashboardType(){
108 return "Compass";
109 }
110 private ITable m_table;
111
112 /**
113 * {@inheritDoc}
114 */
115 public void initTable(ITable subtable) {
116 m_table = subtable;
117 updateTable();
118 }
119
120 /**
121 * {@inheritDoc}
122 */
123 public ITable getTable(){
124 return m_table;
125 }
126
127 /**
128 * {@inheritDoc}
129 */
130 public void updateTable() {
131 if (m_table != null) {
132 m_table.putNumber("Value", getAngle());
133 }
134 }
135
136 /**
137 * {@inheritDoc}
138 */
139 public void startLiveWindowMode() {}
140
141 /**
142 * {@inheritDoc}
143 */
144 public void stopLiveWindowMode() {}
145 }