Forum: Mikrocontroller und Digitale Elektronik BM1422AGMV gibt ständig Maximalwert zurück


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Frager (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich versuche einen BM1422AGMV Magnetsensor zu verwenden, kann ihm jedoch 
keine korrekten Messdaten entlocken.

Es kommt ständig nur 2047 für alle Achsen im 12-Bit-Modus und 8191 im 
14-Bit-Modus zurück.

Dabei habe ich mich beim Programmieren an das Datenblatt gehalten:

https://fscdn.rohm.com/en/products/databook/datasheet/ic/sensor/geomagnetic/bm1422agmv-e.pdf

(Implementiert habe ich den Single Mode, den ich zyklisch aufrufe.)

Ich verwende ein Raspberry Pi Zero W, womit der BM1422AGMV mittels I2C 
und der DRDY-Leitung verbunden ist. Der relevante Schaltplanausschnitt 
als Bild ist anbei. Am Pi verwende ich WiringPi. Die I2C Kommunikation 
funktioniert, denn das "Who I am"-Register wird korrekt gelesen und es 
gibt noch weitere Chips, mit denen ebenfalls erfolgreich kommuniziert 
wird.

Die Ausgabe ist jedoch folgende:
1
I2C communication to magnet sensor successfully setup.
2
Magnetometer is now in single mode.
3
Measurement triggered...
4
X= 2047  Y= 2047  Z= 2047
5
Measurement triggered...
6
X= 2047  Y= 2047  Z= 2047
7
Measurement triggered...
8
X= 2047  Y= 2047  Z= 2047
9
Measurement triggered...
10
X= 2047  Y= 2047  Z= 2047
11
.
12
.
13
.
14
.



Hier mein Code:

main.cpp:
1
[...]
2
3
//Magnetsensor initialisieren und "Single Mode" (siehe Datenblatt S.17) aktivieren
4
    Bm1422agmv magnetsensor(MGN_ADDR);
5
    magnetsensor.setSingleMode();
6
7
[...]
8
9
while(1){
10
[...]
11
12
    magnetsensor.readData();
13
14
[...]
15
16
}

In bm1422agmv.cpp:
1
Bm1422agmv::Bm1422agmv(uint8_t addr)
2
{
3
4
  i2c_address = addr;
5
  mgn = wiringPiI2CSetupInterface("/dev/i2c-3", addr);
6
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
7
  if (mgn == -1) {
8
    std::cout << "Failed to init I2C communication to magnet sensor.\n";
9
    return;
10
  }
11
  if(wiringPiI2CReadReg8(mgn, 0x0F) != 0x41) { //Who I am Register muss 0x41 zurückgeben
12
    std::cout << "Failed to init I2C communication to magnet sensor.\n";
13
    return;
14
  }
15
  std::cout << "I2C communication to magnet sensor successfully setup.\n";
16
17
}
1
void Bm1422agmv::setSingleMode(void){
2
3
  //Siehe Datenblatt Seite 17 - Single Mode
4
5
  //Step1 - Power-Control=Active: PC1=1(CNTL1); Reset release: RST_LV=0(CNTL1), RSTB_LV=1(CNTL4)
6
  wiringPiI2CWriteReg8(mgn, 0x1B, 0x82); //CNTL1
7
  wiringPiI2CWriteReg8(mgn, 0x5C, 0x00); //CNTL4
8
  wiringPiI2CWriteReg8(mgn, 0x5D, 0x00); //CNTL4
9
10
  //Step2 - DRDY terminal enable: DREN=1(CNTL2)
11
  wiringPiI2CWriteReg8(mgn, 0x1C, 0x0C); //CNTL2
12
13
  //Step3 - Write offset data
14
  wiringPiI2CWriteReg8(mgn, 0x6C, 0x00); //Offset X
15
  wiringPiI2CWriteReg8(mgn, 0x72, 0x00); //Offset Y
16
  wiringPiI2CWriteReg8(mgn, 0x78, 0x00); //Offset Z
17
18
  std::cout << "Magnetometer is now in single mode." << std::endl;
19
20
}
1
void Bm1422agmv::readData(void){
2
  
3
  //Siehe Datenblatt Seite 17 - Single Mode
4
5
  //Step4 - Start measurement trigger: FORCE=1(CNTL3)
6
  wiringPiI2CWriteReg8(mgn, 0x1D, 0x40); //CNTL3
7
  std::cout << "Measurement triggered...\n";
8
9
  while(digitalRead(DRDY)==0); //Warten auf Daten
10
  std::cout << "Data ready...\n";
11
12
  int16_t dataX;
13
  int16_t dataY;
14
  int16_t dataZ;
15
16
  dataX = wiringPiI2CReadReg8(mgn, 0x10) | (wiringPiI2CReadReg8(mgn, 0x11)<<8); //DataX LSB...MSB
17
  dataY = wiringPiI2CReadReg8(mgn, 0x12) | (wiringPiI2CReadReg8(mgn, 0x13)<<8); //DataX LSB...MSB
18
  dataZ = wiringPiI2CReadReg8(mgn, 0x14) | (wiringPiI2CReadReg8(mgn, 0x15)<<8); //DataX LSB...MSB
19
20
  std::cout << "X= " << dataX << "  Y= " << dataY << "  Z= " << dataZ << "\n";
21
22
}

Was mache ich falsch?

Danke für eure Hilfe im Voraus!

von Anworter (Gast)


Lesenswert?

Hallo Frager,

am Besten mal den Offset Abgleich auskommentieren oder den Default Wert 
30h schreiben. 00h ist kein gültiger Wert für die Offset Register.

Viele Grüße
Antworter

von Frager (Gast)


Lesenswert?

Hallo Antworter!

Danke für deinen Tipp! Du hast absolut Recht, daran lag es! Dabei habe 
ich es sogar schon ausprobiert, den Offset auszukommentieren, hat aber 
nicht geholfen, da ich es vorhin schon geschrieben gehabt habe. Habe 
auch glatt übersehen, dass nicht 0x00, sondern 0x30 der Standardwert 
ist. Wieder was gelernt!

Danke dir nochmals! Du hast mir sehr geholfen!!

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.