Interfacing Bosch BNO055 IMU with ATMega32U4 via I2C

Go To Last Post
22 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello*,

I am trying to interface the BNO055 IMU with ATMega32U4 via TWI. I have written the following code which just tries to read the chip ID. 

According to the BNO055 datasheet, it should return 0xA0 (page no. 54). But the bus doesn't seem to respond.

I have used a 10k Ohm resistor for pull-up on the SDA and SCL lines.

The F_CPU is 16MHz and SCL frequency is 400KHz.

/*
 * Test_BNO055.c
 *
 * Created: 15-July-18 4:31:14 PM
 * Author : Frederic Philips
 */ 

#include <avr/io.h>
#include <avr/sfr_defs.h>
#define F_CPU 16000000UL	//16 MHz frequency
#define BAUD  9600
#include <util/setbaud.h>
#include <util/delay.h>

#include "Test_BNO055.h"

/************************************************************************************
** AVR_Init function:
** - Start-up delay
** - Initializes the I/O peripherals
*************************************************************************************/
void AVR_Init(void)
{
	_delay_ms(750);		//Short pause after BNO055 Power-On Reset(Mandatory)
	DDRD |= _BV(1);		//Set TX as output
	DDRD &= ~(_BV(0));	//Set RX as input

	//Initialize TWI data
	TWI_data = 0;
}

/************************************************************************************
** TWI_Init function:
** Sets the I2C in Fast mode:
** - TWBR = ((F_CPU / F_SCL) - 16) / (2 * (4 ^ TWPS)))
** - Here: F_CPU = 16 MHz, F_SCL = 400 kHz(Fast I2C), TWPS(TWI Pre-Scalar) = 0x00
*************************************************************************************/
void TWI_Init(void)
{
    //Set SCL to 400kHz
    TWSR = 0x00;
    TWBR = 0x0C;
}

/************************************************************************************
** USART Reference:
** - ATmega32U4 Datasheet - Rev. CORP072610(Pg.186)
** - AVR Microcontroller and Embedded Systems - Mazidi(Pg.395)
** - Embedded C Programming and the Atmel AVR - Barnett(Pg.132)
*************************************************************************************
** To initialize the UART, the following steps are to be followed:
** - Set the Baud rate(use <util/setbaud.h>, which depends on the macros F_CPU & BAUD)
** - Disable double speed(2x) mode
** - Set the no. of data bits(8/9 bits), stop bit(1/2) and parity bit(None/Odd/Even)
** - Set the USART mode(Synchronous/Asynchronous/Asynchronous 2x)
** - Enable Receiver & Transmitter(Set RXEN & TXEN bits in UCSRB register)
*************************************************************************************/
void UART_Init(void)
{
	//Set the BAUD rate(Ref. ATmega32U4 Datasheet Pg.189, Table 18-1)
	//To hard-code the Baud rate, Ref. Tables 18-9 to 18-12 in Pgs. 210 - 213
	UBRR1 = ((F_CPU / (16UL * BAUD)) - 1);

	//Disables 2x speed
	UCSR1A &= ~(_BV(U2X1));

	//Enable 8-bit character size, one stop-bit, no parity & asynchronous mode
	UCSR1C |= _BV(UCSZ11) | _BV(UCSZ10);

	//Enable Transmitter & Receiver
	UCSR1B |= _BV(TXEN1) | _BV(RXEN1);
}

/************************************************************************************
** UART_Tx function:
** - Transmits the TWI data via the USB Serial
** - The data is received & displayed in a Hyperterminal
*************************************************************************************/
void UART_Tx(unsigned char data)
{
	loop_until_bit_is_set(UCSR1A, UDRE1);	//Wait until buffer is empty
	UDR1 = data;				//Send TWI data via UART
}

/************************************************************************************
** TWI_Start function:
** Initializes the TWI and communicates the save device for read/write
** address = Slave_address + read/write
*************************************************************************************/
void TWI_Start(uint8_t address)
{
	TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);

	while(!(TWCR & (1 << TWINT)));

	TWDR = address;
	TWCR = _BV(TWINT) | _BV(TWEN);
	while(!(TWCR & (1 << TWINT)));
}

/************************************************************************************
** TWI_Stop function:
** Stops the TWI transmission
*************************************************************************************/
void TWI_Stop(void)
{
	TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
}

/************************************************************************************
** TWI_Write function:
** Writes the data on the TWI bus
*************************************************************************************/
void TWI_Write(uint8_t data)
{
	TWDR = data;
	TWCR = _BV(TWINT) | _BV(TWEN);
	while(!(TWCR & (1 << TWINT)));
}

/************************************************************************************
** TWI_Read function:
** Reads the data from the TWI bus
*************************************************************************************/
uint8_t TWI_Read(void)
{
	TWCR = _BV(TWINT) | _BV(TWEN);
	while(!(TWCR & (1 << TWINT)));
	return TWDR;
}

/************************************************************************************
** Send_to_IMU function:
** Writes an 8-bit data to a specific address on the slave device
*************************************************************************************/
void Send_to_IMU(uint8_t devAddr, uint8_t reg, uint8_t byte)
{
	TWI_Start(devAddr + I2C_WRITE);
	TWI_Write(reg);
	TWI_Write(byte);

	TWI_Stop();
}

/************************************************************************************
** Receive_from_IMU function:
** Reads an 8-bit data from a specific address on the slave device
*************************************************************************************/
void Receive_from_IMU(uint8_t devAddr, uint8_t reg)
{
	TWI_Start(devAddr + I2C_WRITE);
	TWI_Write(reg);

	TWI_Start(devAddr + I2C_READ);
	TWI_data = TWI_Read();

	TWI_Stop();
}

/************************************************************************************
** Main function:
** - Contains an endless loop
** - Sets the BNO055 in NDOF mode and fetches the quaternion data
*************************************************************************************/
int main(void)
{
	AVR_Init();
	UART_Init();
	TWI_Init();

	//Endless Loop
	while(1)
	{
		Receive_from_IMU(BNO055_ADDRESS, BNO055_CHIP_ID_ADDR);  //Returns 0xA0
		UART_Tx(TWI_data);
		_delay_ms(1000);					//1 second delay
	}
}
/*
 * Test_BNO055.h
 *
 * Created: 24-July-18 8:42:04 AM
 *  Author: Frederic Philips
 */ 

#ifndef TEST_BNO055_H_
#define TEST_BNO055_H_

//BNO055 TWI Address: Low - 0x28, High - 0x29
#define BNO055_ADDRESS	0x28

//TWI Read/Write
#define I2C_WRITE 0
#define I2C_READ  1

//Register definitions
/* Page id register definition */
#define BNO055_PAGE_ID_ADDR          0x07
/* PAGE0 REGISTER DEFINITION START*/
#define BNO055_CHIP_ID_ADDR          0x00
#define BNO055_ACCEL_REV_ID_ADDR     0x01
#define BNO055_MAG_REV_ID_ADDR       0x02
#define BNO055_GYRO_REV_ID_ADDR      0x03
#define BNO055_SW_REV_ID_LSB_ADDR    0x04
#define BNO055_SW_REV_ID_MSB_ADDR    0x05
#define BNO055_BL_REV_ID_ADDR        0x06
/* Accelerometer data register */
#define BNO055_ACCEL_DATA_X_LSB_ADDR 0x08
#define BNO055_ACCEL_DATA_X_MSB_ADDR 0x09
#define BNO055_ACCEL_DATA_Y_LSB_ADDR 0x0A
#define BNO055_ACCEL_DATA_Y_MSB_ADDR 0x0B
#define BNO055_ACCEL_DATA_Z_LSB_ADDR 0x0C
#define BNO055_ACCEL_DATA_Z_MSB_ADDR 0x0D
/* Magnetometer data register */
#define BNO055_MAG_DATA_X_LSB_ADDR   0x0E
#define BNO055_MAG_DATA_X_MSB_ADDR   0x0F
#define BNO055_MAG_DATA_Y_LSB_ADDR   0x10
#define BNO055_MAG_DATA_Y_MSB_ADDR   0x11
#define BNO055_MAG_DATA_Z_LSB_ADDR   0x12
#define BNO055_MAG_DATA_Z_MSB_ADDR   0x13
/* Gyroscope data registers */
#define BNO055_GYRO_DATA_X_LSB_ADDR  0x14
#define BNO055_GYRO_DATA_X_MSB_ADDR  0x15
#define BNO055_GYRO_DATA_Y_LSB_ADDR  0x16
#define BNO055_GYRO_DATA_Y_MSB_ADDR  0x17
#define BNO055_GYRO_DATA_Z_LSB_ADDR  0x18
#define BNO055_GYRO_DATA_Z_MSB_ADDR  0x19
/* Euler data registers */
#define BNO055_EULER_H_LSB_ADDR      0x1A
#define BNO055_EULER_H_MSB_ADDR      0x1B
#define BNO055_EULER_R_LSB_ADDR      0x1C
#define BNO055_EULER_R_MSB_ADDR      0x1D
#define BNO055_EULER_P_LSB_ADDR      0x1E
#define BNO055_EULER_P_MSB_ADDR      0x1F
/* Quaternion data registers */
#define BNO055_QUATERNION_DATA_W_LSB_ADDR  0x20
#define BNO055_QUATERNION_DATA_W_MSB_ADDR  0x21
#define BNO055_QUATERNION_DATA_X_LSB_ADDR  0x22
#define BNO055_QUATERNION_DATA_X_MSB_ADDR  0x23
#define BNO055_QUATERNION_DATA_Y_LSB_ADDR  0x24
#define BNO055_QUATERNION_DATA_Y_MSB_ADDR  0x25
#define BNO055_QUATERNION_DATA_Z_LSB_ADDR  0x26
#define BNO055_QUATERNION_DATA_Z_MSB_ADDR  0x27
/* Linear acceleration data registers */
#define BNO055_LINEAR_ACCEL_DATA_X_LSB_ADDR 0x28
#define BNO055_LINEAR_ACCEL_DATA_X_MSB_ADDR 0x29
#define BNO055_LINEAR_ACCEL_DATA_Y_LSB_ADDR 0x2A
#define BNO055_LINEAR_ACCEL_DATA_Y_MSB_ADDR 0x2B
#define BNO055_LINEAR_ACCEL_DATA_Z_LSB_ADDR 0x2C
#define BNO055_LINEAR_ACCEL_DATA_Z_MSB_ADDR 0x2D
/* Gravity data registers */
#define BNO055_GRAVITY_DATA_X_LSB_ADDR      0x2E
#define BNO055_GRAVITY_DATA_X_MSB_ADDR      0x2F
#define BNO055_GRAVITY_DATA_Y_LSB_ADDR      0x30
#define BNO055_GRAVITY_DATA_Y_MSB_ADDR      0x31
#define BNO055_GRAVITY_DATA_Z_LSB_ADDR      0x32
#define BNO055_GRAVITY_DATA_Z_MSB_ADDR      0x33
/* Temperature data register */
#define BNO055_TEMP_ADDR                    0x34
/* Status registers */
#define BNO055_CALIB_STAT_ADDR              0x35
#define BNO055_SELFTEST_RESULT_ADDR         0x36
#define BNO055_INTR_STAT_ADDR               0x37
#define BNO055_SYS_CLK_STAT_ADDR            0x38
#define BNO055_SYS_STAT_ADDR                0x39
#define BNO055_SYS_ERR_ADDR                 0x3A
/* Unit selection register */
#define BNO055_UNIT_SEL_ADDR                0x3B
#define BNO055_DATA_SELECT_ADDR             0x3C
/* Mode registers */
#define BNO055_OPR_MODE_ADDR                0x3D
#define BNO055_PWR_MODE_ADDR                0x3E
#define BNO055_SYS_TRIGGER_ADDR             0x3F
#define BNO055_TEMP_SOURCE_ADDR             0x40
/* Axis remap registers */
#define BNO055_AXIS_MAP_CONFIG_ADDR         0x41
#define BNO055_AXIS_MAP_SIGN_ADDR           0x42
/* Accelerometer Offset registers */
#define ACCEL_OFFSET_X_LSB_ADDR             0x55
#define ACCEL_OFFSET_X_MSB_ADDR             0x56
#define ACCEL_OFFSET_Y_LSB_ADDR             0x57
#define ACCEL_OFFSET_Y_MSB_ADDR             0x58
#define ACCEL_OFFSET_Z_LSB_ADDR             0x59
#define ACCEL_OFFSET_Z_MSB_ADDR             0x5A
/* Magnetometer Offset registers */
#define MAG_OFFSET_X_LSB_ADDR               0x5B
#define MAG_OFFSET_X_MSB_ADDR               0x5C
#define MAG_OFFSET_Y_LSB_ADDR               0x5D
#define MAG_OFFSET_Y_MSB_ADDR               0x5E
#define MAG_OFFSET_Z_LSB_ADDR               0x5F
#define MAG_OFFSET_Z_MSB_ADDR               0x60
/* Gyroscope Offset registers*/
#define GYRO_OFFSET_X_LSB_ADDR              0x61
#define GYRO_OFFSET_X_MSB_ADDR              0x62
#define GYRO_OFFSET_Y_LSB_ADDR              0x63
#define GYRO_OFFSET_Y_MSB_ADDR              0x64
#define GYRO_OFFSET_Z_LSB_ADDR              0x65
#define GYRO_OFFSET_Z_MSB_ADDR              0x66
/* Radius registers */
#define ACCEL_RADIUS_LSB_ADDR               0x67
#define ACCEL_RADIUS_MSB_ADDR               0x68
#define MAG_RADIUS_LSB_ADDR                 0x69
#define MAG_RADIUS_MSB_ADDR                 0x6A

/* Page 1 registers */
#define BNO055_UNIQUE_ID_ADDR               0x50

//Definitions for unit selection
#define MPERSPERS   0x00
#define MILLIG      0x01
#define DEG_PER_SEC 0x00
#define RAD_PER_SEC 0x02
#define DEGREES     0x00
#define RADIANS     0x04
#define CENTIGRADE  0x00
#define FAHRENHEIT  0x10
#define WINDOWS     0x00
#define ANDROID     0x80

//Definitions for power mode
#define POWER_MODE_NORMAL   0x00
#define POWER_MODE_LOWPOWER 0x01
#define POWER_MODE_SUSPEND  0x02

//Definitions for operating mode
#define OPERATION_MODE_CONFIG        0x00
#define OPERATION_MODE_ACCONLY       0x01
#define OPERATION_MODE_MAGONLY       0x02
#define OPERATION_MODE_GYRONLY       0x03
#define OPERATION_MODE_ACCMAG        0x04
#define OPERATION_MODE_ACCGYRO       0x05
#define OPERATION_MODE_MAGGYRO       0x06
#define OPERATION_MODE_AMG           0x07
#define OPERATION_MODE_IMUPLUS       0x08
#define OPERATION_MODE_COMPASS       0x09
#define OPERATION_MODE_M4G           0x0A
#define OPERATION_MODE_NDOF_FMC_OFF  0x0B
#define OPERATION_MODE_NDOF          0x0C

//Function Prototypes
void AVR_Init(void);
void TWI_Init(void);
void UART_Init(void);
void UART_Tx(unsigned char data);
void TWI_Start(uint8_t address);
void TWI_Stop(void);
void TWI_Write(uint8_t data);
uint8_t TWI_Read(void);
void Send_to_IMU(uint8_t devAddr, uint8_t reg, uint8_t byte);
void Receive_from_IMU(uint8_t devAddr, uint8_t reg);

//Store TWI data
uint8_t TWI_data;

#endif /* TEST_BNO055_H_ */

Could someone point out the problem? Thanks!

Regards,
Frederic Philips

Last Edited: Fri. Aug 10, 2018 - 01:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At 400KHz your 10k pull ups are weak, try 2k2-4k7....    Also using void I2C functions is sure to be a problem, why not use proven code such as Peter Fleury's here:  http://homepage.hispeed.ch/peter...

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

fredphil wrote:
the bus (sic?) doesn't seem to respond

What do you mean by that?

 

The bus is just a passive link - it's the Slave which should respond.

 

Have you looked at the lines with an oscilloscope to see what's happening ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

fredphil wrote:
the bus (sic?) doesn't seem to respond

What do you mean by that?

The bus is just a passive link - it's the Slave which should respond.

Sorry, that's what I meant. The slave device doesn't seem to respond.

 

awneil wrote:

Have you looked at the lines with an oscilloscope to see what's happening ... ?

Unfortunately I dont have a scope. I tried debugging using the UART and found that the code is stuck at:

while(!(TWCR & (1 << TWINT)));

 

Regards,
Frederic Philips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

At 400KHz your 10k pull ups are weak, try 2k2-4k7....

Tried 2.5K, same result.

 

ki0bk wrote:

    Also using void I2C functions is sure to be a problem, why not use proven code such as Peter Fleury's here:  http://homepage.hispeed.ch/peter...

Will look into that.

Regards,
Frederic Philips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

fredphil wrote:
Could someone point out the problem? Thanks!

Since I2C is sync Serial, i.e. the master sets the speed, and 400kHz is max, why not start slower and if needed increase to get needed thru-put.

I always start my I2C projects at 50kHz, and in most don't need to increase that.

Anyway just a hint.

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Checkout "sigrok" and devices from ebay that will work with it. You could be watching the signal activity on the wires for $10 or even less.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm ... a $10 logic analyser isn't going to help much with "analogue" problems like too-high pullups on I2C.

 

But it shouldn't take an expensive scope to see that ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was suggesting an analyzer to look at the bit patterns on clock and data, not their analog profile. If the bit patterns aren't right it does not matter what shape they are (though I recognize that the converse is true also).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
If the bit patterns aren't right it does not matter what shape they are 

But being able to see what shape they are could immediately explain why they're not right.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

A $10 Logic Analyser will show up your I2C problem.    Even though inappropriate pullups are an "Analog" problem,   the LA software will decode in exactly the same manner as the TWI hardware.    i.e. it will detect digital high/low at about the same point on the sharkfin I2C signal.

 

My advice is:

1.   4k7 pullups with standard 100kHz I2C bus

2.   use Fleury library

3.   use the return values from the Fleury functions.

4.   attach a ZIP of a complete AS7 project

 

(1) is not very critical.    I bet that 10k pullups with 400kHz bus will be fine.  (if your bus capacitance is less than 100pF)

(4) AS4 project, makefile project, ... is fine.   Just as long as a reader can build and replicate your code

 

Most common I2C problems:

missing pullups.

incorrect Slave address.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

You can use the Arduino tools and examples to generate code and verify your hardware. The 32U4 was used in the Leonardo board.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Guys,

Thanks for your guidance. I am now able to read data from the BNO055. I am using the PF's I2C library and it works great. One minor problem that I had initially was that the slave address needed to be left-shifted by one bit due to the TWAR register structure. This was not obvious in PF's example because the EEPROM 24C02's slave address was not left-shifted. Don't know why...frown
Anyway, now that I am able to communicate with the BNO055, I'll finish the code and provide the link here. So please keep this thread open.

 

P.S. I tried different I2C frequencies and it works without any issues at 400KHz. I also tested it with different pull-up resistor values like 2.5k and 10k Ohm. Again, no problem there :)

 

Thanks all!

Regards,
Frederic Philips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Go on. The Slave datasheet will specify the I2C Bus fequency e.g. 100kHz ot 400kHz.
.
Regarding pullups. The value depends on your bus capacitance. A typical 20pF will be fine @ 400kHz with 4k7 = 9.4us.
You need stronger pullups with the maximum 400pF bus capacitance.
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm sure that it's a good solid company with an excellent new product.  However, I have to wonder about the bozo in the marketing department who thought that it would be a good idea to put two completely different by nearly-indentical-looking symbols next to each other in the product name/number.  Yes, I mean this capital 'O' right next to digit '0' nonsense in "BMO055".   Serious companies don't do this kind of thing, but old European companies will let something like this slip by because they are still running on European legacy languages like German, French, Dutch, whatever and this seems like it is too minor to change.  But when someone in China is trying to order 10000 units and can't get the order placed because it never occurred to them that there could be a difference between 'O' and '0' in the product name, well, c'est la vie.  It's the price that you pay for doing stupid things like having a 'O' next to a '0' in your product name.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Simon,

Interesting rant :)

Regards,
Frederic Philips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
European legacy languages like German,

Hmm ... many of the differences between Real English and Simplified (aka "American") English is that the latter is still stuck in 17th Century.

 

And quite a few others "Americanisms" are slimply word-for-word translations of German ...

 

cheeky

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

fredphil wrote:
One minor problem that I had initially was that the slave address needed to be left-shifted by one bit due to the TWAR register structure. This was not obvious in PF's example

This is an all-too-common problem: https://www.avrfreaks.net/commen...

 

angry

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would love to see your completed code for an example. Ive been using an mpu6050 + atmega328 and put in a great deal of effort to get the dmp loaded to read some values. It works well enough until I change the pitch and roll or yaw at the same time then the values become so inaccurate it creates much headaches.

How accurate are the BNO055 values? especially during simultaneous pitching and rolling motions. The BNO055 is more expensive than the MPU6050 so Im hoping for higher quality sensor fusion/processing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi JungleEskimo,

Using the Euler angles are problematic as they suffer from the Gimbal lock. You may want to use the quaternion format for the angles. 

I found that getting those values from the BNO was a lot simpler than the MPU. Though in this test code I get only the Euler angles (they are more intuitive and human-readable), you can also get the quaternions by changing the register address that can be found in the BNO datasheet. Also, please ignore the nRF code in the example.

Regards,
Frederic Philips

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dude! I ordered the BNO055 over the weekend and got to try it out with the help of your code and it's exactly what I needed. I'm so god damn happy it works so well it almost seems like magic. I can finally read proper acceleration values despite putting the BNO055 into weird/dynamic angles.

 

I've wasted a heroic amount of time grappling with the MPU6050 with all the trouble of figuring out how to adapt the Jeff Rowberg library and trying to filter out changes in accelerometer values during pitch/roll/yaws. I needed to track the translational movement by having the IMU's XYZ values unaffected by any changes in the IMU's orientation. Writing code for it was a nightmare because the MPU6050 is not so robust and its provides bogus values during any kind of dynamic motion.

 

I'm amazed the BNO055 works exactly how I need it to and it's so reliable. I didn't have to set any offsets, the thing just worked out of the box. Best of all I didn't need to run through that complicated mess of initializing the MPU6050's proprietary super secret DMP module.

 

I can finally progress to the next step of my development, so friggin' happy. Thanks so much for sharing your code!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi JungleEskimo,

Happy to help :) Good luck with your project.

Regards,
Frederic Philips