HMC5883L gibt falsche Werte aus

OP #2978990
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
#2979131
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
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.