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!