Вопросы по гироскопу MPU 6050

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем pyro, 17 апр 2013.

  1. Megakoteyka

    Megakoteyka Оракул Модератор

    И загрузив заведомо рабочий код! А то можно много гироскопов перепробовать :)
     
  2. dreadfull

    dreadfull Гик

    вот хозяин этой статьи хотел заставить работать такой же гироскоп, НО запустил или нет или скетчем поделиться ....
    но тот факт что на других скетчах работы нет, наводит мысль что косяк в гироскопе....
     
  3. dreadfull

    dreadfull Гик

    этак, еслиб человечек с аналогичным девайсом, позаливал бы предложенные (найденные) мною скетчи все бы сразу стало понятно....
     
  4. zsm

    zsm Гик

    Опробовал первый и второй примеры , всё работает корректно вроде-не убегают значения, вот видео с первым примером:
    http://yadi.sk/d/xDiihhY5LDNkj

    может в питании дело, попробуйте от батарейки запитать дуню..
     
    Последнее редактирование: 26 мар 2014
  5. dreadfull

    dreadfull Гик

    спс. пойду завтра за кроной;)
     
  6. roggedhorse

    roggedhorse Гик

    Меня смущает функция i2cRead, а именно метод возврата результата.
    Как мне кажется, объект data имеет время жизни, ограниченное вызовом i2cRead.
    То есть после завершения i2cRead содержимое data является неопределенным.
     
    Megakoteyka нравится это.
  7. Megakoteyka

    Megakoteyka Оракул Модератор

    Вы правы. Нужно передавать в функцию указатель на массив.
     
  8. dreadfull

    dreadfull Гик

    порядок подключения 9В правильный???
     

    Вложения:

    • IMG_6638.JPG
      IMG_6638.JPG
      Размер файла:
      877,3 КБ
      Просмотров:
      1.595
  9. zsm

    zsm Гик

    вроде да, плюс должен на средний контакт подаваться.
     
  10. AlexTeos

    AlexTeos Нерд

    Правильно ли я понимаю: лежит гироскоп на столе, если не отрывая от стола вращать его, то это будут показания по Z, к сожалению ось Z во всех скетчах почему то не высчитывается(я пытался но почему то ничего хорошего у меня не вышло), а именно поворот по этой оси мне необходим(необходимо у робота на колесах отслеживать угол поворота в право-влево), поэтому я решил повернуть гироскоп поставив его на ребро и принимать показания уже с оси Y(на рисунке синим я показал угол поворота который мне необходим). К сожалению из сей задумки у меня пока ничего не вышло, может из-за кода может из-за гироскопа, пока неважно, скажите лишь правильно ли я размышляю? Или это все равно остается ось Z?
     

    Вложения:

  11. roggedhorse

    roggedhorse Гик

    Если вы понимаете, что гироскоп - это только датчик угловых скоростей, то вы на правильном пути.
     
  12. dreadfull

    dreadfull Гик

    мне тоже необходимо было получать угол поворота и у меня тоже датчик работает только в таком же положении. НО постоянно самопроизвольно уменьшается значение.... только это значение...
     
  13. AlexTeos

    AlexTeos Нерд

    Тогда помогите подправить код, добавив вычисления оси Z

    Код (Text):

    #include <Wire.h>
    #include "Kalman.h"

    Kalman kalmanX;
    Kalman kalmanY;
    Kalman kalmanZ;

    uint8_t IMUAddress = 0x68;

    /* 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 accZangle;
    double temp;
    double gyroXangle = 180; // Angle calculate using the gyro
    double gyroYangle = 180;
    double gyroZangle = 180;
    double compAngleX = 180; // Calculate the angle using a Kalman filter
    double compAngleY = 180;
    double compAngleZ = 180;
    double kalAngleX; // Calculate the angle using a Kalman filter
    double kalAngleY;
    double kalAngleZ;

    uint32_t timer;

    void setup() {
      Wire.begin();
      Serial.begin(9600);      

      i2cWrite(0x6B,0x00); // Disable sleep mode  
      kalmanX.setAngle(180); // Set starting angle
      kalmanY.setAngle(180);
      kalmanZ.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;
      accZangle = (atan2(accY,accX)+PI)*RAD_TO_DEG;

      double gyroXrate = (double)gyroX/131.0;
      double gyroYrate = -((double)gyroY/131.0);
      double gyroZrate = -((double)gyroZ/131.0);

      gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
      gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
      gyroZangle += kalmanZ.getRate()*((double)(micros()-timer)/1000000);

      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);
      kalAngleZ = kalmanZ.getAngle(accZangle, gyroZrate, (double)(micros()-timer)/1000000);
      timer = micros();

    Serial.println();
        Serial.print("X:");
        Serial.print(kalAngleX,0);
        Serial.print(" ");
        Serial.print("Y:");
        Serial.print(kalAngleY,0);
        Serial.println(" ");
        Serial.print("Z:");
        Serial.print(kalAngleZ,0);
        Serial.println(" ");
      // 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;
    }
    Это код с предыдущей страницы, впринципе все аналогично, только в 2х местах у меня сомнения, посколько я не знаю откуда они берутся, вот:
    accZangle = (atan2(accY,accX)+PI)*RAD_TO_DEG;
    и
    double gyroZrate = -((double)gyroZ/131.0);

    При использовании этого скетча X и Y ведут себя адекватно, а Z изменяется, но постоянно возвращается к значению ~140
     
  14. roggedhorse

    roggedhorse Гик

    Смотрите документ http://www.invensense.com/mems/gyro/documents/PS-MPU-6000A-00v3.4.pdf
    параграф "6.1 Gyroscope Specifications"

    131 - это коэффициент чувствительности гироскопа в заданном режиме (FS = 250 град/сек)
    Поскольку у него 16-битный ADC, то модуль максимального raw-значения равен 32767
    32767 / 250 = 131 условных единиц на градус в секунду.
    То есть, если raw-значение равно 131, то угловая скорость равна 1 градус в секунду.

    В приведенном вами коде нет обработки критической ситуации, когда оба параметра функции atan2 равны нулю (значение скорее всего будет nan, в результате чего у всей последующей математики сносит башню).
    Такая ситуация вполне вероятна.
     
    alexGOL и Megakoteyka нравится это.
  15. alexGOL

    alexGOL Нуб

    Добрый день!
    Уже несколько дней пытаюсь получить адекватные показания по оси Z, сырые значения при этом обрабатывались разными фильтрами, наилучшие результаты в части стабильности значений показал фильтр Калмана. Логика кода в целом аналогична примеру, приведенному выше. Но есть одна проблема - не могу получить показания отклонения угла по оси Z. Подскажите, каким образом это вообще можно реализовать, в частности интересует угол вращения вокруг своей оси при движении.
     
  16. roggedhorse

    roggedhorse Гик

    Речь об акселерометре или о гироскопе ?
     
  17. alexGOL

    alexGOL Нуб

    Речь идет об устройстве MPU 6050 (GY-521). Можно как-то получить данный угол имея проекцию вектора ускорения по оси Z (показания акселерометра) и показание гироскопа (угловая скорость). Я так понимаю показаний одного из устройств мало и есть известные проблемы - дрейф в состоянии покоя и сильный дребезг значений акселерометра. В любом случае хотел получить совет по тому, в каком направлении двигаться. Заранее спасибо.
     
  18. roggedhorse

    roggedhorse Гик

    Когда я разбирался с этим вопросом, то прежде всего построил макет системы координат XYZ и научился понимать углы Roll (крен), Pitch (Тангаж) и Yaw (рыскание). Причем Yaw не есть курс (пеленг).
    Затем прочел эти мануалы:
    http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
    http://www.pololu.com/file/download/LSM303DLH-compass-app-note.pdf?file_id=0J434
    http://mmae.iit.edu/~mpeet/Classes/MMAE441/Aircraft/441Lecture2.pdf
     
    OldKryptos и Megakoteyka нравится это.
  19. alexGOL

    alexGOL Нуб

    Спасибо за информацию, буду изучать.
     
  20. roggedhorse

    roggedhorse Гик

    и еще: в приведенном коде есть две критические ошибки (о них я писал выше)