Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    BMX055 Magnetometer readings in SPI

    BMX055 Magnetometer readings in SPI

    MGirão
    Member

    Hi!
    I have been working with the BMX055 IMU module and i had a problem with reading the Magnetometer in SPI. I've working with an Arduino Mega and have tried I2C wich worked just fine but when i turn it to SPI,Accelarometerand Gyroscope i can read again, I can't just read the Mag. I have been following the datasheet but nothing quite work.

    I would like to ask if anyone have a tip or an example for arduino to help me. Below i leave the program i have for ACC and Gyro.

    Thank you.

     

    #include <SPI.h>

    int CSB1 = A2;
    int CSB3 = A0;
    int CSB2 = A1;

    unsigned int x_lsb = 0x02;
    unsigned int y_lsb = 0x04;
    unsigned int z_lsb = 0x06;

    const byte READ = 0b10000000; // SCP1000's read command

    void setup() {
    pinMode(CSB1, OUTPUT);
    pinMode(CSB2, OUTPUT);
    pinMode(CSB3, OUTPUT);

    Serial.begin(9600);
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV64);
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE0);

    digitalWrite(CSB1, HIGH);
    digitalWrite(CSB2, HIGH);
    digitalWrite(CSB3, HIGH);
    }

    int readAcc(unsigned int coor) {
    int aux;

    digitalWrite(CSB1, LOW);
    SPI.transfer(0x80 + coor); // prepare for read operation register coor where are LSB.
    aux = SPI.transfer(0x00); // reads LSB (4 bits)
    digitalWrite(CSB1, HIGH);

    //check if acceleration value has been updated since last it has been read out last
    if (aux & 1) {
    aux = aux >> 4;

    digitalWrite(CSB1, LOW);
    SPI.transfer(0x80 + coor + 1); // MSB is on the next register
    aux += (SPI.transfer(0x00) << 4); // sums MSB and LSB
    if (aux & 0x800)
    aux &= ~(0x800);
    digitalWrite(CSB1, HIGH);

    return aux;
    }
    else
    return 0;
    }

    int readGyr(unsigned int coor) {
    int lsb;
    int msb;
    int aux;

    digitalWrite(CSB2, LOW);
    SPI.transfer(0x80 + coor);
    lsb = SPI.transfer(0x00);
    digitalWrite(CSB2, HIGH);

    digitalWrite(CSB2, LOW);
    SPI.transfer(0x80 + coor + 1);
    msb = SPI.transfer(0x00);
    digitalWrite(CSB2, HIGH);

    aux = msb;

    if (lsb & 0x80) {
    lsb = ~lsb;
    lsb &= 0x7F;
    lsb++;
    }

    if (msb & 0x80) {
    msb = ~msb;
    msb &= 0x7F;
    msb++;
    }

    if (aux & 0x80) {
    aux = (msb << 8 )  + lsb;
    aux = ~aux;
    aux++;
    }
    else {
    aux = (msb << 8 )+ lsb;
    }

    // Serial.print(" msb:");
    // Serial.println(msb);
    // Serial.print(" lsb:");
    // Serial.println(lsb);

    return aux;
    }


    void loop() {

    int x, y, z;

    ////////////////////////////////////////////////////////////////////////ACC READ / PRINT

    x = readAcc(x_lsb);
    y = readAcc(y_lsb);
    z = readAcc(z_lsb);

    //Serial.print("Acc x:");
    Serial.print(x);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.println(z);

    //////////////////////////////////////////////////////////////////////////GYRO READ / PRINT

    x = readGyr(x_lsb);
    y = readGyr(y_lsb);
    z = readGyr(z_lsb);

    //Serial.print("Gyr x:");
    Serial.print(x);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.println(z);
    }

    2 REPLIES 2

    Vincent
    Community Moderator
    Community Moderator

    The SPI protocol for magnetic unit inside BMX055 is same as Accel and gyro part of BMX055. 

    So the code works for accel and gyro should also work for magnetic part.

    One thing need to care about, for magnetic part, CSB3 are also used for i2c address selection.  so if you use it under i2c mode before, this pin is pull down or pull high by external register or directly tie to VDDIO / GND.  For working under SPI mode, you should release the pin to make host controllable. 

    One more hint:  in your sample code, you read lsb and msb data from sensor in two SPI read action.  it is not recommend to do so.  In order to get correct data from sensor, you need to do burst read for both sensor from the register. 

    int readMag(unsigned int coor) {

    int aux;

     digitalWrite(CSB3, LOW);
     SPI.transfer(0xC0 + coor);
     aux = (SPI.transfer(0x00) >> 3);

     digitalWrite(CSB3, HIGH);

     digitalWrite(CSB3, LOW);
     SPI.transfer(0xC0 + coor + 1);
     aux += (SPI.transfer(0x00) << 5);
     digitalWrite(CSB3, HIGH);

    return aux;

    }

    void loop(){

    ////////////////////////////////////////////////////////////////////////////MAG READ / PRINT

    x = readMag(x_lsb);
    y = readMag(y_lsb);
    z = readMag(z_lsb);

    Serial.print(x);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.println(z);

    }

    I have tried reading the mag like this and still no result. I did use I2C before but dont understand what you mean by releasing the pin for host control.

    I also used (0x80),instead of (0xC0) (and many other specified in datasheets), for the readings, as used in the acc and gyro and no result.

    Thank you again!

     

     

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist