Подключение трех MPU 9250 (бюджет 1000 руб)

Тема в разделе "Закажу проект", создана пользователем Artclonic, 17 апр 2018.

  1. Artclonic

    Artclonic Гик

    Есть готовыи код подключения MPU 9250, нужно внести изменения на подключение и соответственно считывания значении с трех модулеи либо через SPI либо с помощью библиотеки
    #include <SoftwareWire.h>
    SoftwareWire myWire1(4, 5);//4 sda and 5 scl
    SoftwareWire myWire2(6, 7);//6 sda and 7 scl
    SoftwareWire myWire2(8, 9);//6 sda and 7 scl
    Вот код
    Код (C++):
    #include <Wire.h>



    #define    MPU9250_ADDRESS            0x68
    #define    MAG_ADDRESS                0xC
    #define AK8963_ADDRESS                0xC
    #define AK8963_ST1                    0x02

    #define    GYRO_FULL_SCALE_250_DPS    0x00
    #define    GYRO_FULL_SCALE_500_DPS    0x08
    #define    GYRO_FULL_SCALE_1000_DPS   0x10
    #define    GYRO_FULL_SCALE_2000_DPS   0x18

    #define    ACC_FULL_SCALE_2_G        0x00
    #define    ACC_FULL_SCALE_4_G        0x08
    #define    ACC_FULL_SCALE_8_G        0x10
    #define    ACC_FULL_SCALE_16_G       0x18
    #define    Pi                        3,1415926

    #define WHO_AM_I_MPU9250             0x75


    enum Mscale {
      MFS_14BITS = 0, // 0.6 mG per LSB
      MFS_16BITS      // 0.15 mG per LSB
    };

    uint8_t Mmode = 0x06;
    uint8_t Mscale = MFS_16BITS;
    float aRes, gRes, mRes;


    float X ;
    float Y ;
    float Z ;



    void getMres() {
      switch (Mscale)
      {
      // Possible magnetometer scales (and their register bit settings) are:
      // 14 bit resolution (0) and 16 bit resolution (1)
        case MFS_14BITS:
              mRes = 10.*4912./8190.; // Proper scale to return milliGauss
              break;
        case MFS_16BITS:
              mRes = 10.*4912./32760.0; // Proper scale to return milliGauss
              break;
      }
    }

    // This function read Nbytes bytes from I2C device at address Address.
    // Put read bytes starting at register Register in the Data array.
    void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data)
    {
      // Set register address
      Wire.beginTransmission(Address);
      Wire.write(Register);
      Wire.endTransmission(false);

      // Read Nbytes
      Wire.requestFrom(Address, Nbytes);
      uint8_t index=0;
      while (Wire.available())
        Data[index++]=Wire.read();
    }


    // Write a byte (Data) in device (Address) at register (Register)
    void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)
    {
      // Set register address
      Wire.beginTransmission(Address);
      Wire.write(Register);
      Wire.write(Data);
      Wire.endTransmission();
    }


    float xv, yv, zv;

    //calibrated_values[3] is the global array where the calibrated data will be placed
    //calibrated_values[3]: [0]=Xc, [1]=Yc, [2]=Zc
    float calibrated_values[3];
    //transformation(float uncalibrated_values[3]) is the function of the magnetometer data correction
    //uncalibrated_values[3] is the array of the non calibrated magnetometer data
    //uncalibrated_values[3]: [0]=Xnc, [1]=Ync, [2]=Znc
    void transformation(float uncalibrated_values[3])
    {
      //calibration_matrix[3][3] is the transformation matrix
      //replace M11, M12,..,M33 with your transformation matrix data
      double calibration_matrix[3][3] =
      {
        {2195.878755, -32.093680, 6.147725},// Матрица пока не верная но уже работает!
        {-32.093680, 2372.162687, -7.654780},
        {6.147725, -7.654780, 2407.630918}
      };
      //bias[3] is the bias
      //replace Bx, By, Bz with your bias data
      double bias[3] =
      {
        0.189463,
        -0.176225,
        0.127606
      };
      //calculation
      for (int i=0; i<3; ++i) uncalibrated_values[i] = uncalibrated_values[i] - bias[i];
      float result[3] = {0, 0, 0};
      for (int i=0; i<3; ++i)
        for (int j=0; j<3; ++j)
          result[i] += calibration_matrix[i][j] * uncalibrated_values[j];
      for (int i=0; i<3; ++i) calibrated_values[i] = result[i];
    }

    //vector_length_stabilasation() - is the function of the magnetometer vector length stabilasation (stabilisation of the sphere radius)
    float scaler;
    boolean scaler_flag = false;
    float normal_vector_length;
    void vector_length_stabilasation(){
      //calculate the normal vector length
      if (scaler_flag == false)
      {
        getHeading();
        normal_vector_length = sqrt(calibrated_values[0]*calibrated_values[0] + calibrated_values[1]*calibrated_values[1] + calibrated_values[2]*calibrated_values[2]);
        scaler_flag = true;
      }
      //calculate the current scaler
      scaler = normal_vector_length/sqrt(calibrated_values[0]*calibrated_values[0] + calibrated_values[1]*calibrated_values[1] + calibrated_values[2]*calibrated_values[2]);
      //apply the current scaler to the calibrated coordinates (global array calibrated_values)
      calibrated_values[0] = calibrated_values[0]*scaler;
      calibrated_values[1] = calibrated_values[1]*scaler;
      calibrated_values[2] = calibrated_values[2]*scaler;
    }

    // Initializations
    void setup()
    {
      // Arduino initializations
      Wire.begin();
      Serial.begin(115200);

      // Configure gyroscope range
      I2CwriteByte(MPU9250_ADDRESS,27,GYRO_FULL_SCALE_2000_DPS);
      // Configure accelerometers range
      I2CwriteByte(MPU9250_ADDRESS,28,ACC_FULL_SCALE_16_G);
      // Set by pass mode for the magnetometers
      I2CwriteByte(MPU9250_ADDRESS,0x37,0x02);

      // Request first magnetometer single measurement
      I2CwriteByte(MAG_ADDRESS,0x0A,Mscale << 4 | Mmode );//Mscale << 4 | Mmode

    }


    long int cpt=0;
    // Main loop, read and display data

    void loop()
    {

      // _______________
      // ::: Counter :::

      // Display data counter
      //Serial.print (cpt++,DEC);
      //Serial.print ("\t");

      // ____________________________________
      // :::  accelerometer and gyroscope :::

      // Read accelerometer and gyroscope
      uint8_t Buf[14];
      I2Cread(MPU9250_ADDRESS,0x3B,14,Buf);


      // Create 16 bits values from 8 bits data

      // Accelerometer
      int16_t ax=-(Buf[0]<<8 | Buf[1]);
      int16_t ay=-(Buf[2]<<8 | Buf[3]);
      int16_t az=Buf[4]<<8 | Buf[5];

      // Gyroscope
      int16_t gx=-(Buf[8]<<8 | Buf[9]);
      int16_t gy=-(Buf[10]<<8 | Buf[11]);
      int16_t gz=Buf[12]<<8 | Buf[13];

        // Display values

       //Accelerometer
      //Serial.print ("Значения акселерометра");
      //Serial.print ("\t");
      //Serial.print (ax,DEC);
      //Serial.print ("\t");
      //Serial.print (ay,DEC);
      //Serial.print ("\t");
      //Serial.print (az,DEC);
      //Serial.print ("\t");

       //Gyroscope
      //Serial.print ("Значения гироскопа");
      //Serial.print ("\t");
      //Serial.print (gx,DEC);
      //Serial.print ("\t");
      //Serial.print (gy,DEC);
      //Serial.print ("\t");
      //Serial.print (gz,DEC);
      //Serial.print ("\t");


      // _____________________
      // :::  Magnetometer :::



       //Read register Status 1 and wait for the DRDY: Data Ready

      //uint8_t ST1;
      //do
      //{
       // I2Cread(MAG_ADDRESS,0x02,1,&ST1);
      //}
         // while (!(ST1&0x01));

     

      if(readByte(MAG_ADDRESS, 0x02)& 0x01); {
      // Read magnetometer data
      uint8_t Mag[7];
      //readBytes(AK8963_ADDRESS, 0x03, 7, &Mag[0]);

      I2Cread(MAG_ADDRESS,0x03,7,&Mag[0]);

      uint8_t c = Mag[6];

    if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
     
      // Create 16 bits values from 8 bits data

      // Magnetometer
      int16_t mx=-(Mag[3]<<8 | Mag[2]);
      int16_t my=-(Mag[1]<<8 | Mag[0]);
      int16_t mz=-(Mag[5]<<8 | Mag[4]);





      X = mx;
      Y = my;
      Z = mz;





    //float values_from_magnetometer[3];

    // getHeading();
    // values_from_magnetometer[0] = xv;
      //values_from_magnetometer[1] = yv;
      //values_from_magnetometer[2] = zv;
      //transformation(values_from_magnetometer);

      //vector_length_stabilasation();

      //Serial.flush();
      //Serial.print(calibrated_values[0]);
      //Serial.print(",");
    // Serial.print(calibrated_values[1]);
      //Serial.print(",");
      //Serial.print(calibrated_values[2]);
    // Serial.println();

    // delay(100);



      // Magnetometer
      //Serial.print ("Значения магнитометра");
      //Serial.print ("\t");
      Serial.print (X ,DEC);
      Serial.print ("\t");
      Serial.println (Y ,DEC);
      Serial.println ("\t");
      Serial.print (Z ,DEC);
      Serial.print ("\t");
      Serial.print ( Mscale << 4 | Mmode ,DEC);
      Serial.print ("\t");

    // Serial.print (mx,DEC);
      //Serial.print ("\t");
      //Serial.println (my ,DEC);
      //Serial.println ("\t");
      //Serial.print (mz,DEC);
      //Serial.print ("\t");
      }

      }


      // End of line
      //Serial.println("");
    delay(100);
    }

    uint8_t readByte(uint8_t address, uint8_t subAddress)
    {
      uint8_t data; // `data` will store the register data
      Wire.beginTransmission(address);         // Initialize the Tx buffer
      Wire.write(subAddress);                  // Put slave register address in Tx buffer
      Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
      Wire.requestFrom(address, (uint8_t) 1);  // Read one byte from slave register address
      data = Wire.read();                      // Fill Rx buffer with result
      return data;                             // Return data read from slave register
    }

    void getHeading()
    {

      xv = X;
      yv = Y;
      zv = Z;
    }
     
  2. Artclonic

    Artclonic Гик

    Повторюсь...
     
  3. man9913

    man9913 Гик

    может 2к?
     
  4. Artclonic

    Artclonic Гик

    Две тыс?
     
  5. man9913

    man9913 Гик

    по spi могу сделать за 2тыр
     
  6. Artclonic

    Artclonic Гик

    Ок! Я согласен на 2 тыщ, три момента две кнопки ещё прикрутить, одна для передачи данных в порт, другая при длительном нажатии 3 сек пишет в порт слово, и третье это реализация разницы между предыдущим и текущим значением, на примере одного значения, я потом разнести для всех значений.
     
  7. man9913

    man9913 Гик

    отписался в личку