Использование датчика GY-521 - ФОРУМ ДВ Робот dvrobot.ru
Воскресенье, 18.11.2018, 09:27
Главная Мой профиль Регистрация Выход
  • НАШ МАГАЗИН
  • Вы вошли как Гость | Группа "Гости"Приветствую Вас, Гость
    [ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
    • Страница 1 из 1
    • 1
    Модератор форума: GRACH, Serg  
    ФОРУМ ДВ Робот dvrobot.ru » DV ROBOT » Библиотека Проектов » Использование датчика GY-521 (Подключение и получение)
    Использование датчика GY-521
    rheinhardДата: Вторник, 15.01.2013, 03:21 | Сообщение # 1
    1.5 Вольт
    Группа: Пользователи
    Сообщений: 7
    Репутация: 20
    Статус: Offline
    Итак, вдохновимся сегодня тем, что всегда вдохновляло ведущих передачи "Очумелые ручки" и приступим.



    А задача у нас следующая. Точнее, три задачи.
    1. Подключиться к датчику,
    2. Получить какие-то данные
    3. Придумать,что с этими данными делать.

    Купить GY-521 можно здесь

    1. Подключаемся.
    Согласно собственной спецификации, гироскоп-акселерометр GY-521, на одной микросхеме MPU6050 имеет в составе гироскоп на три координаты, акселерометр на три координаты, подтягивающие резисторы на плате и датчик температуры. Работает по шине IIS (I2C). Напряжение питания датчика - 3.3 вольта.
    Что это значит? Это значит, что если вы используете Arduino Pro mini, с логикой, работающей при макс. напряжении 3.3 вольта, то без особенных на то проблем вы датчик подключите.

    Даже приведу схему подключения GY-521 к Arduino Pro Mini

    Вывод 3.3V Arduino - Vcc
    Вывод GND Arduino - GND
    Аналоговый вывод A4 Arduino - SDA
    Аналоговый вывод A5 Arduino - SCL
    Опционально, вывод INT датчика подсоединяется к цифровому выводу 2 Arduino.

    Многие на форумах советуют между выводами SCL и GND, а так же SDA и GND поставить по подтягивающему резистору на 2.2 кОм. Это не лишено смысла. Возможно, они понадобятся. По крайней мере, хуже не станет. Если вы планируете повесить наоднушину несколькоустройств,то резисторы понадобятся обязательно.

    Однако, если у вас другая плата, то потребуется немного похимичить, так как потребуется конвертер логических уровней.

    Линейка плат Arduino начиная с маленькой Nano и кончая большой Mega работает с логикой, основывающейся на напряжении в 5 вольт. Это означает, что, как минимум, ваш датчик, рассчитанный на 3.3 В работатьоткажется, как максимум - сгорит. Чтобы этого не произошло, напряжение на шине нужно конвертировать в нужное.

    Рассмотрим пример:
    Наверняка вам известно, что бинарнаялогика давно не оперирует такими величинами, как наличие и отсутствие напряжения. То есть, скажем, при передачи бита "1" в электронике применяется один уровень напряжения, а при передаче "0" - отнюдь не его отсутствие, а несколько пониженный уровень. В случае с Arduino - это 5в при передаче бита "1" и, поправьте меня, если это не так, 3.5в при передаче "0".
    В то же время датчик, работающий намаксимуме в 3.3в будет передавать "1" как 3.3в, а "0" как, скажем, 2.5в. Налицо несовпадение.
    Почему бы не поставить на выводы по резистору, скажете вы, и не превратить напряжение 5в в 3.3, и не напрягаться?
    Действительно, это будет работать, но в одну сторону - из Arduino в датчик. В обратную сторону, из датчика информация придти не сможет вовсе, поскольку даже единица в свои хилые 3.3 вольта, потеряясь на резисторе, не даст даже "0" для Arduino.

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

    Но, это достаточно простое устройство, и его можно собрать самому. Потребуется всего лишь 4 резистора на 2.2 кОм и два МОСФЕТ-транзистора, типа 2N7000, или, на самом деле, любых других, рассчитанных на 5в.
    Схема сборки приведена здесь: https://www.sparkfun.com/products/8745

    Поискав в интернете, можно найти схему на четырех транзисторах, для бедных, или даже на восьми диодах для совсем бедных, но это уже другая история.

    Дело в другом - имея конвертер, мы можем с одной стороны работать с логикой на 5в, а с другой стороны - на 3в.

    Подключается конвертер просто.
    Вывод конвертера GND - к выводу GND Arduino и к выводу GND датчика
    Вывод конвертера 5в - к выводу 5в Arduino
    Вывод конвертера 3.3в - к выводу 3.3в Arduino и к выводу VCC датчика
    Вывод конвертера SCL 5в - к выводу A5 Arduino (выводу 21 Mega)
    Вывод конвертера SDA 5в - к выводу A4 Arduino (выводу 20 Mega)
    Вывод конвертера SCL 3.3в - к выводу датчика SCL
    Вывод конвертера SDA 3.3в - к выводу датчика SDA
    Опционально: цифровой вывод 2 Arduino через резистор 2.2кОм к выводу INT датчика.

    На этом все. Теперь можно загрузить скетч для проверки наличия устройств.



    При выполнении скетча в мониторе порта вы должны увидеть хотя бы одно устройство. Либо "No I2C devices found", если конвертер либо устройство не работают.
    Если же устройство найдено, можно переходить к следующему шагу.

    Добавлено (15.01.2013, 03:19)
    ---------------------------------------------
    2. Получим, наконец, данные.

    Если вы думаете, что все сразу и просто, то... Нет, не все так просто.
    Чтобы работать с устройством, понадобится библиотека для работы с этим устройством.
    Библиотеку с примерами вы можете скачать здесь: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
    Ну, или просто скачать все библиотеки одним архивом отсюда:
    https://github.com/jrowberg/i2cdevlib/archive/master.zip
    Вытащить из архива две директории - I2Cdev и MPU6050 и положить в директорию среды разработки arduino/libraries

    Теперь, перезапустив среду, вы можете выбрать из группы примеров MPU6050 два примера работы с датчиком.

    Рассмотрим первый - DMP6. Первый потому, что сложный и потребует подключения вывода INT. Зато дает очень точные данные. Но на любителя, поскольку подойдет лишь для неподвижного устройства. Для устройств движущихся и вибрирующих при этом, такая точность необязательна.

    Рассмотрим второй - RAW. Пример достаточно примитивен, но с некоторой долей ухищрения позволяет получить достаточно точные данные. Дело в том, что Arduino и датчик работают с разными частотами, и в момент чтения данных с датчика при несовпадении напряжений данные получаются с погрешностями.
    При использовании вывода INT частота получения данных задается как раз принудительно, поэтому данные получаются точнее.

    Тем не менее, фильтрацию и отсеивание глюков рассмотрим в третьей части, а пока просто что-то получим.

    Согласно примеру, можно получить голые данные с датчика таким образом:

    1. Подключить нужные библиотеки:

    Код
    #include "Wire.h"
    #include "I2Cdev.h"
    #include "MPU6050.h"


    2. создать экземпляр объекта датчика и задать набор переменных для получения из датчика значений

    Код
    MPU6050 accelgyro;

    int16_t ax, ay, az;
    int16_t gx, gy, gz;


    3. Включить шину. Датчик при инициализации самокалибруется, и можно дать ему для этого времени, замедлив, скажем при инициализации Arduino на 100мкс.

    Код
    void setup() {
    ...
    Wire.begin();
    accelgyro.initialize();
    ...
    delay(100);   //замедление
    }


    4. Получить и вывести данные

    Код
    void loop() {
    ...
    //Получение значений акселерометра и гироскопа сразу
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);       
    ...
    //Вывод всего
    Serial.print("a/g:\t");
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.print(az); Serial.print("\t");
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
    ...
    }


    Вот и все. И если вы после загрузки скетча ничего не видите, значит вы забыли включить монитор! Хахаха.

    Купить Модуль GY-521 Аксе-Гиро

    Добавлено (15.01.2013, 03:21)
    ---------------------------------------------
    Дальше будет чуть позже
    Прикрепления: 4188808.jpg(40.1 Kb)


    Сообщение отредактировал rheinhard - Вторник, 15.01.2013, 03:21
     
    cmept-27Дата: Вторник, 29.01.2013, 01:23 | Сообщение # 2
    3.5 Вольт
    Группа: Пользователи
    Сообщений: 17
    Репутация: 0
    Статус: Offline
    Ну теперь самое простое, применить Фильтр Калмана и в бой ))).

    Добавлено (29.01.2013, 01:23)
    ---------------------------------------------
    http://yadi.sk/d/QqbTn46_2BAnW  Вот библиотека фильтра Кальмана 
    А вот пример применения 

    Код
    #include <Wire.h>
    #include "Kalman.h"
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);

    Kalman kalmanX;
    Kalman kalmanY;

    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 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();
       Serial.begin(9600);
       lcd.init();                       
       lcd.backlight();               

       i2cWrite(0x6B,0x00); // Disable sleep mode         
       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 += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
       gyroYangle += kalmanY.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);
       timer = micros();

       lcd.setCursor (0,0);
       lcd.print ("X=");
       lcd.print (kalAngleX,0);
       lcd.print (" Y=");
       lcd.print (kalAngleY,0);
       delay (100);
       lcd.clear ();

       // 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;
    }
     
    sanikДата: Понедельник, 04.11.2013, 12:08 | Сообщение # 3
    5 Вольт
    Группа: Пользователи
    Сообщений: 55
    Репутация: 0
    Статус: Offline
    cmept-27, А как эти данные применить например к сервам? Например наклонил по оси Y повернулась одна серва Наклонил по оси Х повернулась другая серва? Если не сложно приведите пример....

    Ну не знаю я
     
    ФОРУМ ДВ Робот dvrobot.ru » DV ROBOT » Библиотека Проектов » Использование датчика GY-521 (Подключение и получение)
    • Страница 1 из 1
    • 1
    Поиск:

    ДВ Робот - Чат