|
| 1 | +#include <Wire.h> |
| 2 | +#include <DigiKeyboard.h> |
| 3 | +#define ADXL345 (0x53) //address of Accelerometer |
| 4 | +#define ADXL345_X (0x32) //register for X value from Accelerometer |
| 5 | +#define ADXL345_Y (0x34) //register for Y value from Accelerometer |
| 6 | +#define ADXL345_Z (0x36) //register for Z value from Accelerometer |
| 7 | +#define HMC5883 (0x1E) //address of Magnetometer |
| 8 | +#define ITG3200 (0x68) //address of Gyro |
| 9 | +int16_t magX = 0; //X value from Magnetometer |
| 10 | +int16_t magY = 0; //Y value from Magnetometer |
| 11 | +int16_t magZ = 0; //Z value from Magnetometer |
| 12 | +int gyroHX = 0; //HX value from Gyro |
| 13 | +int gyroHY = 0; //HY value from Gyro |
| 14 | +int gyroHZ = 0; //HZ value from Gyro |
| 15 | +void setup() |
| 16 | +{ |
| 17 | + Wire.begin(); |
| 18 | + |
| 19 | + initAccelerometer(); |
| 20 | + |
| 21 | + initMagnetometer(); |
| 22 | + |
| 23 | + initGyro(); |
| 24 | + |
| 25 | +} |
| 26 | + |
| 27 | + |
| 28 | +void loop() |
| 29 | +{ |
| 30 | + |
| 31 | + DigiKeyboard.println(readAccelerometer(ADXL345_X)); |
| 32 | + DigiKeyboard.println(readAccelerometer(ADXL345_Y)); |
| 33 | + DigiKeyboard.println(readAccelerometer(ADXL345_Z)); |
| 34 | + DigiKeyboard.delay(1000); |
| 35 | + readMagnetometer(); |
| 36 | + DigiKeyboard.println(magX); |
| 37 | + DigiKeyboard.println(magY); |
| 38 | + DigiKeyboard.println(magZ); |
| 39 | + DigiKeyboard.println(getHeading()); |
| 40 | + DigiKeyboard.delay(1000); |
| 41 | + readGyro(); |
| 42 | + DigiKeyboard.println(gyroHX); |
| 43 | + DigiKeyboard.println(gyroHY); |
| 44 | + DigiKeyboard.println(gyroHZ); |
| 45 | + DigiKeyboard.delay(1000); |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | +} |
| 50 | + |
| 51 | + |
| 52 | + |
| 53 | +void initGyro(){ |
| 54 | + writeRegister(ITG3200, 0x3E, 0x00); //enable |
| 55 | + writeRegister(ITG3200, 0x15, 0x07); // EB, 50, 80, 7F, DE, 23, 20, FF |
| 56 | + writeRegister(ITG3200, 0x16, 0x1E); // +/- 2000 dgrs/sec, 1KHz, 1E, 19 |
| 57 | + writeRegister(ITG3200, 0x17, 0x00); |
| 58 | +} |
| 59 | + |
| 60 | +void readGyro(){ |
| 61 | + Wire.beginTransmission(ITG3200); |
| 62 | + Wire.write(0x1B); //format x y z temp |
| 63 | + Wire.endTransmission(); |
| 64 | + Wire.requestFrom(ITG3200, (byte)8); |
| 65 | + |
| 66 | + // Wait around until enough data is available |
| 67 | + while (Wire.available() < 8); |
| 68 | + uint8_t lo = Wire.read(); |
| 69 | + uint8_t hi = Wire.read(); |
| 70 | + //throw out first two - don't seem accurate |
| 71 | + //gyroTemp = (lo << 8) | hi; // temperature |
| 72 | + //gyroTemp = ((double) (gyroTemp + 13200)) / 280; |
| 73 | + lo = Wire.read(); |
| 74 | + hi = Wire.read(); |
| 75 | + gyroHX = (((lo << 8) | hi) + 120 )/ 14.375; |
| 76 | + lo = Wire.read(); |
| 77 | + hi = Wire.read(); |
| 78 | + gyroHY = (((lo << 8) | hi) + 20 )/ 14.375; |
| 79 | + lo = Wire.read(); |
| 80 | + hi = Wire.read(); |
| 81 | + gyroHZ = (((lo << 8) | hi) + 93 )/ 14.375; |
| 82 | + |
| 83 | +} |
| 84 | + |
| 85 | +void initMagnetometer(){ |
| 86 | + writeRegister(HMC5883, 0x02, 0x00); //enable |
| 87 | +} |
| 88 | + |
| 89 | + |
| 90 | +void readMagnetometer(){ |
| 91 | + Wire.beginTransmission(HMC5883); |
| 92 | + Wire.write(0x03); //format X_H_M |
| 93 | + Wire.endTransmission(); |
| 94 | + Wire.requestFrom(HMC5883, (byte)6); |
| 95 | + |
| 96 | + // Wait around until enough data is available |
| 97 | + while (Wire.available() < 6); |
| 98 | + |
| 99 | + // Note high before low (different than accel) |
| 100 | + uint8_t hi = Wire.read(); |
| 101 | + uint8_t lo = Wire.read(); |
| 102 | + // Shift values to create properly formed integer (low byte first) |
| 103 | + magX = (int16_t)(hi | ((int16_t)lo << 8)); |
| 104 | + // Note high before low (different than accel) |
| 105 | + hi = Wire.read(); |
| 106 | + lo = Wire.read(); |
| 107 | + // Shift values to create properly formed integer (low byte first) |
| 108 | + magY = (int16_t)(hi | ((int16_t)lo << 8)); |
| 109 | + // Note high before low (different than accel) |
| 110 | + hi = Wire.read(); |
| 111 | + lo = Wire.read(); |
| 112 | + // Shift values to create properly formed integer (low byte first) |
| 113 | + magZ = (int16_t)(hi | ((int16_t)lo << 8)); |
| 114 | +} |
| 115 | + |
| 116 | +void initAccelerometer(){ |
| 117 | + //if(readRegister(ADXL345,0x00) != 0xE5) |
| 118 | + writeRegister(ADXL345, 0x2D, 0x08); //power up and enable measurements |
| 119 | + writeRegister(ADXL345, 0x31, 0x01);//set range to +/-4G |
| 120 | +} |
| 121 | + |
| 122 | +uint16_t readAccelerometer(uint8_t reg){ |
| 123 | + Wire.beginTransmission(ADXL345); |
| 124 | + Wire.write(reg); |
| 125 | + Wire.endTransmission(); |
| 126 | + Wire.requestFrom(ADXL345, 2); |
| 127 | + return (uint16_t)(Wire.read() | (Wire.read() << 8)); |
| 128 | +} |
| 129 | + |
| 130 | +uint8_t readRegister(uint8_t address, uint8_t reg){ |
| 131 | + Wire.beginTransmission(address); |
| 132 | + Wire.write(reg); |
| 133 | + Wire.endTransmission(); |
| 134 | + Wire.requestFrom(address, 1); |
| 135 | + return Wire.read(); |
| 136 | + } |
| 137 | +void writeRegister(uint8_t address, uint8_t reg, uint8_t val){ |
| 138 | + Wire.beginTransmission(address); |
| 139 | + Wire.write(reg); |
| 140 | + Wire.write(val); |
| 141 | + Wire.endTransmission(); |
| 142 | + } |
| 143 | + |
| 144 | +float getHeading(){ |
| 145 | + // Hold the module so that Z is pointing 'up' and you can measure the heading with x&y |
| 146 | + // Calculate heading when the magnetometer is level, then correct for signs of axis. |
| 147 | + float heading = atan2(magY, magX); |
| 148 | + // Correct for when signs are reversed. |
| 149 | + if(heading < 0) |
| 150 | + heading += 2*PI; |
| 151 | + // Check for wrap due to addition of declination. |
| 152 | + if(heading > 2*PI) |
| 153 | + heading -= 2*PI; |
| 154 | + // Convert radians to degrees for readability. |
| 155 | + heading = heading * 180/M_PI; |
| 156 | + return heading; |
| 157 | +} |
0 commit comments