drive HMC5883L (10DOF IMU / AHRS )

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

hi.

I need to drive HMC5883L with xmega128a1 but I am not understand the code that wrote for twi!

I found this code for avr

#include 
#include 
#include 
#include 
#include "twimaster.c"

#define HMC5883L_WRITE 0x3C // write address
#define HMC5883L_READ 0x3D // read address

int16_t raw_x = 0;
int16_t raw_y = 0;
int16_t raw_z = 0;

void init_HMC5883L(void){

	i2c_start(HMC5883L_WRITE);
	i2c_write(0x00); // set pointer to CRA
	i2c_write(0x70); // write 0x70 to CRA
	i2c_stop();

	i2c_start(HMC5883L_WRITE);
	i2c_write(0x01); // set pointer to CRB
	i2c_write(0xA0);
	i2c_stop();

	i2c_start(HMC5883L_WRITE);
	i2c_write(0x02); // set pointer to measurement mode
	i2c_write(0x00); // continous measurement
	i2c_stop();
}

void getHeading(void){

	i2c_start_wait(HMC5883L_WRITE);
	i2c_write(0x03); //set pointer to X-axis MSB
	i2c_stop();

	i2c_rep_start(HMC5883L_READ);

	raw_x = ((uint8_t)i2c_readAck())<<8;
	raw_x |= i2c_readAck();

	raw_z = ((uint8_t)i2c_readAck())<<8;
	raw_z |= i2c_readAck();

	raw_y = ((uint8_t)i2c_readAck())<<8;
	raw_y |= i2c_readNak();

	i2c_stop();
}

int main(void){

	i2c_init();
	init_HMC5883L();


	while(1){

		getHeading();

                // convert the raw data into a heading in degrees
		float headingDegrees = atan2((double)raw_y,(double)raw_x)* 180 / 3.14159265 + 180;

		/*
                Here you can do something with the heading data you just acquired
                */
	}
}

anyone knows that how change it for xmega?!
I wanted to use AVR1308 but I can not understand! :(

In addition I find this:
http://asf.atmel.com/docs/latest...

but again I do not know how can i use this!

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

I convert above code to this but still not working:(

#include "avr_compiler.h"
#include "twi_master_driver.h"

#define NUM_BYTES        8

/*! CPU speed 2MHz, BAUDRATE 100kHz and Baudrate Register Settings */
#define CPU_SPEED       32000000
#define BAUDRATE	100000
#define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)


/* Global variables */
TWI_Master_t twiMaster;    /*!< TWI master module. */


/*! Buffer with test data to send.*/
uint8_t sendBuffer[NUM_BYTES];

void TWIRun(void)
{
		// Enable internal pull-up on PC0, PC1.. Uncomment if you don't have external pullups
		PORTCFG.MPCMASK = 0x03; // Configure several PINxCTRL registers at the same time
		PORTC.PIN0CTRL = (PORTC.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches

		/* Initialize TWI master. */
		TWI_MasterInit(&twiMaster,
		&TWIC,
		TWI_MASTER_INTLVL_LO_gc,
		TWI_BAUDSETTING);

		/* Enable LO interrupt level. */
		PMIC.CTRL |= PMIC_LOLVLEN_bm;
		sei();
		
		sendBuffer[0]=0x00;
		sendBuffer[1]=0x70;
		while (TWI_MasterWrite(&twiMaster,0x3C,&sendBuffer,2) != TWIM_STATUS_READY)	WDT_Reset();
		
		sendBuffer[0]=0x01;
		sendBuffer[1]=0xA0;
		while (TWI_MasterWrite(&twiMaster,0x3C,&sendBuffer,2) != TWIM_STATUS_READY)	WDT_Reset();
		
		sendBuffer[0]=0x02;
		sendBuffer[1]=0x00;
		while (TWI_MasterWrite(&twiMaster,0x3C,&sendBuffer,2) != TWIM_STATUS_READY)	WDT_Reset();
		
		while(1)
		{
			while (TWI_MasterWrite(&twiMaster,0x3C,0x03,1) != TWIM_STATUS_READY)	WDT_Reset();

			
			while (TWI_MasterRead(&twiMaster,0x3D,8) != TWIM_STATUS_READY) WDT_Reset();
			
			USART_F1_PutC(twiMaster.readData);
		}
}

/*! TWIC Master Interrupt vector. */
ISR(TWIC_TWIM_vect)
{
	TWI_MasterInterruptHandler(&twiMaster);
}

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

Thank you all for guiding me :D!!!!!!!!!!!!!!

finally I could solve my problem.
That was about the slave address.
In atmel library we should shift the address 1 bit to right!

this is my final code:

#include "avr_compiler.h"
#include "twi_master_driver.h"

#define NUM_BYTES        8

/*! CPU speed 2MHz, BAUDRATE 100kHz and Baudrate Register Settings */
#define CPU_SPEED       32000000
#define BAUDRATE	400000
#define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)

#define HMC5883L_WRITE 0x1E // write address
#define HMC5883L_READ 0x1E // read address

/* Global variables */
TWI_Master_t twiMaster;    /*!< TWI master module. */


/*! Buffer with test data to send.*/
uint8_t sendBuffer[NUM_BYTES];



void TWIRun(void)
{
		// Enable internal pull-up on PC0, PC1.. Uncomment if you don't have external pullups
		PORTCFG.MPCMASK = 0x03; // Configure several PINxCTRL registers at the same time
		PORTC.PIN0CTRL = (PORTC.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches

		/* Initialize TWI master. */
		TWI_MasterInit(&twiMaster,
		&TWIC,
		TWI_MASTER_INTLVL_LO_gc,
		TWI_BAUDSETTING);

		/* Enable LO interrupt level. */
		PMIC.CTRL |= PMIC_LOLVLEN_bm;
		sei();
}
void DigitalCompass()
{
		sendBuffer[0]=0x00;
		sendBuffer[1]=0x70;
		TWI_MasterWrite(&twiMaster,HMC5883L_WRITE,&sendBuffer,2);
		while ( twiMaster.status != TWIM_STATUS_READY)	WDT_Reset();
		
		sendBuffer[0]=0x01;
		sendBuffer[1]=0xA0;
		TWI_MasterWrite(&twiMaster,HMC5883L_WRITE,&sendBuffer,2);
		while ( twiMaster.status != TWIM_STATUS_READY)	WDT_Reset();
		
		sendBuffer[0]=0x02;
		sendBuffer[1]=0x00;
		TWI_MasterWrite(&twiMaster,HMC5883L_WRITE,&sendBuffer,2);
		while ( twiMaster.status != TWIM_STATUS_READY)	WDT_Reset();
		
		WDT_Reset();
		sendBuffer[0]=0x03;
		TWI_MasterWrite(&twiMaster,HMC5883L_WRITE,&sendBuffer,1);
		while ( twiMaster.status != TWIM_STATUS_READY)	WDT_Reset();

		TWI_MasterRead(&twiMaster,HMC5883L_READ,6);
		while ( twiMaster.status != TWIM_STATUS_READY) WDT_Reset();
		
				 
		Compass_raw_x = ((uint8_t)twiMaster.readData[0])<<8;
		Compass_raw_x |= twiMaster.readData[1];

		Compass_raw_z = ((uint8_t)twiMaster.readData[2])<<8;
		Compass_raw_z |= twiMaster.readData[3];

		Compass_raw_y = ((uint8_t)twiMaster.readData[4])<<8;
		Compass_raw_y |= twiMaster.readData[5];
				
		//int headingDegrees =(int) (atan2((double)raw_y,(double)raw_x)* 180 / 3.14159265 + 180);
}

/*! TWIC Master Interrupt vector. */
ISR(TWIC_TWIM_vect)
{
	TWI_MasterInterruptHandler(&twiMaster);
}

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

Hi, can you please send the libraries 

twi_master_driver.h and twi_master_driver.c

 

 

 

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

search atmel site, it comes from them most likely.

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

I found the librairies but the code doesn't work

The gyro returns the same values of raw_x raw_y and raw_z even when i moved it.

 

The gyro is ok beacause it works well on Arduino. so i think i'm missing some thing.

 

Can you please provide an example for using TWI ( init , read and write ) without ASF 

 

Thank you

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

And why are you not searching it yourself? 

Document: http://www.atmel.com/images/doc8...

Software: http://www.atmel.com/Images/AVR1...

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

So nice he said it thrice!

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Not my problem Atmels servers are slower than my mouse clicks and "post reply" button is not debounced :D