HMC5883

Grove is a modulated, ready-to-use tool set.
Much like Lego, it takes a building block approach to assembling electronics.

Moderators: lily.li, violet, salmanfarisvp, jeremy882, crail.lyu969

kruftin
Pre-kindergarten
Pre-kindergarten
Posts: 9
Joined: Sun May 20, 2012 11:26 pm
Are you a staff member of seeedstudio?: no
Which products/projects are your favorite?: hmc5883

HMC5883

Post by kruftin » Sun May 20, 2012 11:31 pm

I have Grove - 3-axis Compass v1.0b (HMC5883).
I connect this device to atmega32. And have as result from compass 0xFF as MSB and 0x00 as LSB in X,Y,Z registers. Why I have this problem? Voltage for compass pcb 3.3 volts.

http://www.seeedstudio.com/wiki/index.p ... pass_v1.0b

User avatar
deray
Elementary-3
Elementary-3
Posts: 327
Joined: Fri Mar 30, 2012 1:45 pm

Re: HMC5883

Post by deray » Mon May 21, 2012 11:24 am

It should be 0x03 - 0x08 in the datasheet. In the I2C program code, I just set the mode, and request receive.

Code: Select all

  Wire.beginTransmission(HMC5883_WriteAddress);  //Initiate a transmission with HMC5883 (Write address).
  Wire.requestFrom(HMC5883_WriteAddress,6);      //Request 6 bytes of data from the address specified.
How did you get the registers address ?

kruftin
Pre-kindergarten
Pre-kindergarten
Posts: 9
Joined: Sun May 20, 2012 11:26 pm
Are you a staff member of seeedstudio?: no
Which products/projects are your favorite?: hmc5883

Re: HMC5883

Post by kruftin » Mon May 21, 2012 1:20 pm

I use avr microcontroller without arduino. Sure I read registers 0x03...0x08.
Part of my code:

Code: Select all

void HMC5883(void)
{		
	//unsigned char xh, xl, yh, yl, zh, zl;
	long xo, yo, zo;
    
	
	i2cSendStart();
	i2cWaitForComplete();
	i2cWrite_Address(0x3C);    //write to HMC
	i2cWaitForComplete(); 
	i2cWrite_Data(0x02);    //mode register 
	i2cWaitForComplete();
	i2cWrite_Data(0x00);    //continuous measurement mode
	i2cWaitForComplete();
    //status_er = i2cGetStatus();
    //i2cCheckForMT_SLA();
	i2cSendStop(); 
    delay_ms(10);
	
	//must read all six registers plus one to move the pointer back to 0x03
	i2cSendStart();
	i2cWaitForComplete();
	i2cRead_Address(0x3D);          //read from HMC
    i2cWaitForComplete();
	i2cReceiveByte(TRUE);
	//i2cWaitForComplete();
	xh = i2cRead_Data();	//x high byte
	i2cWaitForComplete();  
    
	i2cReceiveByte(TRUE);
	i2cWaitForComplete();
	xl = i2cRead_Data();	//x low byte
	i2cWaitForComplete();
	xo = xl|(xh << 8);
	
	i2cReceiveByte(TRUE);
	i2cWaitForComplete();
    
	yh = i2cRead_Data();	//y high byte
	i2cWaitForComplete();
	
	i2cReceiveByte(TRUE);
	i2cWaitForComplete();
	yl = i2cRead_Data();	//y low byte
	i2cWaitForComplete();
	yo = yl|(yh << 8);
	
	i2cReceiveByte(TRUE);
	i2cWaitForComplete();
	zh = i2cRead_Data();	
	i2cWaitForComplete();      //z high byte
	
	i2cReceiveByte(TRUE);
	i2cWaitForComplete();
	zl = i2cRead_Data();	//z low byte
	i2cWaitForComplete();
	zo = zl|(zh << 8);
	
	i2cRead_Data();         //must reach 0x09 to go back to 0x03
	i2cWaitForComplete();
    i2cReceiveByte(TRUE);
	i2cWaitForComplete();
    status_er = i2cGetStatus();
	
	i2cSendStop();	
}

User avatar
deray
Elementary-3
Elementary-3
Posts: 327
Joined: Fri Mar 30, 2012 1:45 pm

Re: HMC5883

Post by deray » Mon May 21, 2012 2:32 pm

Code: Select all

i2cRead_Address(0x3D);          //read from HMC
It should be Ox3c.

kruftin
Pre-kindergarten
Pre-kindergarten
Posts: 9
Joined: Sun May 20, 2012 11:26 pm
Are you a staff member of seeedstudio?: no
Which products/projects are your favorite?: hmc5883

Re: HMC5883

Post by kruftin » Mon May 21, 2012 4:21 pm

Why? In datasheet address for reading is 0x3D. In status register of this compass i read value 0xff, it's very strange. How set default setting for compass or realize reset all configurations of HMC5883?

kruftin
Pre-kindergarten
Pre-kindergarten
Posts: 9
Joined: Sun May 20, 2012 11:26 pm
Are you a staff member of seeedstudio?: no
Which products/projects are your favorite?: hmc5883

Re: HMC5883

Post by kruftin » Tue May 22, 2012 11:57 am

I read status register of HMC5883 and i get 0xff, in configuration A register is 0xf0, in configuration B register is 0x20.

Tobe
Pre-kindergarten
Pre-kindergarten
Posts: 34
Joined: Tue Jan 17, 2012 11:04 am
Are you a staff member of seeedstudio?: yes
Which products/projects are your favorite?: Seeeduino

Re: HMC5883

Post by Tobe » Tue May 22, 2012 4:07 pm

If you can,you can post your i2cRead_Address function how to achieve,also the i2cWrite_Data function.
here is the change of the code:

Code: Select all

 //must read all six registers plus one to move the pointer back to 0x03
   i2cSendStart();
   i2cWaitForComplete();
   i2cRead_Address(0x3D);          //read from HMC
    i2cWaitForComplete();
   i2cReceiveByte(TRUE);

   delay_ms(500);

   //i2cWaitForComplete();
   xh = i2cRead_Data();   //x high byte
   i2cWaitForComplete();  
and you can try the 0x3D and 0x3C both.This is depanding on the function of the i2CRead_Address();if in the function you are already set the read bit "bit 0" to '1',then use the ox3C,if not use the 0x3D.

kruftin
Pre-kindergarten
Pre-kindergarten
Posts: 9
Joined: Sun May 20, 2012 11:26 pm
Are you a staff member of seeedstudio?: no
Which products/projects are your favorite?: hmc5883

Re: HMC5883

Post by kruftin » Tue May 22, 2012 6:57 pm

Yes, I can.

Code: Select all

void i2cRead_Address(unsigned char data)
{
	TWDR=data;	// Address and read instruction
	TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
	while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte received
	while((TWSR & 0xF8)!= 0x40);  // Check for the acknoledgement
}

unsigned char i2cRead_Data(void)
{
	TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
	while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
	while((TWSR & 0xF8) != 0x58); // Check for the acknoledgement
	recv_data=TWDR;
    return (TWDR);
}
void i2cWrite_Address(unsigned char data)
{
	TWDR=data;	// Address and write instruction
	TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
	while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
	while((TWSR & 0xF8)!= 0x18);  // Check for the acknoledgement
}
void i2cWrite_Data(unsigned char data)
{
	TWDR=data;	// put data in TWDR
	TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
	while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
	while((TWSR & 0xF8) != 0x28); // Check for the acknoledgement
}
I try to use example from datasheet on HMC5883L, but i don't understand what mean "Send 0x3D 0x06".

Tobe
Pre-kindergarten
Pre-kindergarten
Posts: 34
Joined: Tue Jan 17, 2012 11:04 am
Are you a staff member of seeedstudio?: yes
Which products/projects are your favorite?: Seeeduino

Re: HMC5883

Post by Tobe » Thu May 24, 2012 5:18 pm

The 0x3D 0x06 just for the arduino firmware,that mean is to read 6 datas from the HMC5883.
For the code,you can consult the arduino demo code.

kruftin
Pre-kindergarten
Pre-kindergarten
Posts: 9
Joined: Sun May 20, 2012 11:26 pm
Are you a staff member of seeedstudio?: no
Which products/projects are your favorite?: hmc5883

Re: HMC5883

Post by kruftin » Thu May 24, 2012 7:37 pm

Now all work good. I wrote code, where i move pointer to each data registers and read it.

Post Reply