磁気センサv4
Dependencies: mbed
Fork of mag_sensor by
main.cpp@1:21ba826811d6, 2018-08-12 (annotated)
- Committer:
- ponpoko1939
- Date:
- Sun Aug 12 06:34:00 2018 +0000
- Revision:
- 1:21ba826811d6
- Parent:
- 0:ae23b58fc2d4
- Child:
- 2:8ba36609face
- Child:
- 3:7644f7b86ae0
??????????????????...?
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ponpoko1939 | 0:ae23b58fc2d4 | 1 | /*MPU9250_PROGRAM ver2.2 PROGRAMED BY RYOTARO FUNAI 2018/08/10*/ |
ponpoko1939 | 0:ae23b58fc2d4 | 2 | #include <mbed.h> |
ponpoko1939 | 0:ae23b58fc2d4 | 3 | #include <math.h> |
ponpoko1939 | 0:ae23b58fc2d4 | 4 | |
ponpoko1939 | 0:ae23b58fc2d4 | 5 | I2C i2c(p9, p10); |
ponpoko1939 | 0:ae23b58fc2d4 | 6 | Serial pc(USBTX, USBRX); //TWELITE使う予定なら13,14ピン |
ponpoko1939 | 0:ae23b58fc2d4 | 7 | |
ponpoko1939 | 0:ae23b58fc2d4 | 8 | #define MPU9250_ADDRESS 0x68<<1 //I2CでのMPU9250のスレーブアドレス |
ponpoko1939 | 0:ae23b58fc2d4 | 9 | #define AK8963_ADDRESS 0x0c<<1 //磁気センサのスレーブアドレス |
ponpoko1939 | 0:ae23b58fc2d4 | 10 | #define Whoami 0x75 //who_am_iレジスタのアドレス、0x71が返ってくる |
ponpoko1939 | 0:ae23b58fc2d4 | 11 | #define Magadd 0x00 //ak8963のWho_am_i |
ponpoko1939 | 0:ae23b58fc2d4 | 12 | #define PWR 0x6b //スリープモードをonにするためのアドレス |
ponpoko1939 | 0:ae23b58fc2d4 | 13 | #define MAG_OPN 0x37 //mpu9250から磁気センサにアクセスできるようにする |
ponpoko1939 | 0:ae23b58fc2d4 | 14 | #define ACC_CONFIG 0x1c //加速度センサ設定用のアドレス |
ponpoko1939 | 0:ae23b58fc2d4 | 15 | #define ACC_2G 0x00 //加速度センサのレンジ(2G) |
ponpoko1939 | 0:ae23b58fc2d4 | 16 | #define ACC_4G 0x08 //加速度センサのレンジ(4G) |
ponpoko1939 | 0:ae23b58fc2d4 | 17 | #define ACC_8G 0x10 //加速度センサのレンジ(8G) |
ponpoko1939 | 0:ae23b58fc2d4 | 18 | #define ACC_16G 0x18 //加速度センサのレンジ(16Gまで計測可能) |
ponpoko1939 | 0:ae23b58fc2d4 | 19 | #define MAG_CONFIG 0x0a //磁気センサ設定用のアドレス |
ponpoko1939 | 0:ae23b58fc2d4 | 20 | #define MAG_8HZ 0x12 //磁気センサの出力周期(8Hz) |
ponpoko1939 | 0:ae23b58fc2d4 | 21 | #define MAG_100HZ 0x16 //磁気センサの出力周期(100Hz) |
ponpoko1939 | 0:ae23b58fc2d4 | 22 | #define accRange 16.0 //加速度センサの測定レンジ |
ponpoko1939 | 0:ae23b58fc2d4 | 23 | #define ST2 0x02 //磁気センサのステータスが入っているアドレス |
ponpoko1939 | 0:ae23b58fc2d4 | 24 | #define Ain 35 |
ponpoko1939 | 0:ae23b58fc2d4 | 25 | #define SDA 21 |
ponpoko1939 | 0:ae23b58fc2d4 | 26 | #define SCL 22 |
ponpoko1939 | 0:ae23b58fc2d4 | 27 | #define led 2 //チェック用のLEDピン |
ponpoko1939 | 0:ae23b58fc2d4 | 28 | |
ponpoko1939 | 0:ae23b58fc2d4 | 29 | void Ac_Read(int16_t*, int16_t*, int16_t*); //9軸から加速度の値を取得 |
ponpoko1939 | 0:ae23b58fc2d4 | 30 | void Mag_Read(int16_t*, int16_t*, int16_t*); |
ponpoko1939 | 0:ae23b58fc2d4 | 31 | //addrにスレーブアドレス、regにアクセスするアドレスを入力する |
ponpoko1939 | 0:ae23b58fc2d4 | 32 | void i2cRead(uint8_t addr,uint8_t reg, uint8_t bytes,uint8_t* data); |
ponpoko1939 | 0:ae23b58fc2d4 | 33 | void i2cWrite(uint8_t addr,uint8_t reg, uint8_t data); |
ponpoko1939 | 0:ae23b58fc2d4 | 34 | uint8_t IDcheck(); |
ponpoko1939 | 0:ae23b58fc2d4 | 35 | |
ponpoko1939 | 0:ae23b58fc2d4 | 36 | uint8_t accgyrodata[14]; |
ponpoko1939 | 0:ae23b58fc2d4 | 37 | uint8_t magneticdata[7]; |
ponpoko1939 | 0:ae23b58fc2d4 | 38 | uint8_t ST2_Bit; //磁気センサのステータスを入れておく |
ponpoko1939 | 0:ae23b58fc2d4 | 39 | |
ponpoko1939 | 0:ae23b58fc2d4 | 40 | int16_t mx, my, mz; |
ponpoko1939 | 0:ae23b58fc2d4 | 41 | double magX, magY, magZ, mag; |
ponpoko1939 | 1:21ba826811d6 | 42 | int16_t ax, ay, az; |
ponpoko1939 | 1:21ba826811d6 | 43 | float accX, accY, accZ, acc; |
ponpoko1939 | 1:21ba826811d6 | 44 | double rad; |
ponpoko1939 | 1:21ba826811d6 | 45 | double degree; |
ponpoko1939 | 0:ae23b58fc2d4 | 46 | float ID; |
ponpoko1939 | 1:21ba826811d6 | 47 | double roll; |
ponpoko1939 | 1:21ba826811d6 | 48 | double pitch; |
ponpoko1939 | 1:21ba826811d6 | 49 | |
ponpoko1939 | 0:ae23b58fc2d4 | 50 | int main() { |
ponpoko1939 | 0:ae23b58fc2d4 | 51 | i2cWrite(MPU9250_ADDRESS, PWR, 0x00); //スリープモードの解除 |
ponpoko1939 | 0:ae23b58fc2d4 | 52 | double maveX = 0, maveY = 0, maveZ = 0; |
ponpoko1939 | 0:ae23b58fc2d4 | 53 | while(1) { |
ponpoko1939 | 1:21ba826811d6 | 54 | //加速度の値を取得し、落下判定 |
ponpoko1939 | 1:21ba826811d6 | 55 | Ac_Read(&ax,&ay,&az); |
ponpoko1939 | 1:21ba826811d6 | 56 | accX = ax * accRange / 32768.0;//[G]に変換 |
ponpoko1939 | 1:21ba826811d6 | 57 | accY = ay * accRange / 32768.0;//[G]に変換 |
ponpoko1939 | 1:21ba826811d6 | 58 | accZ = az * accRange / 32768.0;//[G]に変換 |
ponpoko1939 | 1:21ba826811d6 | 59 | roll = atan2(accY, accZ); |
ponpoko1939 | 1:21ba826811d6 | 60 | pitch = atan2(-accX, sin(accY) + cos(accZ)); |
ponpoko1939 | 1:21ba826811d6 | 61 | i2cWrite(MPU9250_ADDRESS, MAG_OPN, 0x02); //磁気センサの起動 |
ponpoko1939 | 1:21ba826811d6 | 62 | i2cWrite(AK8963_ADDRESS, MAG_CONFIG, MAG_100HZ);//磁気センサの測定レンジの設定 |
ponpoko1939 | 1:21ba826811d6 | 63 | for(int i = 0;i < 150;i++){ |
ponpoko1939 | 0:ae23b58fc2d4 | 64 | Mag_Read(&mx, &my, &mz); |
ponpoko1939 | 0:ae23b58fc2d4 | 65 | maveX += mx; |
ponpoko1939 | 0:ae23b58fc2d4 | 66 | maveY += my; |
ponpoko1939 | 0:ae23b58fc2d4 | 67 | maveZ += mz; |
ponpoko1939 | 1:21ba826811d6 | 68 | wait_ms(10); |
ponpoko1939 | 0:ae23b58fc2d4 | 69 | } |
ponpoko1939 | 1:21ba826811d6 | 70 | maveX /= 150; |
ponpoko1939 | 1:21ba826811d6 | 71 | maveY /= 150; |
ponpoko1939 | 1:21ba826811d6 | 72 | maveZ /= 150; |
ponpoko1939 | 0:ae23b58fc2d4 | 73 | magX = (maveX - 168.75) / 32768.0f * 4800.0f;//[uT]に変換 |
ponpoko1939 | 0:ae23b58fc2d4 | 74 | magY = (maveY - 18.75) / 32768.0f * 4800.0f;//[uT]に変換 |
ponpoko1939 | 1:21ba826811d6 | 75 | magZ = mz / 32768.0f * 4800.0f;//[uT]に変換 |
ponpoko1939 | 0:ae23b58fc2d4 | 76 | pc.printf("%f,%f\n\r", magX, magY); |
ponpoko1939 | 1:21ba826811d6 | 77 | //ID = IDcheck(); |
ponpoko1939 | 0:ae23b58fc2d4 | 78 | //pc.printf("%f\n\r", ID); |
ponpoko1939 | 1:21ba826811d6 | 79 | rad = atan2(magZ * sin(roll) - magY * cos(roll), magX * cos(pitch) + magY * sin(pitch) * sin(roll) + magZ * sin(pitch) * cos(roll)); |
ponpoko1939 | 1:21ba826811d6 | 80 | degree = -((int)(rad * 180.0 / 3.141592 + 270.0 - 7.5) % 360 - 360.0); |
ponpoko1939 | 1:21ba826811d6 | 81 | /* |
ponpoko1939 | 0:ae23b58fc2d4 | 82 | if(degree < 0){ |
ponpoko1939 | 0:ae23b58fc2d4 | 83 | degree += 360; |
ponpoko1939 | 0:ae23b58fc2d4 | 84 | } |
ponpoko1939 | 1:21ba826811d6 | 85 | */ |
ponpoko1939 | 1:21ba826811d6 | 86 | pc.printf("%d\n\r",(int)degree); |
ponpoko1939 | 0:ae23b58fc2d4 | 87 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 88 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 89 | |
ponpoko1939 | 1:21ba826811d6 | 90 | //mpu9250から加速度センサのみ引っ張ってくる |
ponpoko1939 | 1:21ba826811d6 | 91 | void Ac_Read(int16_t* ax, int16_t* ay, int16_t* az){ |
ponpoko1939 | 1:21ba826811d6 | 92 | i2cWrite(MPU9250_ADDRESS, PWR, 0x00); //スリープモードの解除 |
ponpoko1939 | 1:21ba826811d6 | 93 | i2cWrite(MPU9250_ADDRESS, ACC_CONFIG, ACC_16G);//加速度センサの測定レンジの設定 |
ponpoko1939 | 1:21ba826811d6 | 94 | i2cRead(MPU9250_ADDRESS, 0x3b, 14, accgyrodata); |
ponpoko1939 | 1:21ba826811d6 | 95 | *ax = (accgyrodata[0] << 8) | accgyrodata[1];//accGyroTempData[0]を左に8シフトし(<<),accGyroTempData[1]を足し合わせる(|) |は論理和 |
ponpoko1939 | 1:21ba826811d6 | 96 | *ay = (accgyrodata[2] << 8) | accgyrodata[3];//accGyroTempData[2]を左に8シフトし(<<),accGyroTempData[3]を足し合わせる(|) |
ponpoko1939 | 1:21ba826811d6 | 97 | *az = (accgyrodata[4] << 8) | accgyrodata[5];//accGyroTempData[4]を左に8シフトし(<<),accGyroTempData[5]を足し合わせる(|) |
ponpoko1939 | 1:21ba826811d6 | 98 | } |
ponpoko1939 | 1:21ba826811d6 | 99 | |
ponpoko1939 | 0:ae23b58fc2d4 | 100 | //mpu9250から磁気センサのみ引っ張ってくる |
ponpoko1939 | 0:ae23b58fc2d4 | 101 | void Mag_Read(int16_t* mx, int16_t* my, int16_t* mz){ |
ponpoko1939 | 0:ae23b58fc2d4 | 102 | i2cRead(AK8963_ADDRESS, ST2, 1, &ST2_Bit);//読み出し準備ができたか確認 |
ponpoko1939 | 0:ae23b58fc2d4 | 103 | if(ST2_Bit & 0x01){ //ちゃんと読めたかをST2レジスタの値を読んで確認 |
ponpoko1939 | 0:ae23b58fc2d4 | 104 | i2cRead(AK8963_ADDRESS, 0x03, 7, magneticdata); |
ponpoko1939 | 0:ae23b58fc2d4 | 105 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 106 | else pc.printf("ERROR!!\n"); |
ponpoko1939 | 0:ae23b58fc2d4 | 107 | *mx = (magneticdata[0] << 8) | magneticdata[1]; |
ponpoko1939 | 0:ae23b58fc2d4 | 108 | *my = (magneticdata[2] << 8) | magneticdata[3]; |
ponpoko1939 | 0:ae23b58fc2d4 | 109 | *mz = (magneticdata[4] << 8) | magneticdata[5]; |
ponpoko1939 | 0:ae23b58fc2d4 | 110 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 111 | |
ponpoko1939 | 0:ae23b58fc2d4 | 112 | //mpu9250からデータを取得(bytesに受け取るデータのバイト数、dataに実際のデータを挿入していく) |
ponpoko1939 | 0:ae23b58fc2d4 | 113 | void i2cRead(uint8_t addr,uint8_t reg, uint8_t bytes,uint8_t* data){ |
ponpoko1939 | 0:ae23b58fc2d4 | 114 | char cmd[1]; |
ponpoko1939 | 0:ae23b58fc2d4 | 115 | char written_data[14]; |
ponpoko1939 | 0:ae23b58fc2d4 | 116 | cmd[0] = reg; |
ponpoko1939 | 0:ae23b58fc2d4 | 117 | i2c.write(addr, cmd, 1, 1); |
ponpoko1939 | 0:ae23b58fc2d4 | 118 | i2c.read(addr, written_data, bytes, 0); |
ponpoko1939 | 0:ae23b58fc2d4 | 119 | for(int ii = 0; ii < bytes; ii++) { |
ponpoko1939 | 0:ae23b58fc2d4 | 120 | data[ii] = written_data[ii]; |
ponpoko1939 | 0:ae23b58fc2d4 | 121 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 122 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 123 | |
ponpoko1939 | 0:ae23b58fc2d4 | 124 | //mpu9250にデータを送信(dataに送信するデータを入力する) |
ponpoko1939 | 0:ae23b58fc2d4 | 125 | void i2cWrite(uint8_t addr,uint8_t reg, uint8_t data){ |
ponpoko1939 | 0:ae23b58fc2d4 | 126 | char cmd[2]; |
ponpoko1939 | 0:ae23b58fc2d4 | 127 | cmd[0] = reg; //レジスタ指定 |
ponpoko1939 | 0:ae23b58fc2d4 | 128 | cmd[1] = data; //送信するデータ |
ponpoko1939 | 0:ae23b58fc2d4 | 129 | i2c.write(addr, cmd, 2); //レジスタ指定はどうする? |
ponpoko1939 | 0:ae23b58fc2d4 | 130 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 131 | /* |
ponpoko1939 | 0:ae23b58fc2d4 | 132 | void readMagData(int16_t * destination) |
ponpoko1939 | 0:ae23b58fc2d4 | 133 | { |
ponpoko1939 | 0:ae23b58fc2d4 | 134 | uint8_t rawData[7]; // x/y/z gyro register data, ST2 register stored here, must read ST2 at end of data acquisition |
ponpoko1939 | 0:ae23b58fc2d4 | 135 | if(readByte(AK8963_ADDRESS, AK8963_ST1) & 0x01) { // wait for magnetometer data ready bit to be set |
ponpoko1939 | 0:ae23b58fc2d4 | 136 | readBytes(AK8963_ADDRESS, AK8963_XOUT_L, 7, &rawData[0]); // Read the six raw data and ST2 registers sequentially into data array |
ponpoko1939 | 0:ae23b58fc2d4 | 137 | uint8_t c = rawData[6]; // End data read by reading ST2 register |
ponpoko1939 | 0:ae23b58fc2d4 | 138 | if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data |
ponpoko1939 | 0:ae23b58fc2d4 | 139 | destination[0] = (int16_t)(((int16_t)rawData[1] << 8) | rawData[0]); // Turn the MSB and LSB into a signed 16-bit value |
ponpoko1939 | 0:ae23b58fc2d4 | 140 | destination[1] = (int16_t)(((int16_t)rawData[3] << 8) | rawData[2]) ; // Data stored as little Endian |
ponpoko1939 | 0:ae23b58fc2d4 | 141 | destination[2] = (int16_t)(((int16_t)rawData[5] << 8) | rawData[4]) ; |
ponpoko1939 | 0:ae23b58fc2d4 | 142 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 143 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 144 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 145 | |
ponpoko1939 | 0:ae23b58fc2d4 | 146 | void getMres() { |
ponpoko1939 | 0:ae23b58fc2d4 | 147 | switch (Mscale) |
ponpoko1939 | 0:ae23b58fc2d4 | 148 | { |
ponpoko1939 | 0:ae23b58fc2d4 | 149 | // Possible magnetometer scales (and their register bit settings) are: |
ponpoko1939 | 0:ae23b58fc2d4 | 150 | // 14 bit resolution (0) and 16 bit resolution (1) |
ponpoko1939 | 0:ae23b58fc2d4 | 151 | case MFS_14BITS: |
ponpoko1939 | 0:ae23b58fc2d4 | 152 | mRes = 10.0*4912.0/8190.0; // Proper scale to return milliGauss |
ponpoko1939 | 0:ae23b58fc2d4 | 153 | break; |
ponpoko1939 | 0:ae23b58fc2d4 | 154 | case MFS_16BITS: |
ponpoko1939 | 0:ae23b58fc2d4 | 155 | mRes = 10.0*4912.0/32760.0; // Proper scale to return milliGauss |
ponpoko1939 | 0:ae23b58fc2d4 | 156 | break; |
ponpoko1939 | 0:ae23b58fc2d4 | 157 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 158 | } |
ponpoko1939 | 0:ae23b58fc2d4 | 159 | */ |
ponpoko1939 | 0:ae23b58fc2d4 | 160 | |
ponpoko1939 | 0:ae23b58fc2d4 | 161 | //Who_am_Iアドレスで接続確認ができる。0x48もしくは10進数で72が返ってくればok |
ponpoko1939 | 0:ae23b58fc2d4 | 162 | uint8_t IDcheck(){ |
ponpoko1939 | 0:ae23b58fc2d4 | 163 | uint8_t address; |
ponpoko1939 | 0:ae23b58fc2d4 | 164 | i2cRead(AK8963_ADDRESS, Magadd, 1, &address); |
ponpoko1939 | 0:ae23b58fc2d4 | 165 | return address; |
ponpoko1939 | 0:ae23b58fc2d4 | 166 | } |