code for the left controller (Niimote)

Dependencies:   PinDetect_hw3 USBDevice mbed

Committer:
franklu
Date:
Mon Sep 21 15:22:04 2015 +0000
Revision:
2:e3a7b0fd4a59
Parent:
1:8252a6052ebe
changed main names;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
franklu 1:8252a6052ebe 1 #include "mbed.h"
franklu 1:8252a6052ebe 2 #include "USBKeyboard.h"
franklu 1:8252a6052ebe 3 #include "PinDetect.h"
franklu 1:8252a6052ebe 4
franklu 1:8252a6052ebe 5 /* Testing example code from Simon Scott on using BNO055. */
franklu 1:8252a6052ebe 6
franklu 1:8252a6052ebe 7 USBKeyboard keyboard;
franklu 1:8252a6052ebe 8
franklu 1:8252a6052ebe 9 Serial pc(USBTX,USBRX);
franklu 1:8252a6052ebe 10 I2C i2c(A4, A5);
franklu 1:8252a6052ebe 11
franklu 1:8252a6052ebe 12 DigitalOut led(LED1);
franklu 1:8252a6052ebe 13 DigitalOut led2(LED2);
franklu 1:8252a6052ebe 14
franklu 1:8252a6052ebe 15 const int bno055_addr = 0x28 << 1;
franklu 1:8252a6052ebe 16
franklu 1:8252a6052ebe 17 const int BNO055_ID_ADDR = 0x00;
franklu 1:8252a6052ebe 18 const int BNO055_EULER_H_LSB_ADDR = 0x1A;
franklu 1:8252a6052ebe 19 const int BNO055_TEMP_ADDR = 0x34;
franklu 1:8252a6052ebe 20 const int BNO055_OPR_MODE_ADDR = 0x3D;
franklu 1:8252a6052ebe 21 const int BNO055_CALIB_STAT_ADDR = 0x35;
franklu 1:8252a6052ebe 22 const int BNO055_SYS_STAT_ADDR = 0x39;
franklu 1:8252a6052ebe 23 const int BNO055_SYS_ERR_ADDR = 0x3A;
franklu 1:8252a6052ebe 24 const int BNO055_AXIS_MAP_CONFIG_ADDR = 0x41;
franklu 1:8252a6052ebe 25 const int BNO055_SYS_TRIGGER_ADDR = 0x3F;
franklu 1:8252a6052ebe 26
franklu 1:8252a6052ebe 27 typedef struct CalibStatus_t
franklu 1:8252a6052ebe 28 {
franklu 1:8252a6052ebe 29 int mag;
franklu 1:8252a6052ebe 30 int acc;
franklu 1:8252a6052ebe 31 int gyr;
franklu 1:8252a6052ebe 32 int sys;
franklu 1:8252a6052ebe 33 } CalibStatus;
franklu 1:8252a6052ebe 34
franklu 1:8252a6052ebe 35 typedef struct Euler_t
franklu 1:8252a6052ebe 36 {
franklu 1:8252a6052ebe 37 float heading;
franklu 1:8252a6052ebe 38 float pitch;
franklu 1:8252a6052ebe 39 float roll;
franklu 1:8252a6052ebe 40 } Euler;
franklu 1:8252a6052ebe 41
franklu 1:8252a6052ebe 42 Euler calibrationVals;
franklu 1:8252a6052ebe 43 /**
franklu 1:8252a6052ebe 44 * Function to write to a single 8-bit register
franklu 1:8252a6052ebe 45 */
franklu 1:8252a6052ebe 46 void writeReg(int regAddr, char value)
franklu 1:8252a6052ebe 47 {
franklu 1:8252a6052ebe 48 char wbuf[2];
franklu 1:8252a6052ebe 49 wbuf[0] = regAddr;
franklu 1:8252a6052ebe 50 wbuf[1] = value;
franklu 1:8252a6052ebe 51 i2c.write(bno055_addr, wbuf, 2, false);
franklu 1:8252a6052ebe 52 }
franklu 1:8252a6052ebe 53
franklu 1:8252a6052ebe 54 /**
franklu 1:8252a6052ebe 55 * Function to read from a single 8-bit register
franklu 1:8252a6052ebe 56 */
franklu 1:8252a6052ebe 57 char readReg(int regAddr)
franklu 1:8252a6052ebe 58 {
franklu 1:8252a6052ebe 59 char rwbuf = regAddr;
franklu 1:8252a6052ebe 60 i2c.write(bno055_addr, &rwbuf, 1, false);
franklu 1:8252a6052ebe 61 i2c.read(bno055_addr, &rwbuf, 1, false);
franklu 1:8252a6052ebe 62 return rwbuf;
franklu 1:8252a6052ebe 63 }
franklu 1:8252a6052ebe 64
franklu 1:8252a6052ebe 65 /**
franklu 1:8252a6052ebe 66 * Returns the calibration status of each component
franklu 1:8252a6052ebe 67 */
franklu 1:8252a6052ebe 68 CalibStatus readCalibrationStatus()
franklu 1:8252a6052ebe 69 {
franklu 1:8252a6052ebe 70 CalibStatus status;
franklu 1:8252a6052ebe 71 int regVal = readReg(BNO055_CALIB_STAT_ADDR);
franklu 1:8252a6052ebe 72
franklu 1:8252a6052ebe 73 status.mag = regVal & 0x03;
franklu 1:8252a6052ebe 74 status.acc = (regVal >> 2) & 0x03;
franklu 1:8252a6052ebe 75 status.gyr = (regVal >> 4) & 0x03;
franklu 1:8252a6052ebe 76 status.sys = (regVal >> 6) & 0x03;
franklu 1:8252a6052ebe 77
franklu 1:8252a6052ebe 78 return status;
franklu 1:8252a6052ebe 79 }
franklu 1:8252a6052ebe 80
franklu 1:8252a6052ebe 81
franklu 1:8252a6052ebe 82 /**
franklu 1:8252a6052ebe 83 * Checks that there are no errors on the accelerometer
franklu 1:8252a6052ebe 84 */
franklu 1:8252a6052ebe 85 bool bno055Healthy()
franklu 1:8252a6052ebe 86 {
franklu 1:8252a6052ebe 87 int sys_error = readReg(BNO055_SYS_ERR_ADDR);
franklu 1:8252a6052ebe 88 wait(0.001);
franklu 1:8252a6052ebe 89 int sys_stat = readReg(BNO055_SYS_STAT_ADDR);
franklu 1:8252a6052ebe 90 wait(0.001);
franklu 1:8252a6052ebe 91
franklu 1:8252a6052ebe 92 if(sys_error == 0 && sys_stat == 5)
franklu 1:8252a6052ebe 93 return true;
franklu 1:8252a6052ebe 94 else
franklu 1:8252a6052ebe 95 return false;
franklu 1:8252a6052ebe 96 }
franklu 1:8252a6052ebe 97
franklu 1:8252a6052ebe 98 /**
franklu 1:8252a6052ebe 99 * Reads the Euler angles, zeroed out
franklu 1:8252a6052ebe 100 */
franklu 1:8252a6052ebe 101 Euler getEulerAngles()
franklu 1:8252a6052ebe 102 {
franklu 1:8252a6052ebe 103 char buf[16];
franklu 1:8252a6052ebe 104 Euler e;
franklu 1:8252a6052ebe 105
franklu 1:8252a6052ebe 106 // Read in the Euler angles
franklu 1:8252a6052ebe 107 buf[0] = BNO055_EULER_H_LSB_ADDR;
franklu 1:8252a6052ebe 108 i2c.write(bno055_addr, buf, 1, false);
franklu 1:8252a6052ebe 109 i2c.read(bno055_addr, buf, 6, false);
franklu 1:8252a6052ebe 110
franklu 1:8252a6052ebe 111 short int euler_head = buf[0] + (buf[1] << 8);
franklu 1:8252a6052ebe 112 short int euler_roll = buf[2] + (buf[3] << 8);
franklu 1:8252a6052ebe 113 short int euler_pitch = buf[4] + (buf[5] << 8);
franklu 1:8252a6052ebe 114
franklu 1:8252a6052ebe 115 e.heading = ((float)euler_head) / 16.0;
franklu 1:8252a6052ebe 116 e.roll = ((float)euler_roll) / 16.0;
franklu 1:8252a6052ebe 117 e.pitch = ((float)euler_pitch) / 16.0;
franklu 1:8252a6052ebe 118
franklu 1:8252a6052ebe 119 return e;
franklu 1:8252a6052ebe 120 }
franklu 1:8252a6052ebe 121
franklu 1:8252a6052ebe 122
franklu 1:8252a6052ebe 123
franklu 1:8252a6052ebe 124 /**
franklu 1:8252a6052ebe 125 * Configure and initialize the BNO055
franklu 1:8252a6052ebe 126 */
franklu 1:8252a6052ebe 127 bool initBNO055()
franklu 1:8252a6052ebe 128 {
franklu 1:8252a6052ebe 129 unsigned char regVal;
franklu 1:8252a6052ebe 130 i2c.frequency(400000);
franklu 1:8252a6052ebe 131 bool startupPass = true;
franklu 1:8252a6052ebe 132
franklu 1:8252a6052ebe 133 // Do some basic power-up tests
franklu 1:8252a6052ebe 134 regVal = readReg(BNO055_ID_ADDR);
franklu 1:8252a6052ebe 135 if(regVal == 0xA0)
franklu 1:8252a6052ebe 136 pc.printf("BNO055 successfully detected!\r\n");
franklu 1:8252a6052ebe 137 else {
franklu 1:8252a6052ebe 138 pc.printf("ERROR: no BNO055 detected\r\n");
franklu 1:8252a6052ebe 139 startupPass = false;
franklu 1:8252a6052ebe 140 }
franklu 1:8252a6052ebe 141
franklu 1:8252a6052ebe 142 regVal = readReg(BNO055_TEMP_ADDR);
franklu 1:8252a6052ebe 143 pc.printf("Chip temperature is: %d C\r\n", regVal);
franklu 1:8252a6052ebe 144
franklu 1:8252a6052ebe 145 if(regVal == 0)
franklu 1:8252a6052ebe 146 startupPass = false;
franklu 1:8252a6052ebe 147
franklu 1:8252a6052ebe 148 // Change mode to CONFIG
franklu 1:8252a6052ebe 149 writeReg(BNO055_OPR_MODE_ADDR, 0x00);
franklu 1:8252a6052ebe 150 wait(0.2);
franklu 1:8252a6052ebe 151
franklu 1:8252a6052ebe 152 regVal = readReg(BNO055_OPR_MODE_ADDR);
franklu 1:8252a6052ebe 153 pc.printf("Change to mode: %d\r\n", regVal);
franklu 1:8252a6052ebe 154 wait(0.1);
franklu 1:8252a6052ebe 155
franklu 1:8252a6052ebe 156 // Remap axes
franklu 1:8252a6052ebe 157 writeReg(BNO055_AXIS_MAP_CONFIG_ADDR, 0x06); // b00_00_01_10
franklu 1:8252a6052ebe 158 wait(0.1);
franklu 1:8252a6052ebe 159
franklu 1:8252a6052ebe 160 // Set to external crystal
franklu 1:8252a6052ebe 161 writeReg(BNO055_SYS_TRIGGER_ADDR, 0x80);
franklu 1:8252a6052ebe 162 wait(0.2);
franklu 1:8252a6052ebe 163
franklu 1:8252a6052ebe 164 // Change mode to NDOF
franklu 1:8252a6052ebe 165 writeReg(BNO055_OPR_MODE_ADDR, 0x0C);
franklu 1:8252a6052ebe 166 wait(0.2);
franklu 1:8252a6052ebe 167
franklu 1:8252a6052ebe 168 regVal = readReg(BNO055_OPR_MODE_ADDR);
franklu 1:8252a6052ebe 169 pc.printf("Change to mode: %d\r\n", regVal);
franklu 1:8252a6052ebe 170 wait(0.1);
franklu 1:8252a6052ebe 171
franklu 1:8252a6052ebe 172 calibrationVals = getEulerAngles();
franklu 1:8252a6052ebe 173 return startupPass;
franklu 1:8252a6052ebe 174 }
franklu 1:8252a6052ebe 175
franklu 1:8252a6052ebe 176 float reduceAngle(float target, float source) {
franklu 1:8252a6052ebe 177 float a = target - source;
franklu 1:8252a6052ebe 178 if (a > 180) {
franklu 1:8252a6052ebe 179 a -= 360;
franklu 1:8252a6052ebe 180 } else if (a < -180) {
franklu 1:8252a6052ebe 181 a += 360;
franklu 1:8252a6052ebe 182 }
franklu 1:8252a6052ebe 183 return a;
franklu 1:8252a6052ebe 184 }
franklu 1:8252a6052ebe 185 int main() {
franklu 1:8252a6052ebe 186
franklu 1:8252a6052ebe 187 // button1.attach_asserted(&button1_pressed);
franklu 1:8252a6052ebe 188 // button1.attach_deasserted(&button1_released);
franklu 1:8252a6052ebe 189 // button1.setAssertValue(0);
franklu 1:8252a6052ebe 190 // button1.setSampleFrequency();
franklu 1:8252a6052ebe 191 //
franklu 1:8252a6052ebe 192 // button2.attach_asserted(&button2_pressed);
franklu 1:8252a6052ebe 193 // button2.attach_deasserted(&button2_released);
franklu 1:8252a6052ebe 194 // button2.setAssertValue(0);
franklu 1:8252a6052ebe 195 // button2.setSampleFrequency();
franklu 1:8252a6052ebe 196
franklu 1:8252a6052ebe 197 bool startupPassed;
franklu 1:8252a6052ebe 198 Euler e;
franklu 1:8252a6052ebe 199
franklu 1:8252a6052ebe 200 //RED_LED = 0;
franklu 1:8252a6052ebe 201 led = 0;
franklu 1:8252a6052ebe 202 led2 = 1;
franklu 1:8252a6052ebe 203 // Initialize
franklu 1:8252a6052ebe 204 pc.baud(115200);
franklu 1:8252a6052ebe 205 pc.printf("starting up\r\n");
franklu 1:8252a6052ebe 206 wait(0.5);
franklu 1:8252a6052ebe 207 startupPassed = initBNO055(); // Note: set LED to RED if this fails
franklu 1:8252a6052ebe 208
franklu 1:8252a6052ebe 209 float rollAvg = 0;
franklu 1:8252a6052ebe 210
franklu 1:8252a6052ebe 211 float pitchAvg = 0;
franklu 1:8252a6052ebe 212 int readCount = 0;
franklu 1:8252a6052ebe 213
franklu 1:8252a6052ebe 214 bool sentChar;
franklu 1:8252a6052ebe 215 // Read orientation values
franklu 1:8252a6052ebe 216 while(true)
franklu 1:8252a6052ebe 217 {
franklu 1:8252a6052ebe 218 sentChar = false;
franklu 1:8252a6052ebe 219 // Read in the Euler angles
franklu 1:8252a6052ebe 220 e = getEulerAngles();
franklu 1:8252a6052ebe 221
franklu 1:8252a6052ebe 222 wait(0.001);
franklu 1:8252a6052ebe 223
franklu 1:8252a6052ebe 224 // Read in the calibration status
franklu 1:8252a6052ebe 225 CalibStatus calStat = readCalibrationStatus();
franklu 1:8252a6052ebe 226
franklu 1:8252a6052ebe 227 // correct the heading, roll, pitch vals
franklu 1:8252a6052ebe 228 float corHead = reduceAngle(e.heading, calibrationVals.heading);
franklu 1:8252a6052ebe 229 float corRoll = reduceAngle(e.roll, calibrationVals.roll);
franklu 1:8252a6052ebe 230 float corPitch = reduceAngle(e.pitch, calibrationVals.pitch);
franklu 1:8252a6052ebe 231 // printf("Corrected: %7.2f \tRoll: %7.2f \tPitch: %7.2f \tMAG: %d ACC: %d GYR: %d SYS: %d\r\n", corHead, corRoll, corPitch, calStat.mag, calStat.acc, calStat.gyr, calStat.sys);
franklu 1:8252a6052ebe 232
franklu 1:8252a6052ebe 233
franklu 1:8252a6052ebe 234 rollAvg = corRoll; //.8*rollAvg + .2 * reduceAngle(corRoll, rollNums[readCount]);
franklu 1:8252a6052ebe 235 //rollNums[readCount] = corRoll;
franklu 1:8252a6052ebe 236
franklu 1:8252a6052ebe 237
franklu 1:8252a6052ebe 238 pitchAvg = corPitch;//.8*pitchAvg + .2 * reduceAngle(corPitch, pitchNums[readCount]);
franklu 1:8252a6052ebe 239 //pitchNums[readCount] = corPitch;
franklu 1:8252a6052ebe 240
franklu 1:8252a6052ebe 241 if (readCount >=5) { readCount = 0; }
franklu 1:8252a6052ebe 242 readCount++;
franklu 1:8252a6052ebe 243
franklu 1:8252a6052ebe 244 if (rollAvg < -10){
franklu 1:8252a6052ebe 245 keyboard.keyCode('z');
franklu 1:8252a6052ebe 246 keyboard.keyCode('z');
franklu 1:8252a6052ebe 247 keyboard.keyCode('z');
franklu 1:8252a6052ebe 248 keyboard.keyCode('z');
franklu 1:8252a6052ebe 249 }
franklu 1:8252a6052ebe 250
franklu 1:8252a6052ebe 251 wait(0.05);
franklu 1:8252a6052ebe 252 }
franklu 1:8252a6052ebe 253 }