Go Down

Topic: Digital Compass HMC6352 - How Did I Fix It (Read 1 time) previous topic - next topic

krew88

Jun 17, 2011, 10:05 pm Last Edit: Jun 17, 2011, 11:10 pm by krew88 Reason: 1
I bought this http://www.sparkfun.com/products/7915 digital compass for my project, I tested it and it was working properly on a breadboard using this code http://www.arduino.cc/playground/Learning/Hmc6352. But when I placed it on my robot (autonomous  kid car), that moves using a dc motor, the compass stopped working. I tested again on the breadboard and I was receiving 0.0 heading.  After reading the datasheet I managed to fit it. The strangest thing that I noticed was that Arduino wasn't able to send and to receive data from the compass. Then I use that sketch below (I founded somewhere on internet I don't remember where) in order to find the address that Arduino could send and receive data from the compass. This address for my compass was 63 or 191 (DEC).

Code: [Select]

/**
* I2CScanner.pde -- I2C bus scanner for Arduino
*
* 2009, Tod E. Kurt, http://todbot.com/blog/
*
*/

#include "Wire.h"
extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr,
                void(*callback)(byte address, byte result) )
{
  byte rc;
  byte data = 0; // not used, just an address to feed to twi_writeTo()
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr, &data, 0, 1);
    callback( addr, rc );
  }
}

// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
  Serial.print(addr,DEC);
  Serial.print( (result==0) ? " found!":"       ");
  Serial.print( (addr%4) ? "\t":"\n");
}


byte start_address = 1;
byte end_address = 100;

// standard Arduino setup()
void setup()
{
    Wire.begin();

    Serial.begin(19200);
    Serial.println("\nI2CScanner ready!");

    Serial.print("starting scanning of I2C bus from ");
    Serial.print(start_address,DEC);
    Serial.print(" to ");
    Serial.print(end_address,DEC);
    Serial.println("...");

    // start the scan, will call "scanFunc()" on result from each address
    scanI2CBus( start_address, end_address, scanFunc );

    Serial.println("\ndone");
}

// standard Arduino loop()
void loop()
{
    // Nothing to do here, so we'll just blink the built-in LED
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
}


krew88

#1
Jun 17, 2011, 10:06 pm Last Edit: Sep 03, 2011, 12:29 pm by krew88 Reason: 1
After that I used the playground sketch in order to get a heading. But this time I didn't use the address 0x42 (or 0x21). I used the address 63 (DEC) without any shift. And then…….. I got a heading between 359.5 and 0.5. Hmmmm very strange…..
Then I thought that something were wrong with calibration. I made a sketch that calibrates the compass.

Code: [Select]
#include <Wire.h>
int add=63;   //i proti pou pirame exei 63 (mporei kai 191)
void setup()
{
Serial.begin(9600);
Wire.begin();
}
void loop()
{
 delay(10000);
Serial.println("start");
 Wire.beginTransmission(add);
 Wire.send("C");  
 Wire.endTransmission();
 Serial.println("rotrate1");
 delay(20000);
 Serial.println("rotrate2");
 delay(20000);
 Serial.println("stop rotrate");
 Wire.beginTransmission(add);
 Wire.send("E");  
 Wire.endTransmission();
 delay(70);
 Wire.beginTransmission(add);
 Wire.send("L");  
 Wire.endTransmission();
 Serial.print("end");
  delay(500000);
}

According to datasheet, to do an accurate calibration you have to rotate the compass 360 deg in 20 seconds. You have to do this twice. So in my skech, when I see (in the Arduino serial monitor) "Rotate 1" I start rotating the compass for 360 deg in 20 sec. I do the same when I see "Rotate 2". And finally when I see "end" i remove the supply.
After that the compass was working on breadbourd.
I placed again to my robot and I had the same problem. The heading was 0.0…. Then I realized that something were wrong. I did all above again to fix the compass but this time I used different supply for Arduino (my laptop), not the battery that dc motor is supplied. So somthing goes wrong when compass and dc motor share the same supply.
I would appreciate if someone helps here…  

...And sorry for my English

robtillaart

Quote
e the compass 360 deg in 20 seconds.


is in conflict with

Serial.println("rotrate1");
  delay(25000);
  Serial.println("rotrate2");
  delay(25000);
  Serial.println("stop rotrate");

If there is too much iron (or nearby powerlines) on the robot it might disrupt the magnetic field resulting in faulty readings.

And please use the # button for code  -   "quote" is for text
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

krew88

#3
Jun 17, 2011, 11:21 pm Last Edit: Jun 18, 2011, 11:40 am by krew88 Reason: 1


is in conflict with

Serial.println("rotrate1");
 delay(25000);
 Serial.println("rotrate2");
 delay(25000);
 Serial.println("stop rotrate");


According to datasheet these rotation needs to be done between 6 sec and 3 min.
Anyway Fixed.

Quote

If there is too much iron (or nearby powerlines) on the robot it might disrupt the magnetic field resulting in faulty readings.


The heading was always 0. But when I use my laptop to supply Arduino it works.  

Quote

And please use the # button for code  -   "quote" is for text

Fixed.




Go Up