LancerStratos’s blog

第23回ロボットグランプリに向けたロボットランサー”ランサーストラトス”開発記録

BNO055読み取り成功

やっとBNO055の方位角(オイラー角)読み出しに成功しました。原因はデータ型の間違いでした。マニュアルには、オイラー角の出力型は符号付き2バイトとなっているので、上位8ビットと下位8ビットを組み合わせた時のデータ型をint16_tとしなければならないところ、マニュアルに「方位角は0~360°で出力」とあるのを見てuint16_tでよいと思い込んでいたのが間違いだったようです。これに気付くまで、何十回と書き込みを繰り返しました。

方位角出力の時間変化を液晶に表示させてみると、結構ドリフトしているような気がします。以前秋ピコで試したときはそれほどドリフトしなかった記憶なだけにガッカリです。とりあえず読み取りできたので、コースを周回させたときにどうなるか見てみようと考えています。今回作成した関数を記載しておきます。赤字に注目。

#include "stm32f4xx_hal.h"
#include <stdio.h>
extern I2C_HandleTypeDef hi2c1;

#define BNO055_ADDRESS (0x28<<1)
#define BNO055_SYS_TRIGGER 0x3f
#define BNO055_SYS_TRIGGER_1 0b11000000
#define BNO055_SYS_TRIGGER_2 0b10000001
#define BNO055_PWR_MODE 0x3e
#define BNO055_PWR_MODE_1 0b00000000
#define BNO055_AXIS_MAP_CONFIG 0x41
#define BNO055_AXIS_MAP_CONFIG_1 0x21
#define BNO055_AXIS_MAP_SIGN 0x42
#define BNO055_AXIS_MAP_SIGN_1 0x01
#define BNO055_UNIT_SEL 0x3b
#define BNO055_UNIT_SEL_1 0b0000000
#define BNO055_OPR_MODE 0x3d
#define BNO055_OPR_MODE_1 0b00001100

uint8_t bno_read_address = 0x1a;
uint8_t bno_receivedata[2];
int16_t Eular_Z;

void BNO055_Init()
{
    HAL_I2C_Mem_Write(&hi2c1, BNO055_ADDRESS, BNO055_SYS_TRIGGER, I2C_MEMADD_SIZE_8BIT, (uint8_t*)BNO055_SYS_TRIGGER_1, 1, 100);
    HAL_I2C_Mem_Write(&hi2c1, BNO055_ADDRESS, BNO055_SYS_TRIGGER, I2C_MEMADD_SIZE_8BIT, (uint8_t*)BNO055_SYS_TRIGGER_2, 1, 100);
    HAL_I2C_Mem_Write(&hi2c1, BNO055_ADDRESS, BNO055_PWR_MODE, I2C_MEMADD_SIZE_8BIT, (uint8_t*)BNO055_PWR_MODE_1, 1, 100);
    HAL_I2C_Mem_Write(&hi2c1, BNO055_ADDRESS, BNO055_AXIS_MAP_CONFIG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)BNO055_AXIS_MAP_CONFIG_1, 1, 100);
    HAL_I2C_Mem_Write(&hi2c1, BNO055_ADDRESS, BNO055_AXIS_MAP_SIGN, I2C_MEMADD_SIZE_8BIT, (uint8_t*)BNO055_AXIS_MAP_SIGN_1, 1, 100);
    HAL_I2C_Mem_Write(&hi2c1, BNO055_ADDRESS, BNO055_UNIT_SEL, I2C_MEMADD_SIZE_8BIT, (uint8_t*)BNO055_UNIT_SEL_1, 1, 100);
    HAL_I2C_Mem_Write(&hi2c1, BNO055_ADDRESS, BNO055_OPR_MODE, I2C_MEMADD_SIZE_8BIT, (uint8_t*)BNO055_OPR_MODE_1, 1, 100);
}

int16_t get_Heading()
{
    if(HAL_I2C_Mem_Read(&hi2c1, BNO055_ADDRESS, bno_read_address, I2C_MEMADD_SIZE_8BIT, &bno_receivedata[0], 2, 1) == HAL_OK)
        Eular_Z = (bno_receivedata[1]<<8) | bno_receivedata[0];
        else Eular_Z = 999;
    return Eular_Z;
}

BNO055マニュアルには基準座標が下記の通り示されています。この図から方位角はZ軸に関連すると考えるのが普通だと思うのですが、方位角を読みだすアドレスの名はZでなくXと書かれていて、この間違いに気づくのにもかなりの時間がかかりました。マニュアルをよく読めば分かることなのですが。

BNO055座標