Forum: Compiler & IDEs HMC5883L gibt falsche Werte aus


von Patrick B. (p51d)


Lesenswert?

Hallo miteinander
Ich versuche gerade ein wenig mit dem HMC5883L zu spielen. Kommunikation 
läuft soweit, aber leider gibt er mir nicht die richtigen Werte aus. 
Wenn ich eine 180° Drehung mache, dann bekomme ich nur ein Winkel 
zwischen 240 und 300°.
Ich habe mich mitlerweile durch diverse Foren gewühlt, wo Anleitungen zu 
diesem Kompass sind, aber dabei komme ich immer auf den gleichen Wert.

Kann mir jemand sagen, was ich übersehen habe?
1
void HMC5883L_init(void)
2
{
3
    // write CONFIG_A register
4
    uint8_t tmp = (HMC5883L_AVERAGING_8 << (HMC5883L_CRA_AVERAGE_BIT - HMC5883L_CRA_AVERAGE_LENGTH + 1)) |
5
                  (HMC5883L_RATE_15 << (HMC5883L_CRA_RATE_BIT - HMC5883L_CRA_RATE_LENGTH + 1)) |
6
                  (HMC5883L_BIAS_NORMAL << (HMC5883L_CRA_BIAS_BIT - HMC5883L_CRA_BIAS_LENGTH + 1)) ;
7
8
    /*ENABLE*/
9
    I2C_Cmd(HMC5883L_I2C, ENABLE);
10
11
    HMC5883L_I2C_ByteWrite(HMC5883L_DEFAULT_ADDRESS, &tmp ,HMC5883L_RA_CONFIG_A);
12
13
    // write CONFIG_B register
14
    HMC5883L_SetGain(HMC5883L_GAIN_1090);
15
16
    // write MODE register
17
    HMC5883L_SetMode(HMC5883L_MODE_SINGLE);
18
}
19
20
void HMC5883L_GetHeading(int16_t* Mag)
21
{
22
  uint8_t tmpbuff[6]={0};
23
  int i = 0;
24
  HMC5883L_I2C_BufferRead(HMC5883L_DEFAULT_ADDRESS, tmpbuff, HMC5883L_RA_DATAX_H, 6);
25
26
  uint8_t tmp = HMC5883L_MODE_SINGLE << (HMC5883L_MODEREG_BIT - HMC5883L_MODEREG_LENGTH + 1);
27
28
  if (HMC5883Lmode == HMC5883L_MODE_SINGLE)
29
    HMC5883L_I2C_ByteWrite(HMC5883L_DEFAULT_ADDRESS, &tmp ,HMC5883L_RA_MODE);
30
  for(i=0; i<3; i++)
31
    Mag[i]=((int16_t)((uint16_t)tmpbuff[2*i] << 8) + tmpbuff[2*i+1]);
32
}
33
  
34
systick_ticks = 0;
35
HMC5883L_GetHeading(MagneticHeading);
36
Heading = atan2(MagneticHeading[1], MagneticHeading[0]);
37
declinationAngle = 25.02  / 1000.0;                // Your mrad result / 1000.00 (to turn it into radians).
38
Heading += declinationAngle;                  // If you have an EAST declination, use += declinationAngle, if you have a WEST declination, use -= declinationAngle
39
if(Heading < 0)      Heading += 2 * M_PI;          // Correct for when signs are reversed.
40
if(Heading > (2* M_PI))  Heading -= 2 * M_PI;          // Check for wrap due to addition of declination.
41
Heading = Heading * (180 / M_PI);                // Convert radians to degrees for readability.
42
sprintf((char *)buf, "\r\nX: %d\t\tY: %d\t\tZ: %d\t\tHeading: %3.2f",
43
  (int)MagneticHeading[0], (int)MagneticHeading[1], (int)MagneticHeading[2], Heading);
44
VCP_send_str(&buf[0]);

Besten Dank für die Antowrt
MFG
Patrick

von Joachim .. (joachim_01)


Lesenswert?

Hmmm, weiß jetzt nicht ob dir das weiterhilft... vielleicht ist der 
Kompass falsch parametriert? Sparkfun löst es so:
1
C-Code
2
3
void HMC5843(void)
4
{    
5
  uint8_t xh, xl, yh, yl, zh, zl;
6
  long xo, yo, zo;
7
  
8
  i2cSendStart();
9
  i2cWaitForComplete();
10
  i2cSendByte(0x3C);    //write to HMC
11
  i2cWaitForComplete();
12
  i2cSendByte(0x02);    //mode register
13
  i2cWaitForComplete();
14
  i2cSendByte(0x00);    //continuous measurement mode
15
  i2cWaitForComplete();
16
  i2cSendStop();
17
  
18
  //must read all six registers plus one to move the pointer back to 0x03
19
  i2cSendStart();
20
  i2cWaitForComplete();
21
  i2cSendByte(0x3D);          //read from HMC
22
  i2cWaitForComplete();
23
  i2cReceiveByte(TRUE);
24
  i2cWaitForComplete();
25
  xh = i2cGetReceivedByte();  //x high byte
26
  i2cWaitForComplete();
27
  //printf(" %d", xh);
28
  
29
  i2cReceiveByte(TRUE);
30
  i2cWaitForComplete();
31
  xl = i2cGetReceivedByte();  //x low byte
32
  i2cWaitForComplete();
33
  xo = xl|(xh << 8);
34
  printf("x=%4ld, ", xo);
35
  
36
  i2cReceiveByte(TRUE);
37
  i2cWaitForComplete();
38
  yh = i2cGetReceivedByte();  //y high byte
39
  i2cWaitForComplete();
40
  //printf(" %d ", yh);
41
  
42
  i2cReceiveByte(TRUE);
43
  i2cWaitForComplete();
44
  yl = i2cGetReceivedByte();  //y low byte
45
  i2cWaitForComplete();
46
  yo = yl|(yh << 8);
47
  printf("y=%4ld, ", yo);
48
  
49
  i2cReceiveByte(TRUE);
50
  i2cWaitForComplete();
51
  zh = i2cGetReceivedByte();  
52
  i2cWaitForComplete();      //z high byte
53
  //printf(" %d ", zh);
54
  
55
  i2cReceiveByte(TRUE);
56
  i2cWaitForComplete();
57
  zl = i2cGetReceivedByte();  //z low byte
58
  i2cWaitForComplete();
59
  zo = zl|(zh << 8);
60
  printf("z=%ld \r\n", zo);
61
  
62
  i2cSendByte(0x3D);         //must reach 0x09 to go back to 0x03
63
  i2cWaitForComplete();
64
  
65
  i2cSendStop();  
66
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.