Помогите с I2c сенсорами.

Тема в разделе "Arduino & Shields", создана пользователем AlisherRobotRex, 19 мар 2018.

  1. Что нужно кроме этого в программе поменять?
     
  2. Belkin

    Belkin Гик

    Для начала расскажите, что и где в листинге из первого поста делается.
    Вот лично для меня, если не трудно, т.к. я в Си не работаю и плохо его понимаю...
    Будут разъяснения - подскажу. А скорее всего - сами поймете... ;)
     
  3. Я не могу хорошо рассказать, углублённо, что в листинге происходит, только в общих чертах. Но на сайте: https://arduino-kit.ru/catalog/id/modul-3-h-osevogo-g.. я нашёл про изменение адреса. Там написано, что адрес может быть без бита чтения, записи. Но я не понимаю, как это применить к алгоритму
     
  4. Или что без бита записи/чтения, это не важно в плане кода?
     
  5. Belkin

    Belkin Гик

    Это говорит только о том, что адрес - 7 бит, а 8-й бит указывает на режим работы.
    Если удастся реализовать протокол 7-битного приема/передачи, то этот 8-й бит можно (пока) игнорировать. ;)
    А пока все протоколы заточены на работу с целями байтами - придется изучать системы счисления и поглубже вчитываться в даташиты... ;)
     
  6. Belkin

    Belkin Гик

    Вот как так можно - иметь поверхностное представления о языке, на котором пишется программа, но каким-то образом что-то пытаться сделать ? :rolleyes:
    Это, как учится ездить на велосипеде, сидя на диване и читая книжки про это...
     
  7. Я синтаксис знаю, но команды библиотеки Wire не знаю.
    Вообщем, у меня всё заработало, вгрузил правильный, нужный код. Гироскоп с адресом 0x69.
     
  8. На всякий случай загружаю сюда рабочий код для гироскопа.
    Код (C++):
    #include <Wire.h>
    #include "Kalman.h"

    Kalman kalmanX;
    Kalman kalmanY;

    uint8_t IMUAddress = 0x69;

    /* IMU Data */
    int16_t accX;
    int16_t accY;
    int16_t accZ;
    int16_t tempRaw;
    int16_t gyroX;
    int16_t gyroY;
    int16_t gyroZ;

    double accXangle; // Angle calculate using the accelerometer
    double accYangle;
    double temp;
    double gyroXangle = 180; // Angle calculate using the gyro
    double gyroYangle = 180;
    double compAngleX = 180; // Calculate the angle using a Kalman filter
    double compAngleY = 180;
    double kalAngleX; // Calculate the angle using a Kalman filter
    double kalAngleY;

    uint32_t timer;

    void setup() {
      Serial.begin(115200);
      Wire.begin();
      i2cWrite(0x6B,0x00); // Disable sleep mode
      if(i2cRead(0x75,1)[0] != 0x69) { // Read "WHO_AM_I" register
        Serial.print(F("MPU-6050 with address 0x"));
        Serial.print(IMUAddress,HEX);
        Serial.println(F(" is not connected"));
        while(1);
      }  
      kalmanX.setAngle(180); // Set starting angle
      kalmanY.setAngle(180);
      timer = micros();
    }

    void loop() {
      /* Update all the values */
      uint8_t* data = i2cRead(0x3B,14);
      accX = ((data[0] << 8) | data[1]);
      accY = ((data[2] << 8) | data[3]);
      accZ = ((data[4] << 8) | data[5]);
      tempRaw = ((data[6] << 8) | data[7]);
      gyroX = ((data[8] << 8) | data[9]);
      gyroY = ((data[10] << 8) | data[11]);
      gyroZ = ((data[12] << 8) | data[13]);

      /* Calculate the angls based on the different sensors and algorithm */
      accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
      accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;

      double gyroXrate = (double)gyroX/131.0;
      double gyroYrate = -((double)gyroY/131.0);
      gyroXangle += gyroXrate*((double)(micros()-timer)/1000000); // Calculate gyro angle without any filter
      gyroYangle += gyroYrate*((double)(micros()-timer)/1000000);
      //gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
      //gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);

      compAngleX = (0.93*(compAngleX+(gyroXrate*(double)(micros()-timer)/1000000)))+(0.07*accXangle); // Calculate the angle using a Complimentary filter
      compAngleY = (0.93*(compAngleY+(gyroYrate*(double)(micros()-timer)/1000000)))+(0.07*accYangle);

      kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
      kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
      timer = micros();

      temp = ((double)tempRaw + 12412.0) / 340.0;
      Serial.print(kalAngleX);Serial.print("\t");
      Serial.print(kalAngleY);Serial.print("\t");
      Serial.print("\n");

      delay(1); // The accelerometer's maximum samples rate is 1kHz
    }
    void i2cWrite(uint8_t registerAddress, uint8_t data){
      Wire.beginTransmission(IMUAddress);
      Wire.write(registerAddress);
      Wire.write(data);
      Wire.endTransmission(); // Send stop
    }
    uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
      uint8_t data[nbytes];
      Wire.beginTransmission(IMUAddress);
      Wire.write(registerAddress);
      Wire.endTransmission(false); // Don't release the bus
      Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
      for(uint8_t i = 0; i < nbytes; i++)
        data[i] = Wire.read();
      return data;
    }
     
  9. Но всё равно спасибо!
     
  10. Belkin

    Belkin Гик

    Вот что (из всего прочего) предложил Яндекс http://arduino.ru/forum/programmirovanie/rabota-s-i2c-v-biblioteke-wire
    Строка для поиска - "команды библиотеки wire arduino"
     
  11. Насколько я в курсе, при помощи AD0 можно добиться смещения адреса у GY-521на 1 в одну или другую сторону.
    Если AD0 припаять к земле от контроллера, адрес гироскопа на шине уменьшается на 1, если прпаять к +5v контроллера то увеличится на 1, а иначе бкдет тот что по умолчанию. Таким образом можно получить до 3 гироскопов на 1 шине.