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 }