Society of Robots - Robot Forum
Software => Software => Topic started by: silo_xtreme on December 04, 2009, 10:32:04 AM
-
Hey All,
I'm just wondering what kind of results you get with the HMC6352 compass. I'm seeing my heading change by about 3 degrees from a stationary point. I'm using the average from 50 samples to get my heading.
What typical results do you get?
Mike
-
If you look in the datasheet, the typical accuracy is 2.5 degrees. Your results is not surprising then.
Chelmi.
-
Silo, did you notice that your degree values were off from the beginning, ie north was not 0/359 degrees?
I got the HMC6352 also, but the degree values are off... I think it may have to be partly because I reset the factory calibrated settings :o
-
My values are jumping , so i can't tell about North.
I can't explain this:
The robot is stationary, no moving parts, sitting in my lab, facing about 3 degrees from North (maybe), connected to a DC power supply, and each measurement is 6ms apart. Here's 50 samples from the compass at intervals as follows:
At init(). I turn it on
51 51 0 254 194 70 80 141 80 70 9 70 80 8 80 132 80 70 122 141 80 141 194 70 80
132 194 70 194 141 194 70 80 70 80 70 80 141 217 132 140 141 9 60 19 141 194 141
19 141 194
After 1 second.
60 60 141 8 140 122 132 141 140 141 122 80 0 141 194 132 8 141 122 132 132 132 1
94 132 194 132 194 60 80 132 122 132 203 132 132 141 203 122 51 141 122 132 9 14
1 80 194 122 132 132 16 122
After 30 minutes
80 80 140 8 231 217 184 70 0 8 0 9 131 9 0 140 0 132 0 184 0 0 184 194 0 6 194 1
94 140 0 0 184 0 113 9 0 80 0 0 94 9 6 194 6 0 113 194 0 194 87 0
I was trying to see if the measurements would eventually stabilize.
Any one know what's going on? is 6 ms not long enough between measurements?
-
Those readings are junk - there's no meaningful data.
The 6352 can be configured to capture at 1, 5, 10 or 20Hz. You are trying to capture at 166Hz.
-
hgordon,
you're right. I think i'm in Query Mode and was thinking I could get a reading every 6ms. Let me try to put it into continuous mode and see if that resolves the problem.
Many thanks!!
-
ok hgordon,
I tried putting the HMC6352 into continuous mode with no luck. So, I slowed down the code to every 500 ms and still my measurements are funky.
Here's my code for my Xmega.
void EnableCompass(void)
{
// init compass
//configure PORTC PC0 and PC1 for output ... probably want to move this to a global init() function.
bool retval =false;
uint8_t address = 33;
uint8_t TWI_transBuff[4] = {0,0,0,0};
uint8_t result=0;
PORT_SetPinAsOutput(&PORTC,PIN0_bp);
PORT_SetPinAsOutput(&PORTC,PIN1_bp); // I know this can be optimized.
/* Initialize TWI master. */
TWI_MasterInit(&twiMaster,
&TWIC,
TWI_MASTER_INTLVL_LO_gc,
TWI_BAUDSETTING);
/* Enable LO interrupt level. */
PMIC.CTRL |= PMIC_LOLVLEN_bm;
sei();
while (twiMaster.status != TWIM_STATUS_READY) {
// /* Wait until transaction is complete. */
}
TWI_transBuff[0]=0x47; // Write to RAM command
retval=TWI_MasterWrite(&twiMaster,address,TWI_transBuff,1);
delay_us(70);
while (twiMaster.status != TWIM_STATUS_READY) {
// /* Wait until transaction is complete. */
}
TWI_transBuff[0]=0x74; // RAM memory Location
retval = TWI_MasterWrite(&twiMaster,address,TWI_transBuff,1);
while (twiMaster.status != TWIM_STATUS_READY) {
// /* Wait until transaction is complete. */
}
delay_us(70);
TWI_transBuff[0]=0x71; // Operational Mode Setup
retval = TWI_MasterWrite(&twiMaster,address,TWI_transBuff,1);
_delay_ms(1000); // long wait to let HMC perform command
// Copy Operational Mode into EEPROM
while (twiMaster.status != TWIM_STATUS_READY) {
// /* Wait until transaction is complete. */
}
TWI_transBuff[0]=0x4C;
retval = TWI_MasterWrite(&twiMaster,address,TWI_transBuff,1);
TWI_MasterTransactionFinished(&twiMaster,result);
_delay_ms(1000); // long wait to let HMC perform command
}
float GetHeading(void)
{
float heading=0.0; // initialize heading
uint8_t TWI_Operation;
uint8_t BufPos = 0;
uint8_t TWI_recBuff[3] = {0,0,0};
uint8_t TWI_transBuff[4] = {0,0,0,0};
unsigned char data[2]={0,0};
uint8_t address = 33; // read address
bool retval =false;
while (twiMaster.status != TWIM_STATUS_READY) {
/* Wait until transaction is complete. */
}
TWI_transBuff[0]='A';
// retval=TWI_MasterRead(&twiMaster,address,2);
retval = TWI_MasterWriteRead(&twiMaster,address,TWI_transBuff,1,2);
delay_us(6000);
while (twiMaster.status != TWIM_STATUS_READY) {
/* Wait until transaction is complete. */
}
TempValue=((twiMaster.readData[0] << 8) | (twiMaster.readData[1]));
// USART_PutChar(&USARTF1,(char)heading);
USART_TXBuffer_PutByte(&USART_data,TempValue);
heading = (float)((twiMaster.readData[0] << 8) | (twiMaster.readData[1]))/10.0;
return heading;
}
/*! TWIC Master Interrupt vector. */
ISR(TWIC_TWIM_vect)
{
TWI_MasterInterruptHandler(&twiMaster);
}
then to call the measurements every 500 ms I call this function:
float GetavgHeading(void)
{
int hcount=0;
float heading=0;
float avgHeading=0;
for (hcount=0;hcount<50; hcount++)
{
heading+=GetHeading();
_delay_ms(500);
}
avgHeading = heading/hcount;
return avgHeading;
}
my resulting measurements are (divide by 10 to get the actual heading numbers):
9 70 140 140 194 0 132 140 202 132 0 122 78 132 8 202 132 140 140 6 194 9 132 14
9 140 140 8 0 6 132 70 140 140 149 132 132 0 9 132 0 0 9 122 0 0 140 9 0 141
I think I can't get to continuous mode because perhaps I have the wrong read address? Anyhoo, I should still get better data than this in query mode, shouldn't I? ???
my code reuses the drivers from AVR1308: Using the XMEGA TWI
-
I don't use the continuous mode, but rather read the compass twice in succession with a 20ms delay between reads. I'm reading via the 0x41 command and use factor defaults.
-
hgordon ,
Could you post some raw data and code you use to generate it? I'd like to be able to reproduce some sanity, and maybe figure out if my chip went bad or something?
-
We switched to using the HMC5843, so I don't have a data dump, but the HMC6352 data was stable. Here's the code we use in the SRV-1 Blackfin firmware -
void read_compass2x()
{
unsigned char i2c_data[3];
unsigned int ix;
i2c_data[0] = 0x41; // read compass twice to clear last reading
i2cread(0x22, (unsigned char *)i2c_data, 2, SCCB_ON);
delayUS(20000);
i2c_data[0] = 0x41;
i2cread(0x22, (unsigned char *)i2c_data, 2, SCCB_ON);
ix = (((unsigned int)i2c_data[0] << 8) + i2c_data[1]) / 10;
printf("##$C %3d\r\n", ix);
}
-
Interesting..... What are you using as your Baud rate 100khz? Maybe my baud rate setting is wrong, and could cause this instability?
-
Well perhaps not. I think my baud rate register at 0x05 is correct for a 2Mhz clock . Hmm ...
-
I use 100kHz.
-
Hey Everyone.
This problem was due to a bad sensor. For some reason the compass was bad or damaged, the other board we had with the same compass works great. I'm getting about 0.2 deg accuracy (on a work bench).
;D